bug fixing; version up
[sdk/tools/web-simulator.git] / web / ripple.js
1 /*! 
2   Ripple Mobile Environment Emulator v0.9.8 :: Built On Thu Jan 16 2014 10:33:05 GMT+0800 (CST)
3
4                                 Apache License
5                            Version 2.0, January 2004
6                         http://www.apache.org/licenses/
7
8    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
9
10    1. Definitions.
11
12       "License" shall mean the terms and conditions for use, reproduction,
13       and distribution as defined by Sections 1 through 9 of this document.
14
15       "Licensor" shall mean the copyright owner or entity authorized by
16       the copyright owner that is granting the License.
17
18       "Legal Entity" shall mean the union of the acting entity and all
19       other entities that control, are controlled by, or are under common
20       control with that entity. For the purposes of this definition,
21       "control" means (i) the power, direct or indirect, to cause the
22       direction or management of such entity, whether by contract or
23       otherwise, or (ii) ownership of fifty percent (50%) or more of the
24       outstanding shares, or (iii) beneficial ownership of such entity.
25
26       "You" (or "Your") shall mean an individual or Legal Entity
27       exercising permissions granted by this License.
28
29       "Source" form shall mean the preferred form for making modifications,
30       including but not limited to software source code, documentation
31       source, and configuration files.
32
33       "Object" form shall mean any form resulting from mechanical
34       transformation or translation of a Source form, including but
35       not limited to compiled object code, generated documentation,
36       and conversions to other media types.
37
38       "Work" shall mean the work of authorship, whether in Source or
39       Object form, made available under the License, as indicated by a
40       copyright notice that is included in or attached to the work
41       (an example is provided in the Appendix below).
42
43       "Derivative Works" shall mean any work, whether in Source or Object
44       form, that is based on (or derived from) the Work and for which the
45       editorial revisions, annotations, elaborations, or other modifications
46       represent, as a whole, an original work of authorship. For the purposes
47       of this License, Derivative Works shall not include works that remain
48       separable from, or merely link (or bind by name) to the interfaces of,
49       the Work and Derivative Works thereof.
50
51       "Contribution" shall mean any work of authorship, including
52       the original version of the Work and any modifications or additions
53       to that Work or Derivative Works thereof, that is intentionally
54       submitted to Licensor for inclusion in the Work by the copyright owner
55       or by an individual or Legal Entity authorized to submit on behalf of
56       the copyright owner. For the purposes of this definition, "submitted"
57       means any form of electronic, verbal, or written communication sent
58       to the Licensor or its representatives, including but not limited to
59       communication on electronic mailing lists, source code control systems,
60       and issue tracking systems that are managed by, or on behalf of, the
61       Licensor for the purpose of discussing and improving the Work, but
62       excluding communication that is conspicuously marked or otherwise
63       designated in writing by the copyright owner as "Not a Contribution."
64
65       "Contributor" shall mean Licensor and any individual or Legal Entity
66       on behalf of whom a Contribution has been received by Licensor and
67       subsequently incorporated within the Work.
68
69    2. Grant of Copyright License. Subject to the terms and conditions of
70       this License, each Contributor hereby grants to You a perpetual,
71       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
72       copyright license to reproduce, prepare Derivative Works of,
73       publicly display, publicly perform, sublicense, and distribute the
74       Work and such Derivative Works in Source or Object form.
75
76    3. Grant of Patent License. Subject to the terms and conditions of
77       this License, each Contributor hereby grants to You a perpetual,
78       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
79       (except as stated in this section) patent license to make, have made,
80       use, offer to sell, sell, import, and otherwise transfer the Work,
81       where such license applies only to those patent claims licensable
82       by such Contributor that are necessarily infringed by their
83       Contribution(s) alone or by combination of their Contribution(s)
84       with the Work to which such Contribution(s) was submitted. If You
85       institute patent litigation against any entity (including a
86       cross-claim or counterclaim in a lawsuit) alleging that the Work
87       or a Contribution incorporated within the Work constitutes direct
88       or contributory patent infringement, then any patent licenses
89       granted to You under this License for that Work shall terminate
90       as of the date such litigation is filed.
91
92    4. Redistribution. You may reproduce and distribute copies of the
93       Work or Derivative Works thereof in any medium, with or without
94       modifications, and in Source or Object form, provided that You
95       meet the following conditions:
96
97       (a) You must give any other recipients of the Work or
98           Derivative Works a copy of this License; and
99
100       (b) You must cause any modified files to carry prominent notices
101           stating that You changed the files; and
102
103       (c) You must retain, in the Source form of any Derivative Works
104           that You distribute, all copyright, patent, trademark, and
105           attribution notices from the Source form of the Work,
106           excluding those notices that do not pertain to any part of
107           the Derivative Works; and
108
109       (d) If the Work includes a "NOTICE" text file as part of its
110           distribution, then any Derivative Works that You distribute must
111           include a readable copy of the attribution notices contained
112           within such NOTICE file, excluding those notices that do not
113           pertain to any part of the Derivative Works, in at least one
114           of the following places: within a NOTICE text file distributed
115           as part of the Derivative Works; within the Source form or
116           documentation, if provided along with the Derivative Works; or,
117           within a display generated by the Derivative Works, if and
118           wherever such third-party notices normally appear. The contents
119           of the NOTICE file are for informational purposes only and
120           do not modify the License. You may add Your own attribution
121           notices within Derivative Works that You distribute, alongside
122           or as an addendum to the NOTICE text from the Work, provided
123           that such additional attribution notices cannot be construed
124           as modifying the License.
125
126       You may add Your own copyright statement to Your modifications and
127       may provide additional or different license terms and conditions
128       for use, reproduction, or distribution of Your modifications, or
129       for any such Derivative Works as a whole, provided Your use,
130       reproduction, and distribution of the Work otherwise complies with
131       the conditions stated in this License.
132
133    5. Submission of Contributions. Unless You explicitly state otherwise,
134       any Contribution intentionally submitted for inclusion in the Work
135       by You to the Licensor shall be under the terms and conditions of
136       this License, without any additional terms or conditions.
137       Notwithstanding the above, nothing herein shall supersede or modify
138       the terms of any separate license agreement you may have executed
139       with Licensor regarding such Contributions.
140
141    6. Trademarks. This License does not grant permission to use the trade
142       names, trademarks, service marks, or product names of the Licensor,
143       except as required for reasonable and customary use in describing the
144       origin of the Work and reproducing the content of the NOTICE file.
145
146    7. Disclaimer of Warranty. Unless required by applicable law or
147       agreed to in writing, Licensor provides the Work (and each
148       Contributor provides its Contributions) on an "AS IS" BASIS,
149       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
150       implied, including, without limitation, any warranties or conditions
151       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
152       PARTICULAR PURPOSE. You are solely responsible for determining the
153       appropriateness of using or redistributing the Work and assume any
154       risks associated with Your exercise of permissions under this License.
155
156    8. Limitation of Liability. In no event and under no legal theory,
157       whether in tort (including negligence), contract, or otherwise,
158       unless required by applicable law (such as deliberate and grossly
159       negligent acts) or agreed to in writing, shall any Contributor be
160       liable to You for damages, including any direct, indirect, special,
161       incidental, or consequential damages of any character arising as a
162       result of this License or out of the use or inability to use the
163       Work (including but not limited to damages for loss of goodwill,
164       work stoppage, computer failure or malfunction, or any and all
165       other commercial damages or losses), even if such Contributor
166       has been advised of the possibility of such damages.
167
168    9. Accepting Warranty or Additional Liability. While redistributing
169       the Work or Derivative Works thereof, You may choose to offer,
170       and charge a fee for, acceptance of support, warranty, indemnity,
171       or other liability obligations and/or rights consistent with this
172       License. However, in accepting such obligations, You may act only
173       on Your own behalf and on Your sole responsibility, not on behalf
174       of any other Contributor, and only if You agree to indemnify,
175       defend, and hold each Contributor harmless for any liability
176       incurred by, or claims asserted against, such Contributor by reason
177       of your accepting any such warranty or additional liability.
178
179    END OF TERMS AND CONDITIONS
180
181    APPENDIX: How to apply the Apache License to your work.
182
183       To apply the Apache License to your work, attach the following
184       boilerplate notice, with the fields enclosed by brackets "[]"
185       replaced with your own identifying information. (Don't include
186       the brackets!)  The text should be enclosed in the appropriate
187       comment syntax for the file format. We also recommend that a
188       file or class name and description of purpose be included on the
189       same "printed page" as the copyright notice for easier
190       identification within third-party archives.
191
192    Copyright [yyyy] [name of copyright owner]
193
194    Licensed under the Apache License, Version 2.0 (the "License");
195    you may not use this file except in compliance with the License.
196    You may obtain a copy of the License at
197
198        http://www.apache.org/licenses/LICENSE-2.0
199
200    Unless required by applicable law or agreed to in writing, software
201    distributed under the License is distributed on an "AS IS" BASIS,
202    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
203    See the License for the specific language governing permissions and
204    limitations under the License.
205
206 -------------------------------------------------------
207 Copyright 2011 Research In Motion Limited.
208
209 Contributors:
210         Brent Lintner (blintner@rim.com)
211         Dan Silivestru (dsilivestru@rim.com)
212         Gord Tanner (gtanner@rim.com)
213         Nino D'Aversa (ndaversa@rim.com)
214         Nukul Bhasin (nbhasin@rim.com)
215
216 -------------------------------------------------------
217 --> Kudos to third party awesomeness:
218
219 * browser-require *
220
221 https://github.com/rsms/browser-require
222
223 The MIT License
224 http://www.opensource.org/licenses/mit-license.php
225 Copyright (c) 2010 Rasmus Andersson http://hunch.se/
226
227 -------------------------------------------------------
228 * jWorkflow *
229
230 http://github.com/tinyhippos/jWorkflow/
231
232 The MIT License
233 http://www.opensource.org/licenses/mit-license.php
234 Copyright (c) 2010 all contributors:
235 Gord Tanner
236
237 -------------------------------------------------------
238 * jXHR.js (JSON-P XHR) *
239  v0.1 (c) Kyle Simpson 
240  MIT License
241
242 -------------------------------------------------------
243 * UI.Acceleromter Control (panel plugin) *
244
245 Licensed under the MIT license:
246   Copyright Train Hack 2010
247   Contributors: Wolfram Kriesing, Dan Silivestru, Brent Lintner
248   http://www.opensource.org/licenses/mit-license.php
249
250 -------------------------------------------------------
251 * jQuery JavaScript Library *
252
253 http://jquery.com/
254
255 Copyright 2010, John Resig
256 Licensed under MIT
257 http://jquery.org/license
258
259 Includes Sizzle.js
260 http://sizzlejs.com/
261 Copyright 2010, The Dojo Foundation
262 Released under the MIT, BSD, and GPL Licenses.
263
264 -------------------------------------------------------
265 * jQuery UI *
266
267 Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
268 licensed under the MIT (MIT-LICENSE.txt)
269
270 http://docs.jquery.com/UI
271
272 -------------------------------------------------------
273 * jQuery Tooltip plugin *
274
275 http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
276 http://docs.jquery.com/Plugins/Tooltip
277
278 Copyright (c) 2006 - 2008 Jörn Zaefferer
279
280 Dual licensed under the MIT and GPL licenses:
281   http://www.opensource.org/licenses/mit-license.php
282   http://www.gnu.org/licenses/gpl.html
283
284 -------------------------------------------------------
285 * Math.uuid.js (v1.4) *
286
287 http://www.broofa.com
288 mailto:robert@broofa.com
289
290 Copyright (c) 2010 Robert Kieffer
291 Dual licensed under the MIT and GPL licenses.
292
293 -------------------------------------------------------
294 * Wii Opera SDK - 3D Math Class v2.7.22 2008-12-14 *
295 (c) 2007-2008 Daniel Gump. All Rights Reserved.                          
296  http://wiioperasdk.com, http://hullbreachonline.com                      
297  hullbreach@hullbreachonline.com                                          
298                                                                           
299 * Wii Opera SDK - Drawing Class v2.6.16 2008-12-14 * 
300 (c) 2007-2008 Daniel Gump. All Rights Reserved
301 http://wiioperasdk.com, http://hullbreachonline.com
302 hullbreach@hullbreachonline.com
303
304   Wii is a trademark of Nintendo Co., Ltd.                                
305   Opera is a trademark of Opera, ASA.                                     
306   This software package is not associated with either company             
307   but was created to support users of both.  Its alternative name         
308   when supporting other products is the HULLBREACH SDK.                   
309                                                                           
310   Redistribution and use in source and binary forms, with or without      
311   modification, are permitted provided that the following conditions      
312   are met:                                                                
313     * Redistributions of source code must retain the above copyright      
314       notice, this list of conditions and the following disclaimer.       
315     * Redistributions in binary form must reproduce the above copyright   
316       notice, this list of conditions and the following disclaimer in     
317       the documentation and/or other materials provided with the          
318       distribution.                                                       
319     * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names 
320       of its contributors may be used to endorse or promote products      
321       derived from this software without specific prior written           
322       permission.                                                         
323     * If the explicit purpose of the software is not to support the       
324       Nintendo Wii or the Opera Web browser, then the names of such must  
325       not be used in any derived product. The name shall be the           
326       HULLBREACH SDK with a reference link to http://hullbreachonline.    
327                                                                           
328   THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   
329   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          
330   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  
331   DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     
332   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      
333   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      
334   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      
335   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     
336   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   
337   IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      
338   POSSIBILITY OF SUCH DAMAGE.                                             
339
340 -------------------------------------------------------
341   OpenLayers.js -- OpenLayers Map Viewer Library
342
343   Copyright 2005-2010 OpenLayers Contributors, released under the Clear BSD
344   license. Full license text below taken from http://svn.openlayers.org/trunk/openlayers/license.txt
345
346         Copyright 2005-2011 OpenLayers Contributors. All rights reserved. See
347         authors.txt for full list.
348          
349         Redistribution and use in source and binary forms, with or without modification,
350         are permitted provided that the following conditions are met:
351          
352         1. Redistributions of source code must retain the above copyright notice, this
353         list of conditions and the following disclaimer.
354          
355         2. Redistributions in binary form must reproduce the above copyright notice,
356         this list of conditions and the following disclaimer in the documentation and/or
357         other materials provided with the distribution.
358          
359         THIS SOFTWARE IS PROVIDED BY OPENLAYERS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
360         OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
361         MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
362         SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
363         INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
364         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
365         PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
366         LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
367         OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
368         ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
369          
370         The views and conclusions contained in the software and documentation are those
371         of the authors and should not be interpreted as representing official policies,
372         either expressed or implied, of OpenLayers Contributors.
373
374   Includes compressed code under the following licenses:
375
376   (For uncompressed versions of the code used please see the
377   OpenLayers SVN repository: <http://openlayers.org/>)
378
379 -------------------------------------------------------
380   Contains portions of Rico <http://openrico.org/>
381  
382   Copyright 2005 Sabre Airline Solutions  
383   
384   Licensed under the Apache License, Version 2.0 (the "License"); you
385   may not use this file except in compliance with the License. You
386   may obtain a copy of the License at the top of this file or a the following
387   link:
388   
389          http://www.apache.org/licenses/LICENSE-2.0  
390   
391   Unless required by applicable law or agreed to in writing, software
392   distributed under the License is distributed on an "AS IS" BASIS,
393   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
394   implied. See the License for the specific language governing
395   permissions and limitations under the License. 
396
397 -------------------------------------------------------
398   Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
399   Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
400  
401   Licensed under the Apache License, Version 2.0 (the "License");
402   you may not use this file except in compliance with the License.
403   You may obtain a copy of the License at
404   http://www.apache.org/licenses/LICENSE-2.0
405
406 -------------------------------------------------------
407   Contains portions of Gears <http://code.google.com/apis/gears/>
408
409   Copyright 2007, Google Inc.
410
411   Redistribution and use in source and binary forms, with or without
412   modification, are permitted provided that the following conditions are met:
413
414    1. Redistributions of source code must retain the above copyright notice,
415       this list of conditions and the following disclaimer.
416    2. Redistributions in binary form must reproduce the above copyright notice,
417       this list of conditions and the following disclaimer in the documentation
418       and/or other materials provided with the distribution.
419    3. Neither the name of Google Inc. nor the names of its contributors may be
420       used to endorse or promote products derived from this software without
421       specific prior written permission.
422  
423   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
424   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
425   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
426   EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
427   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
428   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
429   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
430   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
431   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
432   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
433  
434   Sets up google.gears.*, which is *the only* supported way to access Gears.
435
436   Circumvent this file at your own risk!
437  
438   In the future, Gears may automatically define google.gears.* without this
439   file. Gears may use these objects to transparently fix bugs and compatibility
440   issues. Applications that use the code below will continue to work seamlessly
441   when that happens.
442 */
443 window.require = null;window.define = null;/**
444  * almond 0.0.3 Copyright (c) 2011, The Dojo Foundation All Rights Reserved.
445  * Available via the MIT or new BSD license.
446  * see: http://github.com/jrburke/almond for details
447  */
448 /*jslint strict: false, plusplus: false */
449 /*global setTimeout: false */
450
451 var requirejs, require, define;
452 (function (undef) {
453
454     var defined = {},
455         waiting = {},
456         aps = [].slice,
457         main, req;
458
459     if (typeof define === "function") {
460         //If a define is already in play via another AMD loader,
461         //do not overwrite.
462         return;
463     }
464
465     /**
466      * Given a relative module name, like ./something, normalize it to
467      * a real name that can be mapped to a path.
468      * @param {String} name the relative name
469      * @param {String} baseName a real name that the name arg is relative
470      * to.
471      * @returns {String} normalized name
472      */
473     function normalize(name, baseName) {
474         //Adjust any relative paths.
475         if (name && name.charAt(0) === ".") {
476             //If have a base name, try to normalize against it,
477             //otherwise, assume it is a top-level require that will
478             //be relative to baseUrl in the end.
479             if (baseName) {
480                 //Convert baseName to array, and lop off the last part,
481                 //so that . matches that "directory" and not name of the baseName's
482                 //module. For instance, baseName of "one/two/three", maps to
483                 //"one/two/three.js", but we want the directory, "one/two" for
484                 //this normalization.
485                 baseName = baseName.split("/");
486                 baseName = baseName.slice(0, baseName.length - 1);
487
488                 name = baseName.concat(name.split("/"));
489
490                 //start trimDots
491                 var i, part;
492                 for (i = 0; (part = name[i]); i++) {
493                     if (part === ".") {
494                         name.splice(i, 1);
495                         i -= 1;
496                     } else if (part === "..") {
497                         if (i === 1 && (name[2] === '..' || name[0] === '..')) {
498                             //End of the line. Keep at least one non-dot
499                             //path segment at the front so it can be mapped
500                             //correctly to disk. Otherwise, there is likely
501                             //no path mapping for a path starting with '..'.
502                             //This can still fail, but catches the most reasonable
503                             //uses of ..
504                             break;
505                         } else if (i > 0) {
506                             name.splice(i - 1, 2);
507                             i -= 2;
508                         }
509                     }
510                 }
511                 //end trimDots
512
513                 name = name.join("/");
514             }
515         }
516         return name;
517     }
518
519     function makeRequire(relName, forceSync) {
520         return function () {
521             //A version of a require function that passes a moduleName
522             //value for items that may need to
523             //look up paths relative to the moduleName
524             return req.apply(undef, aps.call(arguments, 0).concat([relName, forceSync]));
525         };
526     }
527
528     function makeNormalize(relName) {
529         return function (name) {
530             return normalize(name, relName);
531         };
532     }
533
534     function makeLoad(depName) {
535         return function (value) {
536             defined[depName] = value;
537         };
538     }
539
540     function callDep(name) {
541         if (waiting.hasOwnProperty(name)) {
542             var args = waiting[name];
543             delete waiting[name];
544             main.apply(undef, args);
545         }
546         return defined[name];
547     }
548
549     /**
550      * Makes a name map, normalizing the name, and using a plugin
551      * for normalization if necessary. Grabs a ref to plugin
552      * too, as an optimization.
553      */
554     function makeMap(name, relName) {
555         var prefix, plugin,
556             index = name.indexOf('!');
557
558         if (index !== -1) {
559             prefix = normalize(name.slice(0, index), relName);
560             name = name.slice(index + 1);
561             plugin = callDep(prefix);
562
563             //Normalize according
564             if (plugin && plugin.normalize) {
565                 name = plugin.normalize(name, makeNormalize(relName));
566             } else {
567                 name = normalize(name, relName);
568             }
569         } else {
570             name = normalize(name, relName);
571         }
572
573         //Using ridiculous property names for space reasons
574         return {
575             f: prefix ? prefix + '!' + name : name, //fullName
576             n: name,
577             p: plugin
578         };
579     }
580
581     main = function (name, deps, callback, relName) {
582         var args = [],
583             usingExports,
584             cjsModule, depName, i, ret, map;
585
586         //Use name if no relName
587         if (!relName) {
588             relName = name;
589         }
590
591         //Call the callback to define the module, if necessary.
592         if (typeof callback === 'function') {
593
594             //Default to require, exports, module if no deps if
595             //the factory arg has any arguments specified.
596             if (!deps.length && callback.length) {
597                 deps = ['require', 'exports', 'module'];
598             }
599
600             //Pull out the defined dependencies and pass the ordered
601             //values to the callback.
602             for (i = 0; i < deps.length; i++) {
603                 map = makeMap(deps[i], relName);
604                 depName = map.f;
605
606                 //Fast path CommonJS standard dependencies.
607                 if (depName === "require") {
608                     args[i] = makeRequire(name);
609                 } else if (depName === "exports") {
610                     //CommonJS module spec 1.1
611                     args[i] = defined[name] = {};
612                     usingExports = true;
613                 } else if (depName === "module") {
614                     //CommonJS module spec 1.1
615                     cjsModule = args[i] = {
616                         id: name,
617                         uri: '',
618                         exports: defined[name]
619                     };
620                 } else if (defined.hasOwnProperty(depName) || waiting.hasOwnProperty(depName)) {
621                     args[i] = callDep(depName);
622                 } else if (map.p) {
623                     map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
624                     args[i] = defined[depName];
625                 } else {
626                     throw name + ' missing ' + depName;
627                 }
628             }
629
630             ret = callback.apply(defined[name], args);
631
632             if (name) {
633                 //If setting exports via "module" is in play,
634                 //favor that over return value and exports. After that,
635                 //favor a non-undefined return value over exports use.
636                 if (cjsModule && cjsModule.exports !== undef) {
637                     defined[name] = cjsModule.exports;
638                 } else if (!usingExports) {
639                     //Use the return value from the function.
640                     defined[name] = ret;
641                 }
642             }
643         } else if (name) {
644             //May just be an object definition for the module. Only
645             //worry about defining if have a module name.
646             defined[name] = callback;
647         }
648     };
649
650     requirejs = req = function (deps, callback, relName, forceSync) {
651         if (typeof deps === "string") {
652
653             //Just return the module wanted. In this scenario, the
654             //deps arg is the module name, and second arg (if passed)
655             //is just the relName.
656             //Normalize module name, if it contains . or ..
657             return callDep(makeMap(deps, callback).f);
658         } else if (!deps.splice) {
659             //deps is a config object, not an array.
660             //Drop the config stuff on the ground.
661             if (callback.splice) {
662                 //callback is an array, which means it is a dependency list.
663                 //Adjust args if there are dependencies
664                 deps = callback;
665                 callback = arguments[2];
666             } else {
667                 deps = [];
668             }
669         }
670
671         //Simulate async callback;
672         if (forceSync) {
673             main(undef, deps, callback, relName);
674         } else {
675             setTimeout(function () {
676                 main(undef, deps, callback, relName);
677             }, 15);
678         }
679
680         return req;
681     };
682
683     /**
684      * Just drops the config on the floor, but returns req in case
685      * the config return value is used.
686      */
687     req.config = function () {
688         return req;
689     };
690
691     /**
692      * Export require as a global, but only if it does not already exist.
693      */
694     if (!require) {
695         require = req;
696     }
697
698     define = function (name, deps, callback) {
699
700         //This module may not have dependencies
701         if (!deps.splice) {
702             //deps is not an array, so probably means
703             //an object literal or factory function for
704             //the value. Adjust args.
705             callback = deps;
706             deps = [];
707         }
708
709         if (define.unordered) {
710             waiting[name] = [name, deps, callback];
711         } else {
712             main(name, deps, callback);
713         }
714     };
715
716     define.amd = {
717         jQuery: true
718     };
719 }());
720 /*!
721  * jQuery JavaScript Library v1.6
722  * http://jquery.com/
723  *
724  * Copyright 2011, John Resig
725  * licensed under the MIT 
726  * http://jquery.org/license
727  *
728  * Includes Sizzle.js
729  * http://sizzlejs.com/
730  * Copyright 2011, The Dojo Foundation
731  * Released under the MIT, BSD, and GPL Licenses.
732  *
733  * Date: Mon May 2 13:50:00 2011 -0400
734  */
735 (function( window, undefined ) {
736
737 // Use the correct document accordingly with window argument (sandbox)
738 var document = window.document,
739         navigator = window.navigator,
740         location = window.location;
741 var jQuery = (function() {
742
743 // Define a local copy of jQuery
744 var jQuery = function( selector, context ) {
745                 // The jQuery object is actually just the init constructor 'enhanced'
746                 return new jQuery.fn.init( selector, context, rootjQuery );
747         },
748
749         // Map over jQuery in case of overwrite
750         _jQuery = window.jQuery,
751
752         // Map over the $ in case of overwrite
753         _$ = window.$,
754
755         // A central reference to the root jQuery(document)
756         rootjQuery,
757
758         // A simple way to check for HTML strings or ID strings
759         // (both of which we optimize for)
760         quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
761
762         // Check if a string has a non-whitespace character in it
763         rnotwhite = /\S/,
764
765         // Used for trimming whitespace
766         trimLeft = /^\s+/,
767         trimRight = /\s+$/,
768
769         // Check for digits
770         rdigit = /\d/,
771
772         // Match a standalone tag
773         rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
774
775         // JSON RegExp
776         rvalidchars = /^[\],:{}\s]*$/,
777         rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
778         rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
779         rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
780
781         // Useragent RegExp
782         rwebkit = /(webkit)[ \/]([\w.]+)/,
783         ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
784         rmsie = /(msie) ([\w.]+)/,
785         rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
786
787         // Keep a UserAgent string for use with jQuery.browser
788         userAgent = navigator.userAgent,
789
790         // For matching the engine and version of the browser
791         browserMatch,
792
793         // The deferred used on DOM ready
794         readyList,
795
796         // The ready event handler
797         DOMContentLoaded,
798
799         // Save a reference to some core methods
800         toString = Object.prototype.toString,
801         hasOwn = Object.prototype.hasOwnProperty,
802         push = Array.prototype.push,
803         slice = Array.prototype.slice,
804         trim = String.prototype.trim,
805         indexOf = Array.prototype.indexOf,
806
807         // [[Class]] -> type pairs
808         class2type = {};
809
810 jQuery.fn = jQuery.prototype = {
811         constructor: jQuery,
812         init: function( selector, context, rootjQuery ) {
813                 var match, elem, ret, doc;
814
815                 // Handle $(""), $(null), or $(undefined)
816                 if ( !selector ) {
817                         return this;
818                 }
819
820                 // Handle $(DOMElement)
821                 if ( selector.nodeType ) {
822                         this.context = this[0] = selector;
823                         this.length = 1;
824                         return this;
825                 }
826
827                 // The body element only exists once, optimize finding it
828                 if ( selector === "body" && !context && document.body ) {
829                         this.context = document;
830                         this[0] = document.body;
831                         this.selector = selector;
832                         this.length = 1;
833                         return this;
834                 }
835
836                 // Handle HTML strings
837                 if ( typeof selector === "string" ) {
838                         // Are we dealing with HTML string or an ID?
839                         if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
840                                 // Assume that strings that start and end with <> are HTML and skip the regex check
841                                 match = [ null, selector, null ];
842
843                         } else {
844                                 match = quickExpr.exec( selector );
845                         }
846
847                         // Verify a match, and that no context was specified for #id
848                         if ( match && (match[1] || !context) ) {
849
850                                 // HANDLE: $(html) -> $(array)
851                                 if ( match[1] ) {
852                                         context = context instanceof jQuery ? context[0] : context;
853                                         doc = (context ? context.ownerDocument || context : document);
854
855                                         // If a single string is passed in and it's a single tag
856                                         // just do a createElement and skip the rest
857                                         ret = rsingleTag.exec( selector );
858
859                                         if ( ret ) {
860                                                 if ( jQuery.isPlainObject( context ) ) {
861                                                         selector = [ document.createElement( ret[1] ) ];
862                                                         jQuery.fn.attr.call( selector, context, true );
863
864                                                 } else {
865                                                         selector = [ doc.createElement( ret[1] ) ];
866                                                 }
867
868                                         } else {
869                                                 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
870                                                 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
871                                         }
872
873                                         return jQuery.merge( this, selector );
874
875                                 // HANDLE: $("#id")
876                                 } else {
877                                         elem = document.getElementById( match[2] );
878
879                                         // Check parentNode to catch when Blackberry 4.6 returns
880                                         // nodes that are no longer in the document #6963
881                                         if ( elem && elem.parentNode ) {
882                                                 // Handle the case where IE and Opera return items
883                                                 // by name instead of ID
884                                                 if ( elem.id !== match[2] ) {
885                                                         return rootjQuery.find( selector );
886                                                 }
887
888                                                 // Otherwise, we inject the element directly into the jQuery object
889                                                 this.length = 1;
890                                                 this[0] = elem;
891                                         }
892
893                                         this.context = document;
894                                         this.selector = selector;
895                                         return this;
896                                 }
897
898                         // HANDLE: $(expr, $(...))
899                         } else if ( !context || context.jquery ) {
900                                 return (context || rootjQuery).find( selector );
901
902                         // HANDLE: $(expr, context)
903                         // (which is just equivalent to: $(context).find(expr)
904                         } else {
905                                 return this.constructor( context ).find( selector );
906                         }
907
908                 // HANDLE: $(function)
909                 // Shortcut for document ready
910                 } else if ( jQuery.isFunction( selector ) ) {
911                         return rootjQuery.ready( selector );
912                 }
913
914                 if (selector.selector !== undefined) {
915                         this.selector = selector.selector;
916                         this.context = selector.context;
917                 }
918
919                 return jQuery.makeArray( selector, this );
920         },
921
922         // Start with an empty selector
923         selector: "",
924
925         // The current version of jQuery being used
926         jquery: "1.6",
927
928         // The default length of a jQuery object is 0
929         length: 0,
930
931         // The number of elements contained in the matched element set
932         size: function() {
933                 return this.length;
934         },
935
936         toArray: function() {
937                 return slice.call( this, 0 );
938         },
939
940         // Get the Nth element in the matched element set OR
941         // Get the whole matched element set as a clean array
942         get: function( num ) {
943                 return num == null ?
944
945                         // Return a 'clean' array
946                         this.toArray() :
947
948                         // Return just the object
949                         ( num < 0 ? this[ this.length + num ] : this[ num ] );
950         },
951
952         // Take an array of elements and push it onto the stack
953         // (returning the new matched element set)
954         pushStack: function( elems, name, selector ) {
955                 // Build a new jQuery matched element set
956                 var ret = this.constructor();
957
958                 if ( jQuery.isArray( elems ) ) {
959                         push.apply( ret, elems );
960
961                 } else {
962                         jQuery.merge( ret, elems );
963                 }
964
965                 // Add the old object onto the stack (as a reference)
966                 ret.prevObject = this;
967
968                 ret.context = this.context;
969
970                 if ( name === "find" ) {
971                         ret.selector = this.selector + (this.selector ? " " : "") + selector;
972                 } else if ( name ) {
973                         ret.selector = this.selector + "." + name + "(" + selector + ")";
974                 }
975
976                 // Return the newly-formed element set
977                 return ret;
978         },
979
980         // Execute a callback for every element in the matched set.
981         // (You can seed the arguments with an array of args, but this is
982         // only used internally.)
983         each: function( callback, args ) {
984                 return jQuery.each( this, callback, args );
985         },
986
987         ready: function( fn ) {
988                 // Attach the listeners
989                 jQuery.bindReady();
990
991                 // Add the callback
992                 readyList.done( fn );
993
994                 return this;
995         },
996
997         eq: function( i ) {
998                 return i === -1 ?
999                         this.slice( i ) :
1000                         this.slice( i, +i + 1 );
1001         },
1002
1003         first: function() {
1004                 return this.eq( 0 );
1005         },
1006
1007         last: function() {
1008                 return this.eq( -1 );
1009         },
1010
1011         slice: function() {
1012                 return this.pushStack( slice.apply( this, arguments ),
1013                         "slice", slice.call(arguments).join(",") );
1014         },
1015
1016         map: function( callback ) {
1017                 return this.pushStack( jQuery.map(this, function( elem, i ) {
1018                         return callback.call( elem, i, elem );
1019                 }));
1020         },
1021
1022         end: function() {
1023                 return this.prevObject || this.constructor(null);
1024         },
1025
1026         // For internal use only.
1027         // Behaves like an Array's method, not like a jQuery method.
1028         push: push,
1029         sort: [].sort,
1030         splice: [].splice
1031 };
1032
1033 // Give the init function the jQuery prototype for later instantiation
1034 jQuery.fn.init.prototype = jQuery.fn;
1035
1036 jQuery.extend = jQuery.fn.extend = function() {
1037         var options, name, src, copy, copyIsArray, clone,
1038                 target = arguments[0] || {},
1039                 i = 1,
1040                 length = arguments.length,
1041                 deep = false;
1042
1043         // Handle a deep copy situation
1044         if ( typeof target === "boolean" ) {
1045                 deep = target;
1046                 target = arguments[1] || {};
1047                 // skip the boolean and the target
1048                 i = 2;
1049         }
1050
1051         // Handle case when target is a string or something (possible in deep copy)
1052         if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
1053                 target = {};
1054         }
1055
1056         // extend jQuery itself if only one argument is passed
1057         if ( length === i ) {
1058                 target = this;
1059                 --i;
1060         }
1061
1062         for ( ; i < length; i++ ) {
1063                 // Only deal with non-null/undefined values
1064                 if ( (options = arguments[ i ]) != null ) {
1065                         // Extend the base object
1066                         for ( name in options ) {
1067                                 src = target[ name ];
1068                                 copy = options[ name ];
1069
1070                                 // Prevent never-ending loop
1071                                 if ( target === copy ) {
1072                                         continue;
1073                                 }
1074
1075                                 // Recurse if we're merging plain objects or arrays
1076                                 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
1077                                         if ( copyIsArray ) {
1078                                                 copyIsArray = false;
1079                                                 clone = src && jQuery.isArray(src) ? src : [];
1080
1081                                         } else {
1082                                                 clone = src && jQuery.isPlainObject(src) ? src : {};
1083                                         }
1084
1085                                         // Never move original objects, clone them
1086                                         target[ name ] = jQuery.extend( deep, clone, copy );
1087
1088                                 // Don't bring in undefined values
1089                                 } else if ( copy !== undefined ) {
1090                                         target[ name ] = copy;
1091                                 }
1092                         }
1093                 }
1094         }
1095
1096         // Return the modified object
1097         return target;
1098 };
1099
1100 jQuery.extend({
1101         noConflict: function( deep ) {
1102                 if ( window.$ === jQuery ) {
1103                         window.$ = _$;
1104                 }
1105
1106                 if ( deep && window.jQuery === jQuery ) {
1107                         window.jQuery = _jQuery;
1108                 }
1109
1110                 return jQuery;
1111         },
1112
1113         // Is the DOM ready to be used? Set to true once it occurs.
1114         isReady: false,
1115
1116         // A counter to track how many items to wait for before
1117         // the ready event fires. See #6781
1118         readyWait: 1,
1119
1120         // Hold (or release) the ready event
1121         holdReady: function( hold ) {
1122                 if ( hold ) {
1123                         jQuery.readyWait++;
1124                 } else {
1125                         jQuery.ready( true );
1126                 }
1127         },
1128
1129         // Handle when the DOM is ready
1130         ready: function( wait ) {
1131                 // Either a released hold or an DOMready/load event and not yet ready
1132                 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
1133                         // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
1134                         if ( !document.body ) {
1135                                 return setTimeout( jQuery.ready, 1 );
1136                         }
1137
1138                         // Remember that the DOM is ready
1139                         jQuery.isReady = true;
1140
1141                         // If a normal DOM Ready event fired, decrement, and wait if need be
1142                         if ( wait !== true && --jQuery.readyWait > 0 ) {
1143                                 return;
1144                         }
1145
1146                         // If there are functions bound, to execute
1147                         readyList.resolveWith( document, [ jQuery ] );
1148
1149                         // Trigger any bound ready events
1150                         if ( jQuery.fn.trigger ) {
1151                                 jQuery( document ).trigger( "ready" ).unbind( "ready" );
1152                         }
1153                 }
1154         },
1155
1156         bindReady: function() {
1157                 if ( readyList ) {
1158                         return;
1159                 }
1160
1161                 readyList = jQuery._Deferred();
1162
1163                 // Catch cases where $(document).ready() is called after the
1164                 // browser event has already occurred.
1165                 if ( document.readyState === "complete" ) {
1166                         // Handle it asynchronously to allow scripts the opportunity to delay ready
1167                         return setTimeout( jQuery.ready, 1 );
1168                 }
1169
1170                 // Mozilla, Opera and webkit nightlies currently support this event
1171                 if ( document.addEventListener ) {
1172                         // Use the handy event callback
1173                         document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
1174
1175                         // A fallback to window.onload, that will always work
1176                         window.addEventListener( "load", jQuery.ready, false );
1177
1178                 // If IE event model is used
1179                 } else if ( document.attachEvent ) {
1180                         // ensure firing before onload,
1181                         // maybe late but safe also for iframes
1182                         document.attachEvent( "onreadystatechange", DOMContentLoaded );
1183
1184                         // A fallback to window.onload, that will always work
1185                         window.attachEvent( "onload", jQuery.ready );
1186
1187                         // If IE and not a frame
1188                         // continually check to see if the document is ready
1189                         var toplevel = false;
1190
1191                         try {
1192                                 toplevel = window.frameElement == null;
1193                         } catch(e) {}
1194
1195                         if ( document.documentElement.doScroll && toplevel ) {
1196                                 doScrollCheck();
1197                         }
1198                 }
1199         },
1200
1201         // See test/unit/core.js for details concerning isFunction.
1202         // Since version 1.3, DOM methods and functions like alert
1203         // aren't supported. They return false on IE (#2968).
1204         isFunction: function( obj ) {
1205                 return jQuery.type(obj) === "function";
1206         },
1207
1208         isArray: Array.isArray || function( obj ) {
1209                 return jQuery.type(obj) === "array";
1210         },
1211
1212         // A crude way of determining if an object is a window
1213         isWindow: function( obj ) {
1214                 return obj && typeof obj === "object" && "setInterval" in obj;
1215         },
1216
1217         isNaN: function( obj ) {
1218                 return obj == null || !rdigit.test( obj ) || isNaN( obj );
1219         },
1220
1221         type: function( obj ) {
1222                 return obj == null ?
1223                         String( obj ) :
1224                         class2type[ toString.call(obj) ] || "object";
1225         },
1226
1227         isPlainObject: function( obj ) {
1228                 // Must be an Object.
1229                 // Because of IE, we also have to check the presence of the constructor property.
1230                 // Make sure that DOM nodes and window objects don't pass through, as well
1231                 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
1232                         return false;
1233                 }
1234
1235                 // Not own constructor property must be Object
1236                 if ( obj.constructor &&
1237                         !hasOwn.call(obj, "constructor") &&
1238                         !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
1239                         return false;
1240                 }
1241
1242                 // Own properties are enumerated firstly, so to speed up,
1243                 // if last one is own, then all properties are own.
1244
1245                 var key;
1246                 for ( key in obj ) {}
1247
1248                 return key === undefined || hasOwn.call( obj, key );
1249         },
1250
1251         isEmptyObject: function( obj ) {
1252                 for ( var name in obj ) {
1253                         return false;
1254                 }
1255                 return true;
1256         },
1257
1258         error: function( msg ) {
1259                 throw msg;
1260         },
1261
1262         parseJSON: function( data ) {
1263                 if ( typeof data !== "string" || !data ) {
1264                         return null;
1265                 }
1266
1267                 // Make sure leading/trailing whitespace is removed (IE can't handle it)
1268                 data = jQuery.trim( data );
1269
1270                 // Attempt to parse using the native JSON parser first
1271                 if ( window.JSON && window.JSON.parse ) {
1272                         return window.JSON.parse( data );
1273                 }
1274
1275                 // Make sure the incoming data is actual JSON
1276                 // Logic borrowed from http://json.org/json2.js
1277                 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
1278                         .replace( rvalidtokens, "]" )
1279                         .replace( rvalidbraces, "")) ) {
1280
1281                         return (new Function( "return " + data ))();
1282
1283                 }
1284                 jQuery.error( "Invalid JSON: " + data );
1285         },
1286
1287         // Cross-browser xml parsing
1288         // (xml & tmp used internally)
1289         parseXML: function( data , xml , tmp ) {
1290
1291                 if ( window.DOMParser ) { // Standard
1292                         tmp = new DOMParser();
1293                         xml = tmp.parseFromString( data , "text/xml" );
1294                 } else { // IE
1295                         xml = new ActiveXObject( "Microsoft.XMLDOM" );
1296                         xml.async = "false";
1297                         xml.loadXML( data );
1298                 }
1299
1300                 tmp = xml.documentElement;
1301
1302                 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
1303                         jQuery.error( "Invalid XML: " + data );
1304                 }
1305
1306                 return xml;
1307         },
1308
1309         noop: function() {},
1310
1311         // Evaluates a script in a global context
1312         // Workarounds based on findings by Jim Driscoll
1313         // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
1314         globalEval: function( data ) {
1315                 if ( data && rnotwhite.test( data ) ) {
1316                         // We use execScript on Internet Explorer
1317                         // We use an anonymous function so that context is window
1318                         // rather than jQuery in Firefox
1319                         ( window.execScript || function( data ) {
1320                                 window[ "eval" ].call( window, data );
1321                         } )( data );
1322                 }
1323         },
1324
1325         nodeName: function( elem, name ) {
1326                 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
1327         },
1328
1329         // args is for internal usage only
1330         each: function( object, callback, args ) {
1331                 var name, i = 0,
1332                         length = object.length,
1333                         isObj = length === undefined || jQuery.isFunction( object );
1334
1335                 if ( args ) {
1336                         if ( isObj ) {
1337                                 for ( name in object ) {
1338                                         if ( callback.apply( object[ name ], args ) === false ) {
1339                                                 break;
1340                                         }
1341                                 }
1342                         } else {
1343                                 for ( ; i < length; ) {
1344                                         if ( callback.apply( object[ i++ ], args ) === false ) {
1345                                                 break;
1346                                         }
1347                                 }
1348                         }
1349
1350                 // A special, fast, case for the most common use of each
1351                 } else {
1352                         if ( isObj ) {
1353                                 for ( name in object ) {
1354                                         if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
1355                                                 break;
1356                                         }
1357                                 }
1358                         } else {
1359                                 for ( ; i < length; ) {
1360                                         if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
1361                                                 break;
1362                                         }
1363                                 }
1364                         }
1365                 }
1366
1367                 return object;
1368         },
1369
1370         // Use native String.trim function wherever possible
1371         trim: trim ?
1372                 function( text ) {
1373                         return text == null ?
1374                                 "" :
1375                                 trim.call( text );
1376                 } :
1377
1378                 // Otherwise use our own trimming functionality
1379                 function( text ) {
1380                         return text == null ?
1381                                 "" :
1382                                 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
1383                 },
1384
1385         // results is for internal usage only
1386         makeArray: function( array, results ) {
1387                 var ret = results || [];
1388
1389                 if ( array != null ) {
1390                         // The window, strings (and functions) also have 'length'
1391                         // The extra typeof function check is to prevent crashes
1392                         // in Safari 2 (See: #3039)
1393                         // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
1394                         var type = jQuery.type( array );
1395
1396                         if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
1397                                 push.call( ret, array );
1398                         } else {
1399                                 jQuery.merge( ret, array );
1400                         }
1401                 }
1402
1403                 return ret;
1404         },
1405
1406         inArray: function( elem, array ) {
1407
1408                 if ( indexOf ) {
1409                         return indexOf.call( array, elem );
1410                 }
1411
1412                 for ( var i = 0, length = array.length; i < length; i++ ) {
1413                         if ( array[ i ] === elem ) {
1414                                 return i;
1415                         }
1416                 }
1417
1418                 return -1;
1419         },
1420
1421         merge: function( first, second ) {
1422                 var i = first.length,
1423                         j = 0;
1424
1425                 if ( typeof second.length === "number" ) {
1426                         for ( var l = second.length; j < l; j++ ) {
1427                                 first[ i++ ] = second[ j ];
1428                         }
1429
1430                 } else {
1431                         while ( second[j] !== undefined ) {
1432                                 first[ i++ ] = second[ j++ ];
1433                         }
1434                 }
1435
1436                 first.length = i;
1437
1438                 return first;
1439         },
1440
1441         grep: function( elems, callback, inv ) {
1442                 var ret = [], retVal;
1443                 inv = !!inv;
1444
1445                 // Go through the array, only saving the items
1446                 // that pass the validator function
1447                 for ( var i = 0, length = elems.length; i < length; i++ ) {
1448                         retVal = !!callback( elems[ i ], i );
1449                         if ( inv !== retVal ) {
1450                                 ret.push( elems[ i ] );
1451                         }
1452                 }
1453
1454                 return ret;
1455         },
1456
1457         // arg is for internal usage only
1458         map: function( elems, callback, arg ) {
1459                 var value, key, ret = [],
1460                         i = 0,
1461                         length = elems.length,
1462                         // jquery objects are treated as arrays
1463                         isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
1464
1465                 // Go through the array, translating each of the items to their
1466                 if ( isArray ) {
1467                         for ( ; i < length; i++ ) {
1468                                 value = callback( elems[ i ], i, arg );
1469
1470                                 if ( value != null ) {
1471                                         ret[ ret.length ] = value;
1472                                 }
1473                         }
1474
1475                 // Go through every key on the object,
1476                 } else {
1477                         for ( key in elems ) {
1478                                 value = callback( elems[ key ], key, arg );
1479
1480                                 if ( value != null ) {
1481                                         ret[ ret.length ] = value;
1482                                 }
1483                         }
1484                 }
1485
1486                 // Flatten any nested arrays
1487                 return ret.concat.apply( [], ret );
1488         },
1489
1490         // A global GUID counter for objects
1491         guid: 1,
1492
1493         // Bind a function to a context, optionally partially applying any
1494         // arguments.
1495         proxy: function( fn, context ) {
1496                 if ( typeof context === "string" ) {
1497                         var tmp = fn[ context ];
1498                         context = fn;
1499                         fn = tmp;
1500                 }
1501
1502                 // Quick check to determine if target is callable, in the spec
1503                 // this throws a TypeError, but we will just return undefined.
1504                 if ( !jQuery.isFunction( fn ) ) {
1505                         return undefined;
1506                 }
1507
1508                 // Simulated bind
1509                 var args = slice.call( arguments, 2 ),
1510                         proxy = function() {
1511                                 return fn.apply( context, args.concat( slice.call( arguments ) ) );
1512                         };
1513
1514                 // Set the guid of unique handler to the same of original handler, so it can be removed
1515                 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
1516
1517                 return proxy;
1518         },
1519
1520         // Mutifunctional method to get and set values to a collection
1521         // The value/s can be optionally by executed if its a function
1522         access: function( elems, key, value, exec, fn, pass ) {
1523                 var length = elems.length;
1524
1525                 // Setting many attributes
1526                 if ( typeof key === "object" ) {
1527                         for ( var k in key ) {
1528                                 jQuery.access( elems, k, key[k], exec, fn, value );
1529                         }
1530                         return elems;
1531                 }
1532
1533                 // Setting one attribute
1534                 if ( value !== undefined ) {
1535                         // Optionally, function values get executed if exec is true
1536                         exec = !pass && exec && jQuery.isFunction(value);
1537
1538                         for ( var i = 0; i < length; i++ ) {
1539                                 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
1540                         }
1541
1542                         return elems;
1543                 }
1544
1545                 // Getting an attribute
1546                 return length ? fn( elems[0], key ) : undefined;
1547         },
1548
1549         now: function() {
1550                 return (new Date()).getTime();
1551         },
1552
1553         // Use of jQuery.browser is frowned upon.
1554         // More details: http://docs.jquery.com/Utilities/jQuery.browser
1555         uaMatch: function( ua ) {
1556                 ua = ua.toLowerCase();
1557
1558                 var match = rwebkit.exec( ua ) ||
1559                         ropera.exec( ua ) ||
1560                         rmsie.exec( ua ) ||
1561                         ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
1562                         [];
1563
1564                 return { browser: match[1] || "", version: match[2] || "0" };
1565         },
1566
1567         sub: function() {
1568                 function jQuerySub( selector, context ) {
1569                         return new jQuerySub.fn.init( selector, context );
1570                 }
1571                 jQuery.extend( true, jQuerySub, this );
1572                 jQuerySub.superclass = this;
1573                 jQuerySub.fn = jQuerySub.prototype = this();
1574                 jQuerySub.fn.constructor = jQuerySub;
1575                 jQuerySub.sub = this.sub;
1576                 jQuerySub.fn.init = function init( selector, context ) {
1577                         if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
1578                                 context = jQuerySub( context );
1579                         }
1580
1581                         return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
1582                 };
1583                 jQuerySub.fn.init.prototype = jQuerySub.fn;
1584                 var rootjQuerySub = jQuerySub(document);
1585                 return jQuerySub;
1586         },
1587
1588         browser: {}
1589 });
1590
1591 // Populate the class2type map
1592 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
1593         class2type[ "[object " + name + "]" ] = name.toLowerCase();
1594 });
1595
1596 browserMatch = jQuery.uaMatch( userAgent );
1597 if ( browserMatch.browser ) {
1598         jQuery.browser[ browserMatch.browser ] = true;
1599         jQuery.browser.version = browserMatch.version;
1600 }
1601
1602 // Deprecated, use jQuery.browser.webkit instead
1603 if ( jQuery.browser.webkit ) {
1604         jQuery.browser.safari = true;
1605 }
1606
1607 // IE doesn't match non-breaking spaces with \s
1608 if ( rnotwhite.test( "\xA0" ) ) {
1609         trimLeft = /^[\s\xA0]+/;
1610         trimRight = /[\s\xA0]+$/;
1611 }
1612
1613 // All jQuery objects should point back to these
1614 rootjQuery = jQuery(document);
1615
1616 // Cleanup functions for the document ready method
1617 if ( document.addEventListener ) {
1618         DOMContentLoaded = function() {
1619                 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
1620                 jQuery.ready();
1621         };
1622
1623 } else if ( document.attachEvent ) {
1624         DOMContentLoaded = function() {
1625                 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
1626                 if ( document.readyState === "complete" ) {
1627                         document.detachEvent( "onreadystatechange", DOMContentLoaded );
1628                         jQuery.ready();
1629                 }
1630         };
1631 }
1632
1633 // The DOM ready check for Internet Explorer
1634 function doScrollCheck() {
1635         if ( jQuery.isReady ) {
1636                 return;
1637         }
1638
1639         try {
1640                 // If IE is used, use the trick by Diego Perini
1641                 // http://javascript.nwbox.com/IEContentLoaded/
1642                 document.documentElement.doScroll("left");
1643         } catch(e) {
1644                 setTimeout( doScrollCheck, 1 );
1645                 return;
1646         }
1647
1648         // and execute any waiting functions
1649         jQuery.ready();
1650 }
1651
1652 // Expose jQuery to the global object
1653 return jQuery;
1654
1655 })();
1656
1657
1658 var // Promise methods
1659         promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
1660         // Static reference to slice
1661         sliceDeferred = [].slice;
1662
1663 jQuery.extend({
1664         // Create a simple deferred (one callbacks list)
1665         _Deferred: function() {
1666                 var // callbacks list
1667                         callbacks = [],
1668                         // stored [ context , args ]
1669                         fired,
1670                         // to avoid firing when already doing so
1671                         firing,
1672                         // flag to know if the deferred has been cancelled
1673                         cancelled,
1674                         // the deferred itself
1675                         deferred  = {
1676
1677                                 // done( f1, f2, ...)
1678                                 done: function() {
1679                                         if ( !cancelled ) {
1680                                                 var args = arguments,
1681                                                         i,
1682                                                         length,
1683                                                         elem,
1684                                                         type,
1685                                                         _fired;
1686                                                 if ( fired ) {
1687                                                         _fired = fired;
1688                                                         fired = 0;
1689                                                 }
1690                                                 for ( i = 0, length = args.length; i < length; i++ ) {
1691                                                         elem = args[ i ];
1692                                                         type = jQuery.type( elem );
1693                                                         if ( type === "array" ) {
1694                                                                 deferred.done.apply( deferred, elem );
1695                                                         } else if ( type === "function" ) {
1696                                                                 callbacks.push( elem );
1697                                                         }
1698                                                 }
1699                                                 if ( _fired ) {
1700                                                         deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
1701                                                 }
1702                                         }
1703                                         return this;
1704                                 },
1705
1706                                 // resolve with given context and args
1707                                 resolveWith: function( context, args ) {
1708                                         if ( !cancelled && !fired && !firing ) {
1709                                                 // make sure args are available (#8421)
1710                                                 args = args || [];
1711                                                 firing = 1;
1712                                                 try {
1713                                                         while( callbacks[ 0 ] ) {
1714                                                                 callbacks.shift().apply( context, args );
1715                                                         }
1716                                                 }
1717                                                 finally {
1718                                                         fired = [ context, args ];
1719                                                         firing = 0;
1720                                                 }
1721                                         }
1722                                         return this;
1723                                 },
1724
1725                                 // resolve with this as context and given arguments
1726                                 resolve: function() {
1727                                         deferred.resolveWith( this, arguments );
1728                                         return this;
1729                                 },
1730
1731                                 // Has this deferred been resolved?
1732                                 isResolved: function() {
1733                                         return !!( firing || fired );
1734                                 },
1735
1736                                 // Cancel
1737                                 cancel: function() {
1738                                         cancelled = 1;
1739                                         callbacks = [];
1740                                         return this;
1741                                 }
1742                         };
1743
1744                 return deferred;
1745         },
1746
1747         // Full fledged deferred (two callbacks list)
1748         Deferred: function( func ) {
1749                 var deferred = jQuery._Deferred(),
1750                         failDeferred = jQuery._Deferred(),
1751                         promise;
1752                 // Add errorDeferred methods, then and promise
1753                 jQuery.extend( deferred, {
1754                         then: function( doneCallbacks, failCallbacks ) {
1755                                 deferred.done( doneCallbacks ).fail( failCallbacks );
1756                                 return this;
1757                         },
1758                         always: function() {
1759                                 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1760                         },
1761                         fail: failDeferred.done,
1762                         rejectWith: failDeferred.resolveWith,
1763                         reject: failDeferred.resolve,
1764                         isRejected: failDeferred.isResolved,
1765                         pipe: function( fnDone, fnFail ) {
1766                                 return jQuery.Deferred(function( newDefer ) {
1767                                         jQuery.each( {
1768                                                 done: [ fnDone, "resolve" ],
1769                                                 fail: [ fnFail, "reject" ]
1770                                         }, function( handler, data ) {
1771                                                 var fn = data[ 0 ],
1772                                                         action = data[ 1 ],
1773                                                         returned;
1774                                                 if ( jQuery.isFunction( fn ) ) {
1775                                                         deferred[ handler ](function() {
1776                                                                 returned = fn.apply( this, arguments );
1777                                                                 if ( jQuery.isFunction( returned.promise ) ) {
1778                                                                         returned.promise().then( newDefer.resolve, newDefer.reject );
1779                                                                 } else {
1780                                                                         newDefer[ action ]( returned );
1781                                                                 }
1782                                                         });
1783                                                 } else {
1784                                                         deferred[ handler ]( newDefer[ action ] );
1785                                                 }
1786                                         });
1787                                 }).promise();
1788                         },
1789                         // Get a promise for this deferred
1790                         // If obj is provided, the promise aspect is added to the object
1791                         promise: function( obj ) {
1792                                 if ( obj == null ) {
1793                                         if ( promise ) {
1794                                                 return promise;
1795                                         }
1796                                         promise = obj = {};
1797                                 }
1798                                 var i = promiseMethods.length;
1799                                 while( i-- ) {
1800                                         obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1801                                 }
1802                                 return obj;
1803                         }
1804                 });
1805                 // Make sure only one callback list will be used
1806                 deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1807                 // Unexpose cancel
1808                 delete deferred.cancel;
1809                 // Call given func if any
1810                 if ( func ) {
1811                         func.call( deferred, deferred );
1812                 }
1813                 return deferred;
1814         },
1815
1816         // Deferred helper
1817         when: function( firstParam ) {
1818                 var args = arguments,
1819                         i = 0,
1820                         length = args.length,
1821                         count = length,
1822                         deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1823                                 firstParam :
1824                                 jQuery.Deferred();
1825                 function resolveFunc( i ) {
1826                         return function( value ) {
1827                                 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1828                                 if ( !( --count ) ) {
1829                                         // Strange bug in FF4:
1830                                         // Values changed onto the arguments object sometimes end up as undefined values
1831                                         // outside the $.when method. Cloning the object into a fresh array solves the issue
1832                                         deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1833                                 }
1834                         };
1835                 }
1836                 if ( length > 1 ) {
1837                         for( ; i < length; i++ ) {
1838                                 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1839                                         args[ i ].promise().then( resolveFunc(i), deferred.reject );
1840                                 } else {
1841                                         --count;
1842                                 }
1843                         }
1844                         if ( !count ) {
1845                                 deferred.resolveWith( deferred, args );
1846                         }
1847                 } else if ( deferred !== firstParam ) {
1848                         deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1849                 }
1850                 return deferred.promise();
1851         }
1852 });
1853
1854
1855
1856 jQuery.support = (function() {
1857
1858         var div = document.createElement( "div" ),
1859                 all,
1860                 a,
1861                 select,
1862                 opt,
1863                 input,
1864                 marginDiv,
1865                 support,
1866                 fragment,
1867                 body,
1868                 bodyStyle,
1869                 tds,
1870                 events,
1871                 eventName,
1872                 i,
1873                 isSupported;
1874
1875         // Preliminary tests
1876         div.setAttribute("className", "t");
1877         div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1878
1879         all = div.getElementsByTagName( "*" );
1880         a = div.getElementsByTagName( "a" )[ 0 ];
1881
1882         // Can't get basic test support
1883         if ( !all || !all.length || !a ) {
1884                 return {};
1885         }
1886
1887         // First batch of supports tests
1888         select = document.createElement( "select" );
1889         opt = select.appendChild( document.createElement("option") );
1890         input = div.getElementsByTagName( "input" )[ 0 ];
1891
1892         support = {
1893                 // IE strips leading whitespace when .innerHTML is used
1894                 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1895
1896                 // Make sure that tbody elements aren't automatically inserted
1897                 // IE will insert them into empty tables
1898                 tbody: !div.getElementsByTagName( "tbody" ).length,
1899
1900                 // Make sure that link elements get serialized correctly by innerHTML
1901                 // This requires a wrapper element in IE
1902                 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1903
1904                 // Get the style information from getAttribute
1905                 // (IE uses .cssText instead)
1906                 style: /top/.test( a.getAttribute("style") ),
1907
1908                 // Make sure that URLs aren't manipulated
1909                 // (IE normalizes it by default)
1910                 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1911
1912                 // Make sure that element opacity exists
1913                 // (IE uses filter instead)
1914                 // Use a regex to work around a WebKit issue. See #5145
1915                 opacity: /^0.55$/.test( a.style.opacity ),
1916
1917                 // Verify style float existence
1918                 // (IE uses styleFloat instead of cssFloat)
1919                 cssFloat: !!a.style.cssFloat,
1920
1921                 // Make sure that if no value is specified for a checkbox
1922                 // that it defaults to "on".
1923                 // (WebKit defaults to "" instead)
1924                 checkOn: ( input.value === "on" ),
1925
1926                 // Make sure that a selected-by-default option has a working selected property.
1927                 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1928                 optSelected: opt.selected,
1929
1930                 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1931                 getSetAttribute: div.className !== "t",
1932
1933                 // Will be defined later
1934                 submitBubbles: true,
1935                 changeBubbles: true,
1936                 focusinBubbles: false,
1937                 deleteExpando: true,
1938                 noCloneEvent: true,
1939                 inlineBlockNeedsLayout: false,
1940                 shrinkWrapBlocks: false,
1941                 reliableMarginRight: true
1942         };
1943
1944         // Make sure checked status is properly cloned
1945         input.checked = true;
1946         support.noCloneChecked = input.cloneNode( true ).checked;
1947
1948         // Make sure that the options inside disabled selects aren't marked as disabled
1949         // (WebKit marks them as disabled)
1950         select.disabled = true;
1951         support.optDisabled = !opt.disabled;
1952
1953         // Test to see if it's possible to delete an expando from an element
1954         // Fails in Internet Explorer
1955         try {
1956                 delete div.test;
1957         } catch( e ) {
1958                 support.deleteExpando = false;
1959         }
1960
1961         if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1962                 div.attachEvent( "onclick", function click() {
1963                         // Cloning a node shouldn't copy over any
1964                         // bound event handlers (IE does this)
1965                         support.noCloneEvent = false;
1966                         div.detachEvent( "onclick", click );
1967                 });
1968                 div.cloneNode( true ).fireEvent( "onclick" );
1969         }
1970
1971         // Check if a radio maintains it's value
1972         // after being appended to the DOM
1973         input = document.createElement("input");
1974         input.value = "t";
1975         input.setAttribute("type", "radio");
1976         support.radioValue = input.value === "t";
1977
1978         input.setAttribute("checked", "checked");
1979         div.appendChild( input );
1980         fragment = document.createDocumentFragment();
1981         fragment.appendChild( div.firstChild );
1982
1983         // WebKit doesn't clone checked state correctly in fragments
1984         support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1985
1986         div.innerHTML = "";
1987
1988         // Figure out if the W3C box model works as expected
1989         div.style.width = div.style.paddingLeft = "1px";
1990
1991         // We use our own, invisible, body
1992         body = document.createElement( "body" );
1993         bodyStyle = {
1994                 visibility: "hidden",
1995                 width: 0,
1996                 height: 0,
1997                 border: 0,
1998                 margin: 0,
1999                 // Set background to avoid IE crashes when removing (#9028)
2000                 background: "none"
2001         };
2002         for ( i in bodyStyle ) {
2003                 body.style[ i ] = bodyStyle[ i ];
2004         }
2005         body.appendChild( div );
2006         document.documentElement.appendChild( body );
2007
2008         // Check if a disconnected checkbox will retain its checked
2009         // value of true after appended to the DOM (IE6/7)
2010         support.appendChecked = input.checked;
2011
2012         support.boxModel = div.offsetWidth === 2;
2013
2014         if ( "zoom" in div.style ) {
2015                 // Check if natively block-level elements act like inline-block
2016                 // elements when setting their display to 'inline' and giving
2017                 // them layout
2018                 // (IE < 8 does this)
2019                 div.style.display = "inline";
2020                 div.style.zoom = 1;
2021                 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
2022
2023                 // Check if elements with layout shrink-wrap their children
2024                 // (IE 6 does this)
2025                 div.style.display = "";
2026                 div.innerHTML = "<div style='width:4px;'></div>";
2027                 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
2028         }
2029
2030         div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
2031         tds = div.getElementsByTagName( "td" );
2032
2033         // Check if table cells still have offsetWidth/Height when they are set
2034         // to display:none and there are still other visible table cells in a
2035         // table row; if so, offsetWidth/Height are not reliable for use when
2036         // determining if an element has been hidden directly using
2037         // display:none (it is still safe to use offsets if a parent element is
2038         // hidden; don safety goggles and see bug #4512 for more information).
2039         // (only IE 8 fails this test)
2040         isSupported = ( tds[ 0 ].offsetHeight === 0 );
2041
2042         tds[ 0 ].style.display = "";
2043         tds[ 1 ].style.display = "none";
2044
2045         // Check if empty table cells still have offsetWidth/Height
2046         // (IE < 8 fail this test)
2047         support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
2048         div.innerHTML = "";
2049
2050         // Check if div with explicit width and no margin-right incorrectly
2051         // gets computed margin-right based on width of container. For more
2052         // info see bug #3333
2053         // Fails in WebKit before Feb 2011 nightlies
2054         // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
2055         if ( document.defaultView && document.defaultView.getComputedStyle ) {
2056                 marginDiv = document.createElement( "div" );
2057                 marginDiv.style.width = "0";
2058                 marginDiv.style.marginRight = "0";
2059                 div.appendChild( marginDiv );
2060                 support.reliableMarginRight =
2061                         ( parseInt( document.defaultView.getComputedStyle( marginDiv, null ).marginRight, 10 ) || 0 ) === 0;
2062         }
2063
2064         // Remove the body element we added
2065         body.innerHTML = "";
2066         document.documentElement.removeChild( body );
2067
2068         // Technique from Juriy Zaytsev
2069         // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
2070         // We only care about the case where non-standard event systems
2071         // are used, namely in IE. Short-circuiting here helps us to
2072         // avoid an eval call (in setAttribute) which can cause CSP
2073         // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
2074         if ( div.attachEvent ) {
2075                 for( i in {
2076                         submit: 1,
2077                         change: 1,
2078                         focusin: 1
2079                 } ) {
2080                         eventName = "on" + i;
2081                         isSupported = ( eventName in div );
2082                         if ( !isSupported ) {
2083                                 div.setAttribute( eventName, "return;" );
2084                                 isSupported = ( typeof div[ eventName ] === "function" );
2085                         }
2086                         support[ i + "Bubbles" ] = isSupported;
2087                 }
2088         }
2089
2090         return support;
2091 })();
2092
2093 // Keep track of boxModel
2094 jQuery.boxModel = jQuery.support.boxModel;
2095
2096
2097
2098
2099 var rbrace = /^(?:\{.*\}|\[.*\])$/,
2100         rmultiDash = /([a-z])([A-Z])/g;
2101
2102 jQuery.extend({
2103         cache: {},
2104
2105         // Please use with caution
2106         uuid: 0,
2107
2108         // Unique for each copy of jQuery on the page
2109         // Non-digits removed to match rinlinejQuery
2110         expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
2111
2112         // The following elements throw uncatchable exceptions if you
2113         // attempt to add expando properties to them.
2114         noData: {
2115                 "embed": true,
2116                 // Ban all objects except for Flash (which handle expandos)
2117                 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
2118                 "applet": true
2119         },
2120
2121         hasData: function( elem ) {
2122                 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
2123
2124                 return !!elem && !isEmptyDataObject( elem );
2125         },
2126
2127         data: function( elem, name, data, pvt /* Internal Use Only */ ) {
2128                 if ( !jQuery.acceptData( elem ) ) {
2129                         return;
2130                 }
2131
2132                 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
2133
2134                         // We have to handle DOM nodes and JS objects differently because IE6-7
2135                         // can't GC object references properly across the DOM-JS boundary
2136                         isNode = elem.nodeType,
2137
2138                         // Only DOM nodes need the global jQuery cache; JS object data is
2139                         // attached directly to the object so GC can occur automatically
2140                         cache = isNode ? jQuery.cache : elem,
2141
2142                         // Only defining an ID for JS objects if its cache already exists allows
2143                         // the code to shortcut on the same path as a DOM node with no cache
2144                         id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
2145
2146                 // Avoid doing any more work than we need to when trying to get data on an
2147                 // object that has no data at all
2148                 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
2149                         return;
2150                 }
2151
2152                 if ( !id ) {
2153                         // Only DOM nodes need a new unique ID for each element since their data
2154                         // ends up in the global cache
2155                         if ( isNode ) {
2156                                 elem[ jQuery.expando ] = id = ++jQuery.uuid;
2157                         } else {
2158                                 id = jQuery.expando;
2159                         }
2160                 }
2161
2162                 if ( !cache[ id ] ) {
2163                         cache[ id ] = {};
2164
2165                         // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
2166                         // metadata on plain JS objects when the object is serialized using
2167                         // JSON.stringify
2168                         if ( !isNode ) {
2169                                 cache[ id ].toJSON = jQuery.noop;
2170                         }
2171                 }
2172
2173                 // An object can be passed to jQuery.data instead of a key/value pair; this gets
2174                 // shallow copied over onto the existing cache
2175                 if ( typeof name === "object" || typeof name === "function" ) {
2176                         if ( pvt ) {
2177                                 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
2178                         } else {
2179                                 cache[ id ] = jQuery.extend(cache[ id ], name);
2180                         }
2181                 }
2182
2183                 thisCache = cache[ id ];
2184
2185                 // Internal jQuery data is stored in a separate object inside the object's data
2186                 // cache in order to avoid key collisions between internal data and user-defined
2187                 // data
2188                 if ( pvt ) {
2189                         if ( !thisCache[ internalKey ] ) {
2190                                 thisCache[ internalKey ] = {};
2191                         }
2192
2193                         thisCache = thisCache[ internalKey ];
2194                 }
2195
2196                 if ( data !== undefined ) {
2197                         thisCache[ name ] = data;
2198                 }
2199
2200                 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
2201                 // not attempt to inspect the internal events object using jQuery.data, as this
2202                 // internal data object is undocumented and subject to change.
2203                 if ( name === "events" && !thisCache[name] ) {
2204                         return thisCache[ internalKey ] && thisCache[ internalKey ].events;
2205                 }
2206
2207                 return getByName ? thisCache[ name ] : thisCache;
2208         },
2209
2210         removeData: function( elem, name, pvt /* Internal Use Only */ ) {
2211                 if ( !jQuery.acceptData( elem ) ) {
2212                         return;
2213                 }
2214
2215                 var internalKey = jQuery.expando, isNode = elem.nodeType,
2216
2217                         // See jQuery.data for more information
2218                         cache = isNode ? jQuery.cache : elem,
2219
2220                         // See jQuery.data for more information
2221                         id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
2222
2223                 // If there is already no cache entry for this object, there is no
2224                 // purpose in continuing
2225                 if ( !cache[ id ] ) {
2226                         return;
2227                 }
2228
2229                 if ( name ) {
2230                         var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
2231
2232                         if ( thisCache ) {
2233                                 delete thisCache[ name ];
2234
2235                                 // If there is no data left in the cache, we want to continue
2236                                 // and let the cache object itself get destroyed
2237                                 if ( !isEmptyDataObject(thisCache) ) {
2238                                         return;
2239                                 }
2240                         }
2241                 }
2242
2243                 // See jQuery.data for more information
2244                 if ( pvt ) {
2245                         delete cache[ id ][ internalKey ];
2246
2247                         // Don't destroy the parent cache unless the internal data object
2248                         // had been the only thing left in it
2249                         if ( !isEmptyDataObject(cache[ id ]) ) {
2250                                 return;
2251                         }
2252                 }
2253
2254                 var internalCache = cache[ id ][ internalKey ];
2255
2256                 // Browsers that fail expando deletion also refuse to delete expandos on
2257                 // the window, but it will allow it on all other JS objects; other browsers
2258                 // don't care
2259                 if ( jQuery.support.deleteExpando || cache != window ) {
2260                         delete cache[ id ];
2261                 } else {
2262                         cache[ id ] = null;
2263                 }
2264
2265                 // We destroyed the entire user cache at once because it's faster than
2266                 // iterating through each key, but we need to continue to persist internal
2267                 // data if it existed
2268                 if ( internalCache ) {
2269                         cache[ id ] = {};
2270                         // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
2271                         // metadata on plain JS objects when the object is serialized using
2272                         // JSON.stringify
2273                         if ( !isNode ) {
2274                                 cache[ id ].toJSON = jQuery.noop;
2275                         }
2276
2277                         cache[ id ][ internalKey ] = internalCache;
2278
2279                 // Otherwise, we need to eliminate the expando on the node to avoid
2280                 // false lookups in the cache for entries that no longer exist
2281                 } else if ( isNode ) {
2282                         // IE does not allow us to delete expando properties from nodes,
2283                         // nor does it have a removeAttribute function on Document nodes;
2284                         // we must handle all of these cases
2285                         if ( jQuery.support.deleteExpando ) {
2286                                 delete elem[ jQuery.expando ];
2287                         } else if ( elem.removeAttribute ) {
2288                                 elem.removeAttribute( jQuery.expando );
2289                         } else {
2290                                 elem[ jQuery.expando ] = null;
2291                         }
2292                 }
2293         },
2294
2295         // For internal use only.
2296         _data: function( elem, name, data ) {
2297                 return jQuery.data( elem, name, data, true );
2298         },
2299
2300         // A method for determining if a DOM node can handle the data expando
2301         acceptData: function( elem ) {
2302                 if ( elem.nodeName ) {
2303                         var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
2304
2305                         if ( match ) {
2306                                 return !(match === true || elem.getAttribute("classid") !== match);
2307                         }
2308                 }
2309
2310                 return true;
2311         }
2312 });
2313
2314 jQuery.fn.extend({
2315         data: function( key, value ) {
2316                 var data = null;
2317
2318                 if ( typeof key === "undefined" ) {
2319                         if ( this.length ) {
2320                                 data = jQuery.data( this[0] );
2321
2322                                 if ( this[0].nodeType === 1 ) {
2323                             var attr = this[0].attributes, name;
2324                                         for ( var i = 0, l = attr.length; i < l; i++ ) {
2325                                                 name = attr[i].name;
2326
2327                                                 if ( name.indexOf( "data-" ) === 0 ) {
2328                                                         name = jQuery.camelCase( name.substring(5) );
2329
2330                                                         dataAttr( this[0], name, data[ name ] );
2331                                                 }
2332                                         }
2333                                 }
2334                         }
2335
2336                         return data;
2337
2338                 } else if ( typeof key === "object" ) {
2339                         return this.each(function() {
2340                                 jQuery.data( this, key );
2341                         });
2342                 }
2343
2344                 var parts = key.split(".");
2345                 parts[1] = parts[1] ? "." + parts[1] : "";
2346
2347                 if ( value === undefined ) {
2348                         data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
2349
2350                         // Try to fetch any internally stored data first
2351                         if ( data === undefined && this.length ) {
2352                                 data = jQuery.data( this[0], key );
2353                                 data = dataAttr( this[0], key, data );
2354                         }
2355
2356                         return data === undefined && parts[1] ?
2357                                 this.data( parts[0] ) :
2358                                 data;
2359
2360                 } else {
2361                         return this.each(function() {
2362                                 var $this = jQuery( this ),
2363                                         args = [ parts[0], value ];
2364
2365                                 $this.triggerHandler( "setData" + parts[1] + "!", args );
2366                                 jQuery.data( this, key, value );
2367                                 $this.triggerHandler( "changeData" + parts[1] + "!", args );
2368                         });
2369                 }
2370         },
2371
2372         removeData: function( key ) {
2373                 return this.each(function() {
2374                         jQuery.removeData( this, key );
2375                 });
2376         }
2377 });
2378
2379 function dataAttr( elem, key, data ) {
2380         // If nothing was found internally, try to fetch any
2381         // data from the HTML5 data-* attribute
2382         if ( data === undefined && elem.nodeType === 1 ) {
2383                 name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
2384
2385                 data = elem.getAttribute( name );
2386
2387                 if ( typeof data === "string" ) {
2388                         try {
2389                                 data = data === "true" ? true :
2390                                 data === "false" ? false :
2391                                 data === "null" ? null :
2392                                 !jQuery.isNaN( data ) ? parseFloat( data ) :
2393                                         rbrace.test( data ) ? jQuery.parseJSON( data ) :
2394                                         data;
2395                         } catch( e ) {}
2396
2397                         // Make sure we set the data so it isn't changed later
2398                         jQuery.data( elem, key, data );
2399
2400                 } else {
2401                         data = undefined;
2402                 }
2403         }
2404
2405         return data;
2406 }
2407
2408 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
2409 // property to be considered empty objects; this property always exists in
2410 // order to make sure JSON.stringify does not expose internal metadata
2411 function isEmptyDataObject( obj ) {
2412         for ( var name in obj ) {
2413                 if ( name !== "toJSON" ) {
2414                         return false;
2415                 }
2416         }
2417
2418         return true;
2419 }
2420
2421
2422
2423
2424 function handleQueueMarkDefer( elem, type, src ) {
2425         var deferDataKey = type + "defer",
2426                 queueDataKey = type + "queue",
2427                 markDataKey = type + "mark",
2428                 defer = jQuery.data( elem, deferDataKey, undefined, true );
2429         if ( defer &&
2430                 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
2431                 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
2432                 // Give room for hard-coded callbacks to fire first
2433                 // and eventually mark/queue something else on the element
2434                 setTimeout( function() {
2435                         if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
2436                                 !jQuery.data( elem, markDataKey, undefined, true ) ) {
2437                                 jQuery.removeData( elem, deferDataKey, true );
2438                                 defer.resolve();
2439                         }
2440                 }, 0 );
2441         }
2442 }
2443
2444 jQuery.extend({
2445
2446         _mark: function( elem, type ) {
2447                 if ( elem ) {
2448                         type = (type || "fx") + "mark";
2449                         jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
2450                 }
2451         },
2452
2453         _unmark: function( force, elem, type ) {
2454                 if ( force !== true ) {
2455                         type = elem;
2456                         elem = force;
2457                         force = false;
2458                 }
2459                 if ( elem ) {
2460                         type = type || "fx";
2461                         var key = type + "mark",
2462                                 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
2463                         if ( count ) {
2464                                 jQuery.data( elem, key, count, true );
2465                         } else {
2466                                 jQuery.removeData( elem, key, true );
2467                                 handleQueueMarkDefer( elem, type, "mark" );
2468                         }
2469                 }
2470         },
2471
2472         queue: function( elem, type, data ) {
2473                 if ( elem ) {
2474                         type = (type || "fx") + "queue";
2475                         var q = jQuery.data( elem, type, undefined, true );
2476                         // Speed up dequeue by getting out quickly if this is just a lookup
2477                         if ( data ) {
2478                                 if ( !q || jQuery.isArray(data) ) {
2479                                         q = jQuery.data( elem, type, jQuery.makeArray(data), true );
2480                                 } else {
2481                                         q.push( data );
2482                                 }
2483                         }
2484                         return q || [];
2485                 }
2486         },
2487
2488         dequeue: function( elem, type ) {
2489                 type = type || "fx";
2490
2491                 var queue = jQuery.queue( elem, type ),
2492                         fn = queue.shift(),
2493                         defer;
2494
2495                 // If the fx queue is dequeued, always remove the progress sentinel
2496                 if ( fn === "inprogress" ) {
2497                         fn = queue.shift();
2498                 }
2499
2500                 if ( fn ) {
2501                         // Add a progress sentinel to prevent the fx queue from being
2502                         // automatically dequeued
2503                         if ( type === "fx" ) {
2504                                 queue.unshift("inprogress");
2505                         }
2506
2507                         fn.call(elem, function() {
2508                                 jQuery.dequeue(elem, type);
2509                         });
2510                 }
2511
2512                 if ( !queue.length ) {
2513                         jQuery.removeData( elem, type + "queue", true );
2514                         handleQueueMarkDefer( elem, type, "queue" );
2515                 }
2516         }
2517 });
2518
2519 jQuery.fn.extend({
2520         queue: function( type, data ) {
2521                 if ( typeof type !== "string" ) {
2522                         data = type;
2523                         type = "fx";
2524                 }
2525
2526                 if ( data === undefined ) {
2527                         return jQuery.queue( this[0], type );
2528                 }
2529                 return this.each(function() {
2530                         var queue = jQuery.queue( this, type, data );
2531
2532                         if ( type === "fx" && queue[0] !== "inprogress" ) {
2533                                 jQuery.dequeue( this, type );
2534                         }
2535                 });
2536         },
2537         dequeue: function( type ) {
2538                 return this.each(function() {
2539                         jQuery.dequeue( this, type );
2540                 });
2541         },
2542         // Based off of the plugin by Clint Helfers, with permission.
2543         // http://blindsignals.com/index.php/2009/07/jquery-delay/
2544         delay: function( time, type ) {
2545                 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
2546                 type = type || "fx";
2547
2548                 return this.queue( type, function() {
2549                         var elem = this;
2550                         setTimeout(function() {
2551                                 jQuery.dequeue( elem, type );
2552                         }, time );
2553                 });
2554         },
2555         clearQueue: function( type ) {
2556                 return this.queue( type || "fx", [] );
2557         },
2558         // Get a promise resolved when queues of a certain type
2559         // are emptied (fx is the type by default)
2560         promise: function( type, object ) {
2561                 if ( typeof type !== "string" ) {
2562                         object = type;
2563                         type = undefined;
2564                 }
2565                 type = type || "fx";
2566                 var defer = jQuery.Deferred(),
2567                         elements = this,
2568                         i = elements.length,
2569                         count = 1,
2570                         deferDataKey = type + "defer",
2571                         queueDataKey = type + "queue",
2572                         markDataKey = type + "mark";
2573                 function resolve() {
2574                         if ( !( --count ) ) {
2575                                 defer.resolveWith( elements, [ elements ] );
2576                         }
2577                 }
2578                 while( i-- ) {
2579                         if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
2580                                         ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
2581                                                 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
2582                                         jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
2583                                 count++;
2584                                 tmp.done( resolve );
2585                         }
2586                 }
2587                 resolve();
2588                 return defer.promise();
2589         }
2590 });
2591
2592
2593
2594
2595 var rclass = /[\n\t\r]/g,
2596         rspace = /\s+/,
2597         rreturn = /\r/g,
2598         rtype = /^(?:button|input)$/i,
2599         rfocusable = /^(?:button|input|object|select|textarea)$/i,
2600         rclickable = /^a(?:rea)?$/i,
2601         rspecial = /^(?:data-|aria-)/,
2602         rinvalidChar = /\:/,
2603         formHook;
2604
2605 jQuery.fn.extend({
2606         attr: function( name, value ) {
2607                 return jQuery.access( this, name, value, true, jQuery.attr );
2608         },
2609
2610         removeAttr: function( name ) {
2611                 return this.each(function() {
2612                         jQuery.removeAttr( this, name );
2613                 });
2614         },
2615         
2616         prop: function( name, value ) {
2617                 return jQuery.access( this, name, value, true, jQuery.prop );
2618         },
2619         
2620         removeProp: function( name ) {
2621                 return this.each(function() {
2622                         // try/catch handles cases where IE balks (such as removing a property on window)
2623                         try {
2624                                 this[ name ] = undefined;
2625                                 delete this[ name ];
2626                         } catch( e ) {}
2627                 });
2628         },
2629
2630         addClass: function( value ) {
2631                 if ( jQuery.isFunction( value ) ) {
2632                         return this.each(function(i) {
2633                                 var self = jQuery(this);
2634                                 self.addClass( value.call(this, i, self.attr("class") || "") );
2635                         });
2636                 }
2637
2638                 if ( value && typeof value === "string" ) {
2639                         var classNames = (value || "").split( rspace );
2640
2641                         for ( var i = 0, l = this.length; i < l; i++ ) {
2642                                 var elem = this[i];
2643
2644                                 if ( elem.nodeType === 1 ) {
2645                                         if ( !elem.className ) {
2646                                                 elem.className = value;
2647
2648                                         } else {
2649                                                 var className = " " + elem.className + " ",
2650                                                         setClass = elem.className;
2651
2652                                                 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
2653                                                         if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
2654                                                                 setClass += " " + classNames[c];
2655                                                         }
2656                                                 }
2657                                                 elem.className = jQuery.trim( setClass );
2658                                         }
2659                                 }
2660                         }
2661                 }
2662
2663                 return this;
2664         },
2665
2666         removeClass: function( value ) {
2667                 if ( jQuery.isFunction(value) ) {
2668                         return this.each(function(i) {
2669                                 var self = jQuery(this);
2670                                 self.removeClass( value.call(this, i, self.attr("class")) );
2671                         });
2672                 }
2673
2674                 if ( (value && typeof value === "string") || value === undefined ) {
2675                         var classNames = (value || "").split( rspace );
2676
2677                         for ( var i = 0, l = this.length; i < l; i++ ) {
2678                                 var elem = this[i];
2679
2680                                 if ( elem.nodeType === 1 && elem.className ) {
2681                                         if ( value ) {
2682                                                 var className = (" " + elem.className + " ").replace(rclass, " ");
2683                                                 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
2684                                                         className = className.replace(" " + classNames[c] + " ", " ");
2685                                                 }
2686                                                 elem.className = jQuery.trim( className );
2687
2688                                         } else {
2689                                                 elem.className = "";
2690                                         }
2691                                 }
2692                         }
2693                 }
2694
2695                 return this;
2696         },
2697
2698         toggleClass: function( value, stateVal ) {
2699                 var type = typeof value,
2700                         isBool = typeof stateVal === "boolean";
2701
2702                 if ( jQuery.isFunction( value ) ) {
2703                         return this.each(function(i) {
2704                                 var self = jQuery(this);
2705                                 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
2706                         });
2707                 }
2708
2709                 return this.each(function() {
2710                         if ( type === "string" ) {
2711                                 // toggle individual class names
2712                                 var className,
2713                                         i = 0,
2714                                         self = jQuery( this ),
2715                                         state = stateVal,
2716                                         classNames = value.split( rspace );
2717
2718                                 while ( (className = classNames[ i++ ]) ) {
2719                                         // check each className given, space seperated list
2720                                         state = isBool ? state : !self.hasClass( className );
2721                                         self[ state ? "addClass" : "removeClass" ]( className );
2722                                 }
2723
2724                         } else if ( type === "undefined" || type === "boolean" ) {
2725                                 if ( this.className ) {
2726                                         // store className if set
2727                                         jQuery._data( this, "__className__", this.className );
2728                                 }
2729
2730                                 // toggle whole className
2731                                 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2732                         }
2733                 });
2734         },
2735
2736         hasClass: function( selector ) {
2737                 var className = " " + selector + " ";
2738                 for ( var i = 0, l = this.length; i < l; i++ ) {
2739                         if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2740                                 return true;
2741                         }
2742                 }
2743
2744                 return false;
2745         },
2746
2747         val: function( value ) {
2748                 var hooks, ret,
2749                         elem = this[0];
2750                 
2751                 if ( !arguments.length ) {
2752                         if ( elem ) {
2753                                 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2754
2755                                 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2756                                         return ret;
2757                                 }
2758
2759                                 return (elem.value || "").replace(rreturn, "");
2760                         }
2761
2762                         return undefined;
2763                 }
2764
2765                 var isFunction = jQuery.isFunction( value );
2766
2767                 return this.each(function( i ) {
2768                         var self = jQuery(this), val;
2769
2770                         if ( this.nodeType !== 1 ) {
2771                                 return;
2772                         }
2773
2774                         if ( isFunction ) {
2775                                 val = value.call( this, i, self.val() );
2776                         } else {
2777                                 val = value;
2778                         }
2779
2780                         // Treat null/undefined as ""; convert numbers to string
2781                         if ( val == null ) {
2782                                 val = "";
2783                         } else if ( typeof val === "number" ) {
2784                                 val += "";
2785                         } else if ( jQuery.isArray( val ) ) {
2786                                 val = jQuery.map(val, function ( value ) {
2787                                         return value == null ? "" : value + "";
2788                                 });
2789                         }
2790
2791                         hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2792
2793                         // If set returns undefined, fall back to normal setting
2794                         if ( !hooks || ("set" in hooks && hooks.set( this, val, "value" ) === undefined) ) {
2795                                 this.value = val;
2796                         }
2797                 });
2798         }
2799 });
2800
2801 jQuery.extend({
2802         valHooks: {
2803                 option: {
2804                         get: function( elem ) {
2805                                 // attributes.value is undefined in Blackberry 4.7 but
2806                                 // uses .value. See #6932
2807                                 var val = elem.attributes.value;
2808                                 return !val || val.specified ? elem.value : elem.text;
2809                         }
2810                 },
2811                 select: {
2812                         get: function( elem ) {
2813                                 var index = elem.selectedIndex,
2814                                         values = [],
2815                                         options = elem.options,
2816                                         one = elem.type === "select-one";
2817
2818                                 // Nothing was selected
2819                                 if ( index < 0 ) {
2820                                         return null;
2821                                 }
2822
2823                                 // Loop through all the selected options
2824                                 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2825                                         var option = options[ i ];
2826
2827                                         // Don't return options that are disabled or in a disabled optgroup
2828                                         if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2829                                                         (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2830
2831                                                 // Get the specific value for the option
2832                                                 value = jQuery( option ).val();
2833
2834                                                 // We don't need an array for one selects
2835                                                 if ( one ) {
2836                                                         return value;
2837                                                 }
2838
2839                                                 // Multi-Selects return an array
2840                                                 values.push( value );
2841                                         }
2842                                 }
2843
2844                                 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2845                                 if ( one && !values.length && options.length ) {
2846                                         return jQuery( options[ index ] ).val();
2847                                 }
2848
2849                                 return values;
2850                         },
2851
2852                         set: function( elem, value ) {
2853                                 var values = jQuery.makeArray( value );
2854
2855                                 jQuery(elem).find("option").each(function() {
2856                                         this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2857                                 });
2858
2859                                 if ( !values.length ) {
2860                                         elem.selectedIndex = -1;
2861                                 }
2862                                 return values;
2863                         }
2864                 }
2865         },
2866
2867         attrFn: {
2868                 val: true,
2869                 css: true,
2870                 html: true,
2871                 text: true,
2872                 data: true,
2873                 width: true,
2874                 height: true,
2875                 offset: true
2876         },
2877         
2878         attrFix: {
2879                 // Always normalize to ensure hook usage
2880                 tabindex: "tabIndex",
2881                 readonly: "readOnly"
2882         },
2883         
2884         attr: function( elem, name, value, pass ) {
2885                 var nType = elem.nodeType;
2886                 
2887                 // don't get/set attributes on text, comment and attribute nodes
2888                 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2889                         return undefined;
2890                 }
2891
2892                 if ( pass && name in jQuery.attrFn ) {
2893                         return jQuery( elem )[ name ]( value );
2894                 }
2895                 
2896                 var ret, hooks,
2897                         notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2898                 
2899                 // Normalize the name if needed
2900                 name = notxml && jQuery.attrFix[ name ] || name;
2901
2902                 // Get the appropriate hook, or the formHook
2903                 // if getSetAttribute is not supported and we have form objects in IE6/7
2904                 hooks = jQuery.attrHooks[ name ] ||
2905                         ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ?
2906                                 formHook :
2907                                 undefined );
2908
2909                 if ( value !== undefined ) {
2910
2911                         if ( value === null || (value === false && !rspecial.test( name )) ) {
2912                                 jQuery.removeAttr( elem, name );
2913                                 return undefined;
2914
2915                         } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2916                                 return ret;
2917
2918                         } else {
2919
2920                                 // Set boolean attributes to the same name
2921                                 if ( value === true && !rspecial.test( name ) ) {
2922                                         value = name;
2923                                 }
2924
2925                                 elem.setAttribute( name, "" + value );
2926                                 return value;
2927                         }
2928
2929                 } else {
2930
2931                         if ( hooks && "get" in hooks && notxml ) {
2932                                 return hooks.get( elem, name );
2933
2934                         } else {
2935
2936                                 ret = elem.getAttribute( name );
2937
2938                                 // Non-existent attributes return null, we normalize to undefined
2939                                 return ret === null ?
2940                                         undefined :
2941                                         ret;
2942                         }
2943                 }
2944         },
2945         
2946         removeAttr: function( elem, name ) {
2947                 if ( elem.nodeType === 1 ) {
2948                         name = jQuery.attrFix[ name ] || name;
2949                 
2950                         if ( jQuery.support.getSetAttribute ) {
2951                                 // Use removeAttribute in browsers that support it
2952                                 elem.removeAttribute( name );
2953                         } else {
2954                                 jQuery.attr( elem, name, "" );
2955                                 elem.removeAttributeNode( elem.getAttributeNode( name ) );
2956                         }
2957                 }
2958         },
2959
2960         attrHooks: {
2961                 type: {
2962                         set: function( elem, value ) {
2963                                 // We can't allow the type property to be changed (since it causes problems in IE)
2964                                 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2965                                         jQuery.error( "type property can't be changed" );
2966                                 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2967                                         // Setting the type on a radio button after the value resets the value in IE6-9
2968                                         // Reset value to it's default in case type is set after value
2969                                         // This is for element creation
2970                                         var val = elem.getAttribute("value");
2971                                         elem.setAttribute( "type", value );
2972                                         if ( val ) {
2973                                                 elem.value = val;
2974                                         }
2975                                         return value;
2976                                 }
2977                         }
2978                 },
2979                 tabIndex: {
2980                         get: function( elem ) {
2981                                 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2982                                 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2983                                 var attributeNode = elem.getAttributeNode("tabIndex");
2984
2985                                 return attributeNode && attributeNode.specified ?
2986                                         parseInt( attributeNode.value, 10 ) :
2987                                         rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2988                                                 0 :
2989                                                 undefined;
2990                         }
2991                 }
2992         },
2993         
2994         propFix: {},
2995         
2996         prop: function( elem, name, value ) {
2997                 var nType = elem.nodeType;
2998                 
2999                 // don't get/set properties on text, comment and attribute nodes
3000                 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
3001                         return undefined;
3002                 }
3003                 
3004                 var ret, hooks,
3005                         notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
3006                 
3007                 // Try to normalize/fix the name
3008                 name = notxml && jQuery.propFix[ name ] || name;
3009                 
3010                 hooks = jQuery.propHooks[ name ];
3011                 
3012                 if ( value !== undefined ) {
3013                         if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
3014                                 return ret;
3015                         
3016                         } else {
3017                                 return (elem[ name ] = value);
3018                         }
3019                 
3020                 } else {
3021                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
3022                                 return ret;
3023                                 
3024                         } else {
3025                                 return elem[ name ];
3026                         }
3027                 }
3028         },
3029         
3030         propHooks: {}
3031 });
3032
3033 // IE6/7 do not support getting/setting some attributes with get/setAttribute
3034 if ( !jQuery.support.getSetAttribute ) {
3035         jQuery.attrFix = jQuery.extend( jQuery.attrFix, {
3036                 "for": "htmlFor",
3037                 "class": "className",
3038                 maxlength: "maxLength",
3039                 cellspacing: "cellSpacing",
3040                 cellpadding: "cellPadding",
3041                 rowspan: "rowSpan",
3042                 colspan: "colSpan",
3043                 usemap: "useMap",
3044                 frameborder: "frameBorder"
3045         });
3046         
3047         // Use this for any attribute on a form in IE6/7
3048         formHook = jQuery.attrHooks.name = jQuery.attrHooks.value = jQuery.valHooks.button = {
3049                 get: function( elem, name ) {
3050                         var ret;
3051                         if ( name === "value" && !jQuery.nodeName( elem, "button" ) ) {
3052                                 return elem.getAttribute( name );
3053                         }
3054                         ret = elem.getAttributeNode( name );
3055                         // Return undefined if not specified instead of empty string
3056                         return ret && ret.specified ?
3057                                 ret.nodeValue :
3058                                 undefined;
3059                 },
3060                 set: function( elem, value, name ) {
3061                         // Check form objects in IE (multiple bugs related)
3062                         // Only use nodeValue if the attribute node exists on the form
3063                         var ret = elem.getAttributeNode( name );
3064                         if ( ret ) {
3065                                 ret.nodeValue = value;
3066                                 return value;
3067                         }
3068                 }
3069         };
3070
3071         // Set width and height to auto instead of 0 on empty string( Bug #8150 )
3072         // This is for removals
3073         jQuery.each([ "width", "height" ], function( i, name ) {
3074                 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
3075                         set: function( elem, value ) {
3076                                 if ( value === "" ) {
3077                                         elem.setAttribute( name, "auto" );
3078                                         return value;
3079                                 }
3080                         }
3081                 });
3082         });
3083 }
3084
3085
3086 // Some attributes require a special call on IE
3087 if ( !jQuery.support.hrefNormalized ) {
3088         jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
3089                 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
3090                         get: function( elem ) {
3091                                 var ret = elem.getAttribute( name, 2 );
3092                                 return ret === null ? undefined : ret;
3093                         }
3094                 });
3095         });
3096 }
3097
3098 if ( !jQuery.support.style ) {
3099         jQuery.attrHooks.style = {
3100                 get: function( elem ) {
3101                         // Return undefined in the case of empty string
3102                         // Normalize to lowercase since IE uppercases css property names
3103                         return elem.style.cssText.toLowerCase() || undefined;
3104                 },
3105                 set: function( elem, value ) {
3106                         return (elem.style.cssText = "" + value);
3107                 }
3108         };
3109 }
3110
3111 // Safari mis-reports the default selected property of an option
3112 // Accessing the parent's selectedIndex property fixes it
3113 if ( !jQuery.support.optSelected ) {
3114         jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
3115                 get: function( elem ) {
3116                         var parent = elem.parentNode;
3117
3118                         if ( parent ) {
3119                                 parent.selectedIndex;
3120
3121                                 // Make sure that it also works with optgroups, see #5701
3122                                 if ( parent.parentNode ) {
3123                                         parent.parentNode.selectedIndex;
3124                                 }
3125                         }
3126                 }
3127         });
3128 }
3129
3130 // Radios and checkboxes getter/setter
3131 if ( !jQuery.support.checkOn ) {
3132         jQuery.each([ "radio", "checkbox" ], function() {
3133                 jQuery.valHooks[ this ] = {
3134                         get: function( elem ) {
3135                                 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
3136                                 return elem.getAttribute("value") === null ? "on" : elem.value;
3137                         }
3138                 };
3139         });
3140 }
3141 jQuery.each([ "radio", "checkbox" ], function() {
3142         jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
3143                 set: function( elem, value ) {
3144                         if ( jQuery.isArray( value ) ) {
3145                                 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
3146                         }
3147                 }
3148         });
3149 });
3150
3151
3152
3153
3154 var hasOwn = Object.prototype.hasOwnProperty,
3155         rnamespaces = /\.(.*)$/,
3156         rformElems = /^(?:textarea|input|select)$/i,
3157         rperiod = /\./g,
3158         rspaces = / /g,
3159         rescape = /[^\w\s.|`]/g,
3160         fcleanup = function( nm ) {
3161                 return nm.replace(rescape, "\\$&");
3162         };
3163
3164 /*
3165  * A number of helper functions used for managing events.
3166  * Many of the ideas behind this code originated from
3167  * Dean Edwards' addEvent library.
3168  */
3169 jQuery.event = {
3170
3171         // Bind an event to an element
3172         // Original by Dean Edwards
3173         add: function( elem, types, handler, data ) {
3174                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
3175                         return;
3176                 }
3177
3178                 if ( handler === false ) {
3179                         handler = returnFalse;
3180                 } else if ( !handler ) {
3181                         // Fixes bug #7229. Fix recommended by jdalton
3182                         return;
3183                 }
3184
3185                 var handleObjIn, handleObj;
3186
3187                 if ( handler.handler ) {
3188                         handleObjIn = handler;
3189                         handler = handleObjIn.handler;
3190                 }
3191
3192                 // Make sure that the function being executed has a unique ID
3193                 if ( !handler.guid ) {
3194                         handler.guid = jQuery.guid++;
3195                 }
3196
3197                 // Init the element's event structure
3198                 var elemData = jQuery._data( elem );
3199
3200                 // If no elemData is found then we must be trying to bind to one of the
3201                 // banned noData elements
3202                 if ( !elemData ) {
3203                         return;
3204                 }
3205
3206                 var events = elemData.events,
3207                         eventHandle = elemData.handle;
3208
3209                 if ( !events ) {
3210                         elemData.events = events = {};
3211                 }
3212
3213                 if ( !eventHandle ) {
3214                         elemData.handle = eventHandle = function( e ) {
3215                                 // Discard the second event of a jQuery.event.trigger() and
3216                                 // when an event is called after a page has unloaded
3217                                 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
3218                                         jQuery.event.handle.apply( eventHandle.elem, arguments ) :
3219                                         undefined;
3220                         };
3221                 }
3222
3223                 // Add elem as a property of the handle function
3224                 // This is to prevent a memory leak with non-native events in IE.
3225                 eventHandle.elem = elem;
3226
3227                 // Handle multiple events separated by a space
3228                 // jQuery(...).bind("mouseover mouseout", fn);
3229                 types = types.split(" ");
3230
3231                 var type, i = 0, namespaces;
3232
3233                 while ( (type = types[ i++ ]) ) {
3234                         handleObj = handleObjIn ?
3235                                 jQuery.extend({}, handleObjIn) :
3236                                 { handler: handler, data: data };
3237
3238                         // Namespaced event handlers
3239                         if ( type.indexOf(".") > -1 ) {
3240                                 namespaces = type.split(".");
3241                                 type = namespaces.shift();
3242                                 handleObj.namespace = namespaces.slice(0).sort().join(".");
3243
3244                         } else {
3245                                 namespaces = [];
3246                                 handleObj.namespace = "";
3247                         }
3248
3249                         handleObj.type = type;
3250                         if ( !handleObj.guid ) {
3251                                 handleObj.guid = handler.guid;
3252                         }
3253
3254                         // Get the current list of functions bound to this event
3255                         var handlers = events[ type ],
3256                                 special = jQuery.event.special[ type ] || {};
3257
3258                         // Init the event handler queue
3259                         if ( !handlers ) {
3260                                 handlers = events[ type ] = [];
3261
3262                                 // Check for a special event handler
3263                                 // Only use addEventListener/attachEvent if the special
3264                                 // events handler returns false
3265                                 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
3266                                         // Bind the global event handler to the element
3267                                         if ( elem.addEventListener ) {
3268                                                 elem.addEventListener( type, eventHandle, false );
3269
3270                                         } else if ( elem.attachEvent ) {
3271                                                 elem.attachEvent( "on" + type, eventHandle );
3272                                         }
3273                                 }
3274                         }
3275
3276                         if ( special.add ) {
3277                                 special.add.call( elem, handleObj );
3278
3279                                 if ( !handleObj.handler.guid ) {
3280                                         handleObj.handler.guid = handler.guid;
3281                                 }
3282                         }
3283
3284                         // Add the function to the element's handler list
3285                         handlers.push( handleObj );
3286
3287                         // Keep track of which events have been used, for event optimization
3288                         jQuery.event.global[ type ] = true;
3289                 }
3290
3291                 // Nullify elem to prevent memory leaks in IE
3292                 elem = null;
3293         },
3294
3295         global: {},
3296
3297         // Detach an event or set of events from an element
3298         remove: function( elem, types, handler, pos ) {
3299                 // don't do events on text and comment nodes
3300                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
3301                         return;
3302                 }
3303
3304                 if ( handler === false ) {
3305                         handler = returnFalse;
3306                 }
3307
3308                 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
3309                         elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
3310                         events = elemData && elemData.events;
3311
3312                 if ( !elemData || !events ) {
3313                         return;
3314                 }
3315
3316                 // types is actually an event object here
3317                 if ( types && types.type ) {
3318                         handler = types.handler;
3319                         types = types.type;
3320                 }
3321
3322                 // Unbind all events for the element
3323                 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
3324                         types = types || "";
3325
3326                         for ( type in events ) {
3327                                 jQuery.event.remove( elem, type + types );
3328                         }
3329
3330                         return;
3331                 }
3332
3333                 // Handle multiple events separated by a space
3334                 // jQuery(...).unbind("mouseover mouseout", fn);
3335                 types = types.split(" ");
3336
3337                 while ( (type = types[ i++ ]) ) {
3338                         origType = type;
3339                         handleObj = null;
3340                         all = type.indexOf(".") < 0;
3341                         namespaces = [];
3342
3343                         if ( !all ) {
3344                                 // Namespaced event handlers
3345                                 namespaces = type.split(".");
3346                                 type = namespaces.shift();
3347
3348                                 namespace = new RegExp("(^|\\.)" +
3349                                         jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
3350                         }
3351
3352                         eventType = events[ type ];
3353
3354                         if ( !eventType ) {
3355                                 continue;
3356                         }
3357
3358                         if ( !handler ) {
3359                                 for ( j = 0; j < eventType.length; j++ ) {
3360                                         handleObj = eventType[ j ];
3361
3362                                         if ( all || namespace.test( handleObj.namespace ) ) {
3363                                                 jQuery.event.remove( elem, origType, handleObj.handler, j );
3364                                                 eventType.splice( j--, 1 );
3365                                         }
3366                                 }
3367
3368                                 continue;
3369                         }
3370
3371                         special = jQuery.event.special[ type ] || {};
3372
3373                         for ( j = pos || 0; j < eventType.length; j++ ) {
3374                                 handleObj = eventType[ j ];
3375
3376                                 if ( handler.guid === handleObj.guid ) {
3377                                         // remove the given handler for the given type
3378                                         if ( all || namespace.test( handleObj.namespace ) ) {
3379                                                 if ( pos == null ) {
3380                                                         eventType.splice( j--, 1 );
3381                                                 }
3382
3383                                                 if ( special.remove ) {
3384                                                         special.remove.call( elem, handleObj );
3385                                                 }
3386                                         }
3387
3388                                         if ( pos != null ) {
3389                                                 break;
3390                                         }
3391                                 }
3392                         }
3393
3394                         // remove generic event handler if no more handlers exist
3395                         if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
3396                                 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
3397                                         jQuery.removeEvent( elem, type, elemData.handle );
3398                                 }
3399
3400                                 ret = null;
3401                                 delete events[ type ];
3402                         }
3403                 }
3404
3405                 // Remove the expando if it's no longer used
3406                 if ( jQuery.isEmptyObject( events ) ) {
3407                         var handle = elemData.handle;
3408                         if ( handle ) {
3409                                 handle.elem = null;
3410                         }
3411
3412                         delete elemData.events;
3413                         delete elemData.handle;
3414
3415                         if ( jQuery.isEmptyObject( elemData ) ) {
3416                                 jQuery.removeData( elem, undefined, true );
3417                         }
3418                 }
3419         },
3420         
3421         // Events that are safe to short-circuit if no handlers are attached.
3422         // Native DOM events should not be added, they may have inline handlers.
3423         customEvent: {
3424                 "getData": true,
3425                 "setData": true,
3426                 "changeData": true
3427         },
3428
3429         trigger: function( event, data, elem, onlyHandlers ) {
3430                 // Event object or event type
3431                 var type = event.type || event,
3432                         namespaces = [],
3433                         exclusive;
3434
3435                 if ( type.indexOf("!") >= 0 ) {
3436                         // Exclusive events trigger only for the exact event (no namespaces)
3437                         type = type.slice(0, -1);
3438                         exclusive = true;
3439                 }
3440
3441                 if ( type.indexOf(".") >= 0 ) {
3442                         // Namespaced trigger; create a regexp to match event type in handle()
3443                         namespaces = type.split(".");
3444                         type = namespaces.shift();
3445                         namespaces.sort();
3446                 }
3447
3448                 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
3449                         // No jQuery handlers for this event type, and it can't have inline handlers
3450                         return;
3451                 }
3452
3453                 // Caller can pass in an Event, Object, or just an event type string
3454                 event = typeof event === "object" ?
3455                         // jQuery.Event object
3456                         event[ jQuery.expando ] ? event :
3457                         // Object literal
3458                         new jQuery.Event( type, event ) :
3459                         // Just the event type (string)
3460                         new jQuery.Event( type );
3461
3462                 event.type = type;
3463                 event.exclusive = exclusive;
3464                 event.namespace = namespaces.join(".");
3465                 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
3466                 
3467                 // triggerHandler() and global events don't bubble or run the default action
3468                 if ( onlyHandlers || !elem ) {
3469                         event.preventDefault();
3470                         event.stopPropagation();
3471                 }
3472
3473                 // Handle a global trigger
3474                 if ( !elem ) {
3475                         // TODO: Stop taunting the data cache; remove global events and always attach to document
3476                         jQuery.each( jQuery.cache, function() {
3477                                 // internalKey variable is just used to make it easier to find
3478                                 // and potentially change this stuff later; currently it just
3479                                 // points to jQuery.expando
3480                                 var internalKey = jQuery.expando,
3481                                         internalCache = this[ internalKey ];
3482                                 if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
3483                                         jQuery.event.trigger( event, data, internalCache.handle.elem );
3484                                 }
3485                         });
3486                         return;
3487                 }
3488
3489                 // Don't do events on text and comment nodes
3490                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
3491                         return;
3492                 }
3493
3494                 // Clean up the event in case it is being reused
3495                 event.result = undefined;
3496                 event.target = elem;
3497
3498                 // Clone any incoming data and prepend the event, creating the handler arg list
3499                 data = data ? jQuery.makeArray( data ) : [];
3500                 data.unshift( event );
3501
3502                 var cur = elem,
3503                         // IE doesn't like method names with a colon (#3533, #8272)
3504                         ontype = type.indexOf(":") < 0 ? "on" + type : "";
3505
3506                 // Fire event on the current element, then bubble up the DOM tree
3507                 do {
3508                         var handle = jQuery._data( cur, "handle" );
3509
3510                         event.currentTarget = cur;
3511                         if ( handle ) {
3512                                 handle.apply( cur, data );
3513                         }
3514
3515                         // Trigger an inline bound script
3516                         if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
3517                                 event.result = false;
3518                                 event.preventDefault();
3519                         }
3520
3521                         // Bubble up to document, then to window
3522                         cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
3523                 } while ( cur && !event.isPropagationStopped() );
3524
3525                 // If nobody prevented the default action, do it now
3526                 if ( !event.isDefaultPrevented() ) {
3527                         var old,
3528                                 special = jQuery.event.special[ type ] || {};
3529
3530                         if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
3531                                 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
3532
3533                                 // Call a native DOM method on the target with the same name name as the event.
3534                                 // Can't use an .isFunction)() check here because IE6/7 fails that test.
3535                                 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
3536                                 try {
3537                                         if ( ontype && elem[ type ] ) {
3538                                                 // Don't re-trigger an onFOO event when we call its FOO() method
3539                                                 old = elem[ ontype ];
3540
3541                                                 if ( old ) {
3542                                                         elem[ ontype ] = null;
3543                                                 }
3544
3545                                                 jQuery.event.triggered = type;
3546                                                 elem[ type ]();
3547                                         }
3548                                 } catch ( ieError ) {}
3549
3550                                 if ( old ) {
3551                                         elem[ ontype ] = old;
3552                                 }
3553
3554                                 jQuery.event.triggered = undefined;
3555                         }
3556                 }
3557                 
3558                 return event.result;
3559         },
3560
3561         handle: function( event ) {
3562                 event = jQuery.event.fix( event || window.event );
3563                 // Snapshot the handlers list since a called handler may add/remove events.
3564                 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
3565                         run_all = !event.exclusive && !event.namespace,
3566                         args = Array.prototype.slice.call( arguments, 0 );
3567
3568                 // Use the fix-ed Event rather than the (read-only) native event
3569                 args[0] = event;
3570                 event.currentTarget = this;
3571
3572                 for ( var j = 0, l = handlers.length; j < l; j++ ) {
3573                         var handleObj = handlers[ j ];
3574
3575                         // Triggered event must 1) be non-exclusive and have no namespace, or
3576                         // 2) have namespace(s) a subset or equal to those in the bound event.
3577                         if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
3578                                 // Pass in a reference to the handler function itself
3579                                 // So that we can later remove it
3580                                 event.handler = handleObj.handler;
3581                                 event.data = handleObj.data;
3582                                 event.handleObj = handleObj;
3583
3584                                 var ret = handleObj.handler.apply( this, args );
3585
3586                                 if ( ret !== undefined ) {
3587                                         event.result = ret;
3588                                         if ( ret === false ) {
3589                                                 event.preventDefault();
3590                                                 event.stopPropagation();
3591                                         }
3592                                 }
3593
3594                                 if ( event.isImmediatePropagationStopped() ) {
3595                                         break;
3596                                 }
3597                         }
3598                 }
3599                 return event.result;
3600         },
3601
3602         props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
3603
3604         fix: function( event ) {
3605                 if ( event[ jQuery.expando ] ) {
3606                         return event;
3607                 }
3608
3609                 // store a copy of the original event object
3610                 // and "clone" to set read-only properties
3611                 var originalEvent = event;
3612                 event = jQuery.Event( originalEvent );
3613
3614                 for ( var i = this.props.length, prop; i; ) {
3615                         prop = this.props[ --i ];
3616                         event[ prop ] = originalEvent[ prop ];
3617                 }
3618
3619                 // Fix target property, if necessary
3620                 if ( !event.target ) {
3621                         // Fixes #1925 where srcElement might not be defined either
3622                         event.target = event.srcElement || document;
3623                 }
3624
3625                 // check if target is a textnode (safari)
3626                 if ( event.target.nodeType === 3 ) {
3627                         event.target = event.target.parentNode;
3628                 }
3629
3630                 // Add relatedTarget, if necessary
3631                 if ( !event.relatedTarget && event.fromElement ) {
3632                         event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
3633                 }
3634
3635                 // Calculate pageX/Y if missing and clientX/Y available
3636                 if ( event.pageX == null && event.clientX != null ) {
3637                         var eventDocument = event.target.ownerDocument || document,
3638                                 doc = eventDocument.documentElement,
3639                                 body = eventDocument.body;
3640
3641                         event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
3642                         event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
3643                 }
3644
3645                 // Add which for key events
3646                 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
3647                         event.which = event.charCode != null ? event.charCode : event.keyCode;
3648                 }
3649
3650                 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
3651                 if ( !event.metaKey && event.ctrlKey ) {
3652                         event.metaKey = event.ctrlKey;
3653                 }
3654
3655                 // Add which for click: 1 === left; 2 === middle; 3 === right
3656                 // Note: button is not normalized, so don't use it
3657                 if ( !event.which && event.button !== undefined ) {
3658                         event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3659                 }
3660
3661                 return event;
3662         },
3663
3664         // Deprecated, use jQuery.guid instead
3665         guid: 1E8,
3666
3667         // Deprecated, use jQuery.proxy instead
3668         proxy: jQuery.proxy,
3669
3670         special: {
3671                 ready: {
3672                         // Make sure the ready event is setup
3673                         setup: jQuery.bindReady,
3674                         teardown: jQuery.noop
3675                 },
3676
3677                 live: {
3678                         add: function( handleObj ) {
3679                                 jQuery.event.add( this,
3680                                         liveConvert( handleObj.origType, handleObj.selector ),
3681                                         jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3682                         },
3683
3684                         remove: function( handleObj ) {
3685                                 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3686                         }
3687                 },
3688
3689                 beforeunload: {
3690                         setup: function( data, namespaces, eventHandle ) {
3691                                 // We only want to do this special case on windows
3692                                 if ( jQuery.isWindow( this ) ) {
3693                                         this.onbeforeunload = eventHandle;
3694                                 }
3695                         },
3696
3697                         teardown: function( namespaces, eventHandle ) {
3698                                 if ( this.onbeforeunload === eventHandle ) {
3699                                         this.onbeforeunload = null;
3700                                 }
3701                         }
3702                 }
3703         }
3704 };
3705
3706 jQuery.removeEvent = document.removeEventListener ?
3707         function( elem, type, handle ) {
3708                 if ( elem.removeEventListener ) {
3709                         elem.removeEventListener( type, handle, false );
3710                 }
3711         } :
3712         function( elem, type, handle ) {
3713                 if ( elem.detachEvent ) {
3714                         elem.detachEvent( "on" + type, handle );
3715                 }
3716         };
3717
3718 jQuery.Event = function( src, props ) {
3719         // Allow instantiation without the 'new' keyword
3720         if ( !this.preventDefault ) {
3721                 return new jQuery.Event( src, props );
3722         }
3723
3724         // Event object
3725         if ( src && src.type ) {
3726                 this.originalEvent = src;
3727                 this.type = src.type;
3728
3729                 // Events bubbling up the document may have been marked as prevented
3730                 // by a handler lower down the tree; reflect the correct value.
3731                 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3732                         src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3733
3734         // Event type
3735         } else {
3736                 this.type = src;
3737         }
3738
3739         // Put explicitly provided properties onto the event object
3740         if ( props ) {
3741                 jQuery.extend( this, props );
3742         }
3743
3744         // timeStamp is buggy for some events on Firefox(#3843)
3745         // So we won't rely on the native value
3746         this.timeStamp = jQuery.now();
3747
3748         // Mark it as fixed
3749         this[ jQuery.expando ] = true;
3750 };
3751
3752 function returnFalse() {
3753         return false;
3754 }
3755 function returnTrue() {
3756         return true;
3757 }
3758
3759 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3760 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3761 jQuery.Event.prototype = {
3762         preventDefault: function() {
3763                 this.isDefaultPrevented = returnTrue;
3764
3765                 var e = this.originalEvent;
3766                 if ( !e ) {
3767                         return;
3768                 }
3769
3770                 // if preventDefault exists run it on the original event
3771                 if ( e.preventDefault ) {
3772                         e.preventDefault();
3773
3774                 // otherwise set the returnValue property of the original event to false (IE)
3775                 } else {
3776                         e.returnValue = false;
3777                 }
3778         },
3779         stopPropagation: function() {
3780                 this.isPropagationStopped = returnTrue;
3781
3782                 var e = this.originalEvent;
3783                 if ( !e ) {
3784                         return;
3785                 }
3786                 // if stopPropagation exists run it on the original event
3787                 if ( e.stopPropagation ) {
3788                         e.stopPropagation();
3789                 }
3790                 // otherwise set the cancelBubble property of the original event to true (IE)
3791                 e.cancelBubble = true;
3792         },
3793         stopImmediatePropagation: function() {
3794                 this.isImmediatePropagationStopped = returnTrue;
3795                 this.stopPropagation();
3796         },
3797         isDefaultPrevented: returnFalse,
3798         isPropagationStopped: returnFalse,
3799         isImmediatePropagationStopped: returnFalse
3800 };
3801
3802 // Checks if an event happened on an element within another element
3803 // Used in jQuery.event.special.mouseenter and mouseleave handlers
3804 var withinElement = function( event ) {
3805         // Check if mouse(over|out) are still within the same parent element
3806         var parent = event.relatedTarget;
3807
3808         // Firefox sometimes assigns relatedTarget a XUL element
3809         // which we cannot access the parentNode property of
3810         try {
3811
3812                 // Chrome does something similar, the parentNode property
3813                 // can be accessed but is null.
3814                 if ( parent && parent !== document && !parent.parentNode ) {
3815                         return;
3816                 }
3817                 // Traverse up the tree
3818                 while ( parent && parent !== this ) {
3819                         parent = parent.parentNode;
3820                 }
3821
3822                 if ( parent !== this ) {
3823                         // set the correct event type
3824                         event.type = event.data;
3825
3826                         // handle event if we actually just moused on to a non sub-element
3827                         jQuery.event.handle.apply( this, arguments );
3828                 }
3829
3830         // assuming we've left the element since we most likely mousedover a xul element
3831         } catch(e) { }
3832 },
3833
3834 // In case of event delegation, we only need to rename the event.type,
3835 // liveHandler will take care of the rest.
3836 delegate = function( event ) {
3837         event.type = event.data;
3838         jQuery.event.handle.apply( this, arguments );
3839 };
3840
3841 // Create mouseenter and mouseleave events
3842 jQuery.each({
3843         mouseenter: "mouseover",
3844         mouseleave: "mouseout"
3845 }, function( orig, fix ) {
3846         jQuery.event.special[ orig ] = {
3847                 setup: function( data ) {
3848                         jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3849                 },
3850                 teardown: function( data ) {
3851                         jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3852                 }
3853         };
3854 });
3855
3856 // submit delegation
3857 if ( !jQuery.support.submitBubbles ) {
3858
3859         jQuery.event.special.submit = {
3860                 setup: function( data, namespaces ) {
3861                         if ( !jQuery.nodeName( this, "form" ) ) {
3862                                 jQuery.event.add(this, "click.specialSubmit", function( e ) {
3863                                         var elem = e.target,
3864                                                 type = elem.type;
3865
3866                                         if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3867                                                 trigger( "submit", this, arguments );
3868                                         }
3869                                 });
3870
3871                                 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3872                                         var elem = e.target,
3873                                                 type = elem.type;
3874
3875                                         if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3876                                                 trigger( "submit", this, arguments );
3877                                         }
3878                                 });
3879
3880                         } else {
3881                                 return false;
3882                         }
3883                 },
3884
3885                 teardown: function( namespaces ) {
3886                         jQuery.event.remove( this, ".specialSubmit" );
3887                 }
3888         };
3889
3890 }
3891
3892 // change delegation, happens here so we have bind.
3893 if ( !jQuery.support.changeBubbles ) {
3894
3895         var changeFilters,
3896
3897         getVal = function( elem ) {
3898                 var type = elem.type, val = elem.value;
3899
3900                 if ( type === "radio" || type === "checkbox" ) {
3901                         val = elem.checked;
3902
3903                 } else if ( type === "select-multiple" ) {
3904                         val = elem.selectedIndex > -1 ?
3905                                 jQuery.map( elem.options, function( elem ) {
3906                                         return elem.selected;
3907                                 }).join("-") :
3908                                 "";
3909
3910                 } else if ( jQuery.nodeName( elem, "select" ) ) {
3911                         val = elem.selectedIndex;
3912                 }
3913
3914                 return val;
3915         },
3916
3917         testChange = function testChange( e ) {
3918                 var elem = e.target, data, val;
3919
3920                 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3921                         return;
3922                 }
3923
3924                 data = jQuery._data( elem, "_change_data" );
3925                 val = getVal(elem);
3926
3927                 // the current data will be also retrieved by beforeactivate
3928                 if ( e.type !== "focusout" || elem.type !== "radio" ) {
3929                         jQuery._data( elem, "_change_data", val );
3930                 }
3931
3932                 if ( data === undefined || val === data ) {
3933                         return;
3934                 }
3935
3936                 if ( data != null || val ) {
3937                         e.type = "change";
3938                         e.liveFired = undefined;
3939                         jQuery.event.trigger( e, arguments[1], elem );
3940                 }
3941         };
3942
3943         jQuery.event.special.change = {
3944                 filters: {
3945                         focusout: testChange,
3946
3947                         beforedeactivate: testChange,
3948
3949                         click: function( e ) {
3950                                 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3951
3952                                 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3953                                         testChange.call( this, e );
3954                                 }
3955                         },
3956
3957                         // Change has to be called before submit
3958                         // Keydown will be called before keypress, which is used in submit-event delegation
3959                         keydown: function( e ) {
3960                                 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3961
3962                                 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3963                                         (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3964                                         type === "select-multiple" ) {
3965                                         testChange.call( this, e );
3966                                 }
3967                         },
3968
3969                         // Beforeactivate happens also before the previous element is blurred
3970                         // with this event you can't trigger a change event, but you can store
3971                         // information
3972                         beforeactivate: function( e ) {
3973                                 var elem = e.target;
3974                                 jQuery._data( elem, "_change_data", getVal(elem) );
3975                         }
3976                 },
3977
3978                 setup: function( data, namespaces ) {
3979                         if ( this.type === "file" ) {
3980                                 return false;
3981                         }
3982
3983                         for ( var type in changeFilters ) {
3984                                 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3985                         }
3986
3987                         return rformElems.test( this.nodeName );
3988                 },
3989
3990                 teardown: function( namespaces ) {
3991                         jQuery.event.remove( this, ".specialChange" );
3992
3993                         return rformElems.test( this.nodeName );
3994                 }
3995         };
3996
3997         changeFilters = jQuery.event.special.change.filters;
3998
3999         // Handle when the input is .focus()'d
4000         changeFilters.focus = changeFilters.beforeactivate;
4001 }
4002
4003 function trigger( type, elem, args ) {
4004         // Piggyback on a donor event to simulate a different one.
4005         // Fake originalEvent to avoid donor's stopPropagation, but if the
4006         // simulated event prevents default then we do the same on the donor.
4007         // Don't pass args or remember liveFired; they apply to the donor event.
4008         var event = jQuery.extend( {}, args[ 0 ] );
4009         event.type = type;
4010         event.originalEvent = {};
4011         event.liveFired = undefined;
4012         jQuery.event.handle.call( elem, event );
4013         if ( event.isDefaultPrevented() ) {
4014                 args[ 0 ].preventDefault();
4015         }
4016 }
4017
4018 // Create "bubbling" focus and blur events
4019 if ( !jQuery.support.focusinBubbles ) {
4020         jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
4021
4022                 // Attach a single capturing handler while someone wants focusin/focusout
4023                 var attaches = 0;
4024
4025                 jQuery.event.special[ fix ] = {
4026                         setup: function() {
4027                                 if ( attaches++ === 0 ) {
4028                                         document.addEventListener( orig, handler, true );
4029                                 }
4030                         },
4031                         teardown: function() {
4032                                 if ( --attaches === 0 ) {
4033                                         document.removeEventListener( orig, handler, true );
4034                                 }
4035                         }
4036                 };
4037
4038                 function handler( donor ) {
4039                         // Donor event is always a native one; fix it and switch its type.
4040                         // Let focusin/out handler cancel the donor focus/blur event.
4041                         var e = jQuery.event.fix( donor );
4042                         e.type = fix;
4043                         e.originalEvent = {};
4044                         jQuery.event.trigger( e, null, e.target );
4045                         if ( e.isDefaultPrevented() ) {
4046                                 donor.preventDefault();
4047                         }
4048                 }
4049         });
4050 }
4051
4052 jQuery.each(["bind", "one"], function( i, name ) {
4053         jQuery.fn[ name ] = function( type, data, fn ) {
4054                 var handler;
4055
4056                 // Handle object literals
4057                 if ( typeof type === "object" ) {
4058                         for ( var key in type ) {
4059                                 this[ name ](key, data, type[key], fn);
4060                         }
4061                         return this;
4062                 }
4063
4064                 if ( arguments.length === 2 || data === false ) {
4065                         fn = data;
4066                         data = undefined;
4067                 }
4068
4069                 if ( name === "one" ) {
4070                         handler = function( event ) {
4071                                 jQuery( this ).unbind( event, handler );
4072                                 return fn.apply( this, arguments );
4073                         };
4074                         handler.guid = fn.guid || jQuery.guid++;
4075                 } else {
4076                         handler = fn;
4077                 }
4078
4079                 if ( type === "unload" && name !== "one" ) {
4080                         this.one( type, data, fn );
4081
4082                 } else {
4083                         for ( var i = 0, l = this.length; i < l; i++ ) {
4084                                 jQuery.event.add( this[i], type, handler, data );
4085                         }
4086                 }
4087
4088                 return this;
4089         };
4090 });
4091
4092 jQuery.fn.extend({
4093         unbind: function( type, fn ) {
4094                 // Handle object literals
4095                 if ( typeof type === "object" && !type.preventDefault ) {
4096                         for ( var key in type ) {
4097                                 this.unbind(key, type[key]);
4098                         }
4099
4100                 } else {
4101                         for ( var i = 0, l = this.length; i < l; i++ ) {
4102                                 jQuery.event.remove( this[i], type, fn );
4103                         }
4104                 }
4105
4106                 return this;
4107         },
4108
4109         delegate: function( selector, types, data, fn ) {
4110                 return this.live( types, data, fn, selector );
4111         },
4112
4113         undelegate: function( selector, types, fn ) {
4114                 if ( arguments.length === 0 ) {
4115                         return this.unbind( "live" );
4116
4117                 } else {
4118                         return this.die( types, null, fn, selector );
4119                 }
4120         },
4121
4122         trigger: function( type, data ) {
4123                 return this.each(function() {
4124                         jQuery.event.trigger( type, data, this );
4125                 });
4126         },
4127
4128         triggerHandler: function( type, data ) {
4129                 if ( this[0] ) {
4130                         return jQuery.event.trigger( type, data, this[0], true );
4131                 }
4132         },
4133
4134         toggle: function( fn ) {
4135                 // Save reference to arguments for access in closure
4136                 var args = arguments,
4137                         guid = fn.guid || jQuery.guid++,
4138                         i = 0,
4139                         toggler = function( event ) {
4140                                 // Figure out which function to execute
4141                                 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
4142                                 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
4143
4144                                 // Make sure that clicks stop
4145                                 event.preventDefault();
4146
4147                                 // and execute the function
4148                                 return args[ lastToggle ].apply( this, arguments ) || false;
4149                         };
4150
4151                 // link all the functions, so any of them can unbind this click handler
4152                 toggler.guid = guid;
4153                 while ( i < args.length ) {
4154                         args[ i++ ].guid = guid;
4155                 }
4156
4157                 return this.click( toggler );
4158         },
4159
4160         hover: function( fnOver, fnOut ) {
4161                 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
4162         }
4163 });
4164
4165 var liveMap = {
4166         focus: "focusin",
4167         blur: "focusout",
4168         mouseenter: "mouseover",
4169         mouseleave: "mouseout"
4170 };
4171
4172 jQuery.each(["live", "die"], function( i, name ) {
4173         jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
4174                 var type, i = 0, match, namespaces, preType,
4175                         selector = origSelector || this.selector,
4176                         context = origSelector ? this : jQuery( this.context );
4177
4178                 if ( typeof types === "object" && !types.preventDefault ) {
4179                         for ( var key in types ) {
4180                                 context[ name ]( key, data, types[key], selector );
4181                         }
4182
4183                         return this;
4184                 }
4185
4186                 if ( name === "die" && !types &&
4187                                         origSelector && origSelector.charAt(0) === "." ) {
4188
4189                         context.unbind( origSelector );
4190
4191                         return this;
4192                 }
4193
4194                 if ( data === false || jQuery.isFunction( data ) ) {
4195                         fn = data || returnFalse;
4196                         data = undefined;
4197                 }
4198
4199                 types = (types || "").split(" ");
4200
4201                 while ( (type = types[ i++ ]) != null ) {
4202                         match = rnamespaces.exec( type );
4203                         namespaces = "";
4204
4205                         if ( match )  {
4206                                 namespaces = match[0];
4207                                 type = type.replace( rnamespaces, "" );
4208                         }
4209
4210                         if ( type === "hover" ) {
4211                                 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
4212                                 continue;
4213                         }
4214
4215                         preType = type;
4216
4217                         if ( liveMap[ type ] ) {
4218                                 types.push( liveMap[ type ] + namespaces );
4219                                 type = type + namespaces;
4220
4221                         } else {
4222                                 type = (liveMap[ type ] || type) + namespaces;
4223                         }
4224
4225                         if ( name === "live" ) {
4226                                 // bind live handler
4227                                 for ( var j = 0, l = context.length; j < l; j++ ) {
4228                                         jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
4229                                                 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
4230                                 }
4231
4232                         } else {
4233                                 // unbind live handler
4234                                 context.unbind( "live." + liveConvert( type, selector ), fn );
4235                         }
4236                 }
4237
4238                 return this;
4239         };
4240 });
4241
4242 function liveHandler( event ) {
4243         var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
4244                 elems = [],
4245                 selectors = [],
4246                 events = jQuery._data( this, "events" );
4247
4248         // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
4249         if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
4250                 return;
4251         }
4252
4253         if ( event.namespace ) {
4254                 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
4255         }
4256
4257         event.liveFired = this;
4258
4259         var live = events.live.slice(0);
4260
4261         for ( j = 0; j < live.length; j++ ) {
4262                 handleObj = live[j];
4263
4264                 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
4265                         selectors.push( handleObj.selector );
4266
4267                 } else {
4268                         live.splice( j--, 1 );
4269                 }
4270         }
4271
4272         match = jQuery( event.target ).closest( selectors, event.currentTarget );
4273
4274         for ( i = 0, l = match.length; i < l; i++ ) {
4275                 close = match[i];
4276
4277                 for ( j = 0; j < live.length; j++ ) {
4278                         handleObj = live[j];
4279
4280                         if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
4281                                 elem = close.elem;
4282                                 related = null;
4283
4284                                 // Those two events require additional checking
4285                                 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
4286                                         event.type = handleObj.preType;
4287                                         related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
4288
4289                                         // Make sure not to accidentally match a child element with the same selector
4290                                         if ( related && jQuery.contains( elem, related ) ) {
4291                                                 related = elem;
4292                                         }
4293                                 }
4294
4295                                 if ( !related || related !== elem ) {
4296                                         elems.push({ elem: elem, handleObj: handleObj, level: close.level });
4297                                 }
4298                         }
4299                 }
4300         }
4301
4302         for ( i = 0, l = elems.length; i < l; i++ ) {
4303                 match = elems[i];
4304
4305                 if ( maxLevel && match.level > maxLevel ) {
4306                         break;
4307                 }
4308
4309                 event.currentTarget = match.elem;
4310                 event.data = match.handleObj.data;
4311                 event.handleObj = match.handleObj;
4312
4313                 ret = match.handleObj.origHandler.apply( match.elem, arguments );
4314
4315                 if ( ret === false || event.isPropagationStopped() ) {
4316                         maxLevel = match.level;
4317
4318                         if ( ret === false ) {
4319                                 stop = false;
4320                         }
4321                         if ( event.isImmediatePropagationStopped() ) {
4322                                 break;
4323                         }
4324                 }
4325         }
4326
4327         return stop;
4328 }
4329
4330 function liveConvert( type, selector ) {
4331         return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
4332 }
4333
4334 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
4335         "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
4336         "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
4337
4338         // Handle event binding
4339         jQuery.fn[ name ] = function( data, fn ) {
4340                 if ( fn == null ) {
4341                         fn = data;
4342                         data = null;
4343                 }
4344
4345                 return arguments.length > 0 ?
4346                         this.bind( name, data, fn ) :
4347                         this.trigger( name );
4348         };
4349
4350         if ( jQuery.attrFn ) {
4351                 jQuery.attrFn[ name ] = true;
4352         }
4353 });
4354
4355
4356
4357 /*!
4358  * Sizzle CSS Selector Engine
4359  *  Copyright 2011, The Dojo Foundation
4360  *  Released under the MIT, BSD, and GPL Licenses.
4361  *  More information: http://sizzlejs.com/
4362  */
4363 (function(){
4364
4365 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
4366         done = 0,
4367         toString = Object.prototype.toString,
4368         hasDuplicate = false,
4369         baseHasDuplicate = true,
4370         rBackslash = /\\/g,
4371         rNonWord = /\W/;
4372
4373 // Here we check if the JavaScript engine is using some sort of
4374 // optimization where it does not always call our comparision
4375 // function. If that is the case, discard the hasDuplicate value.
4376 //   Thus far that includes Google Chrome.
4377 [0, 0].sort(function() {
4378         baseHasDuplicate = false;
4379         return 0;
4380 });
4381
4382 var Sizzle = function( selector, context, results, seed ) {
4383         results = results || [];
4384         context = context || document;
4385
4386         var origContext = context;
4387
4388         if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
4389                 return [];
4390         }
4391         
4392         if ( !selector || typeof selector !== "string" ) {
4393                 return results;
4394         }
4395
4396         var m, set, checkSet, extra, ret, cur, pop, i,
4397                 prune = true,
4398                 contextXML = Sizzle.isXML( context ),
4399                 parts = [],
4400                 soFar = selector;
4401         
4402         // Reset the position of the chunker regexp (start from head)
4403         do {
4404                 chunker.exec( "" );
4405                 m = chunker.exec( soFar );
4406
4407                 if ( m ) {
4408                         soFar = m[3];
4409                 
4410                         parts.push( m[1] );
4411                 
4412                         if ( m[2] ) {
4413                                 extra = m[3];
4414                                 break;
4415                         }
4416                 }
4417         } while ( m );
4418
4419         if ( parts.length > 1 && origPOS.exec( selector ) ) {
4420
4421                 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4422                         set = posProcess( parts[0] + parts[1], context );
4423
4424                 } else {
4425                         set = Expr.relative[ parts[0] ] ?
4426                                 [ context ] :
4427                                 Sizzle( parts.shift(), context );
4428
4429                         while ( parts.length ) {
4430                                 selector = parts.shift();
4431
4432                                 if ( Expr.relative[ selector ] ) {
4433                                         selector += parts.shift();
4434                                 }
4435                                 
4436                                 set = posProcess( selector, set );
4437                         }
4438                 }
4439
4440         } else {
4441                 // Take a shortcut and set the context if the root selector is an ID
4442                 // (but not if it'll be faster if the inner selector is an ID)
4443                 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4444                                 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4445
4446                         ret = Sizzle.find( parts.shift(), context, contextXML );
4447                         context = ret.expr ?
4448                                 Sizzle.filter( ret.expr, ret.set )[0] :
4449                                 ret.set[0];
4450                 }
4451
4452                 if ( context ) {
4453                         ret = seed ?
4454                                 { expr: parts.pop(), set: makeArray(seed) } :
4455                                 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4456
4457                         set = ret.expr ?
4458                                 Sizzle.filter( ret.expr, ret.set ) :
4459                                 ret.set;
4460
4461                         if ( parts.length > 0 ) {
4462                                 checkSet = makeArray( set );
4463
4464                         } else {
4465                                 prune = false;
4466                         }
4467
4468                         while ( parts.length ) {
4469                                 cur = parts.pop();
4470                                 pop = cur;
4471
4472                                 if ( !Expr.relative[ cur ] ) {
4473                                         cur = "";
4474                                 } else {
4475                                         pop = parts.pop();
4476                                 }
4477
4478                                 if ( pop == null ) {
4479                                         pop = context;
4480                                 }
4481
4482                                 Expr.relative[ cur ]( checkSet, pop, contextXML );
4483                         }
4484
4485                 } else {
4486                         checkSet = parts = [];
4487                 }
4488         }
4489
4490         if ( !checkSet ) {
4491                 checkSet = set;
4492         }
4493
4494         if ( !checkSet ) {
4495                 Sizzle.error( cur || selector );
4496         }
4497
4498         if ( toString.call(checkSet) === "[object Array]" ) {
4499                 if ( !prune ) {
4500                         results.push.apply( results, checkSet );
4501
4502                 } else if ( context && context.nodeType === 1 ) {
4503                         for ( i = 0; checkSet[i] != null; i++ ) {
4504                                 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
4505                                         results.push( set[i] );
4506                                 }
4507                         }
4508
4509                 } else {
4510                         for ( i = 0; checkSet[i] != null; i++ ) {
4511                                 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4512                                         results.push( set[i] );
4513                                 }
4514                         }
4515                 }
4516
4517         } else {
4518                 makeArray( checkSet, results );
4519         }
4520
4521         if ( extra ) {
4522                 Sizzle( extra, origContext, results, seed );
4523                 Sizzle.uniqueSort( results );
4524         }
4525
4526         return results;
4527 };
4528
4529 Sizzle.uniqueSort = function( results ) {
4530         if ( sortOrder ) {
4531                 hasDuplicate = baseHasDuplicate;
4532                 results.sort( sortOrder );
4533
4534                 if ( hasDuplicate ) {
4535                         for ( var i = 1; i < results.length; i++ ) {
4536                                 if ( results[i] === results[ i - 1 ] ) {
4537                                         results.splice( i--, 1 );
4538                                 }
4539                         }
4540                 }
4541         }
4542
4543         return results;
4544 };
4545
4546 Sizzle.matches = function( expr, set ) {
4547         return Sizzle( expr, null, null, set );
4548 };
4549
4550 Sizzle.matchesSelector = function( node, expr ) {
4551         return Sizzle( expr, null, null, [node] ).length > 0;
4552 };
4553
4554 Sizzle.find = function( expr, context, isXML ) {
4555         var set;
4556
4557         if ( !expr ) {
4558                 return [];
4559         }
4560
4561         for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
4562                 var match,
4563                         type = Expr.order[i];
4564                 
4565                 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4566                         var left = match[1];
4567                         match.splice( 1, 1 );
4568
4569                         if ( left.substr( left.length - 1 ) !== "\\" ) {
4570                                 match[1] = (match[1] || "").replace( rBackslash, "" );
4571                                 set = Expr.find[ type ]( match, context, isXML );
4572
4573                                 if ( set != null ) {
4574                                         expr = expr.replace( Expr.match[ type ], "" );
4575                                         break;
4576                                 }
4577                         }
4578                 }
4579         }
4580
4581         if ( !set ) {
4582                 set = typeof context.getElementsByTagName !== "undefined" ?
4583                         context.getElementsByTagName( "*" ) :
4584                         [];
4585         }
4586
4587         return { set: set, expr: expr };
4588 };
4589
4590 Sizzle.filter = function( expr, set, inplace, not ) {
4591         var match, anyFound,
4592                 old = expr,
4593                 result = [],
4594                 curLoop = set,
4595                 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
4596
4597         while ( expr && set.length ) {
4598                 for ( var type in Expr.filter ) {
4599                         if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
4600                                 var found, item,
4601                                         filter = Expr.filter[ type ],
4602                                         left = match[1];
4603
4604                                 anyFound = false;
4605
4606                                 match.splice(1,1);
4607
4608                                 if ( left.substr( left.length - 1 ) === "\\" ) {
4609                                         continue;
4610                                 }
4611
4612                                 if ( curLoop === result ) {
4613                                         result = [];
4614                                 }
4615
4616                                 if ( Expr.preFilter[ type ] ) {
4617                                         match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4618
4619                                         if ( !match ) {
4620                                                 anyFound = found = true;
4621
4622                                         } else if ( match === true ) {
4623                                                 continue;
4624                                         }
4625                                 }
4626
4627                                 if ( match ) {
4628                                         for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4629                                                 if ( item ) {
4630                                                         found = filter( item, match, i, curLoop );
4631                                                         var pass = not ^ !!found;
4632
4633                                                         if ( inplace && found != null ) {
4634                                                                 if ( pass ) {
4635                                                                         anyFound = true;
4636
4637                                                                 } else {
4638                                                                         curLoop[i] = false;
4639                                                                 }
4640
4641                                                         } else if ( pass ) {
4642                                                                 result.push( item );
4643                                                                 anyFound = true;
4644                                                         }
4645                                                 }
4646                                         }
4647                                 }
4648
4649                                 if ( found !== undefined ) {
4650                                         if ( !inplace ) {
4651                                                 curLoop = result;
4652                                         }
4653
4654                                         expr = expr.replace( Expr.match[ type ], "" );
4655
4656                                         if ( !anyFound ) {
4657                                                 return [];
4658                                         }
4659
4660                                         break;
4661                                 }
4662                         }
4663                 }
4664
4665                 // Improper expression
4666                 if ( expr === old ) {
4667                         if ( anyFound == null ) {
4668                                 Sizzle.error( expr );
4669
4670                         } else {
4671                                 break;
4672                         }
4673                 }
4674
4675                 old = expr;
4676         }
4677
4678         return curLoop;
4679 };
4680
4681 Sizzle.error = function( msg ) {
4682         throw "Syntax error, unrecognized expression: " + msg;
4683 };
4684
4685 var Expr = Sizzle.selectors = {
4686         order: [ "ID", "NAME", "TAG" ],
4687
4688         match: {
4689                 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4690                 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4691                 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4692                 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4693                 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4694                 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4695                 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4696                 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4697         },
4698
4699         leftMatch: {},
4700
4701         attrMap: {
4702                 "class": "className",
4703                 "for": "htmlFor"
4704         },
4705
4706         attrHandle: {
4707                 href: function( elem ) {
4708                         return elem.getAttribute( "href" );
4709                 },
4710                 type: function( elem ) {
4711                         return elem.getAttribute( "type" );
4712                 }
4713         },
4714
4715         relative: {
4716                 "+": function(checkSet, part){
4717                         var isPartStr = typeof part === "string",
4718                                 isTag = isPartStr && !rNonWord.test( part ),
4719                                 isPartStrNotTag = isPartStr && !isTag;
4720
4721                         if ( isTag ) {
4722                                 part = part.toLowerCase();
4723                         }
4724
4725                         for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4726                                 if ( (elem = checkSet[i]) ) {
4727                                         while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4728
4729                                         checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4730                                                 elem || false :
4731                                                 elem === part;
4732                                 }
4733                         }
4734
4735                         if ( isPartStrNotTag ) {
4736                                 Sizzle.filter( part, checkSet, true );
4737                         }
4738                 },
4739
4740                 ">": function( checkSet, part ) {
4741                         var elem,
4742                                 isPartStr = typeof part === "string",
4743                                 i = 0,
4744                                 l = checkSet.length;
4745
4746                         if ( isPartStr && !rNonWord.test( part ) ) {
4747                                 part = part.toLowerCase();
4748
4749                                 for ( ; i < l; i++ ) {
4750                                         elem = checkSet[i];
4751
4752                                         if ( elem ) {
4753                                                 var parent = elem.parentNode;
4754                                                 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4755                                         }
4756                                 }
4757
4758                         } else {
4759                                 for ( ; i < l; i++ ) {
4760                                         elem = checkSet[i];
4761
4762                                         if ( elem ) {
4763                                                 checkSet[i] = isPartStr ?
4764                                                         elem.parentNode :
4765                                                         elem.parentNode === part;
4766                                         }
4767                                 }
4768
4769                                 if ( isPartStr ) {
4770                                         Sizzle.filter( part, checkSet, true );
4771                                 }
4772                         }
4773                 },
4774
4775                 "": function(checkSet, part, isXML){
4776                         var nodeCheck,
4777                                 doneName = done++,
4778                                 checkFn = dirCheck;
4779
4780                         if ( typeof part === "string" && !rNonWord.test( part ) ) {
4781                                 part = part.toLowerCase();
4782                                 nodeCheck = part;
4783                                 checkFn = dirNodeCheck;
4784                         }
4785
4786                         checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4787                 },
4788
4789                 "~": function( checkSet, part, isXML ) {
4790                         var nodeCheck,
4791                                 doneName = done++,
4792                                 checkFn = dirCheck;
4793
4794                         if ( typeof part === "string" && !rNonWord.test( part ) ) {
4795                                 part = part.toLowerCase();
4796                                 nodeCheck = part;
4797                                 checkFn = dirNodeCheck;
4798                         }
4799
4800                         checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4801                 }
4802         },
4803
4804         find: {
4805                 ID: function( match, context, isXML ) {
4806                         if ( typeof context.getElementById !== "undefined" && !isXML ) {
4807                                 var m = context.getElementById(match[1]);
4808                                 // Check parentNode to catch when Blackberry 4.6 returns
4809                                 // nodes that are no longer in the document #6963
4810                                 return m && m.parentNode ? [m] : [];
4811                         }
4812                 },
4813
4814                 NAME: function( match, context ) {
4815                         if ( typeof context.getElementsByName !== "undefined" ) {
4816                                 var ret = [],
4817                                         results = context.getElementsByName( match[1] );
4818
4819                                 for ( var i = 0, l = results.length; i < l; i++ ) {
4820                                         if ( results[i].getAttribute("name") === match[1] ) {
4821                                                 ret.push( results[i] );
4822                                         }
4823                                 }
4824
4825                                 return ret.length === 0 ? null : ret;
4826                         }
4827                 },
4828
4829                 TAG: function( match, context ) {
4830                         if ( typeof context.getElementsByTagName !== "undefined" ) {
4831                                 return context.getElementsByTagName( match[1] );
4832                         }
4833                 }
4834         },
4835         preFilter: {
4836                 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4837                         match = " " + match[1].replace( rBackslash, "" ) + " ";
4838
4839                         if ( isXML ) {
4840                                 return match;
4841                         }
4842
4843                         for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4844                                 if ( elem ) {
4845                                         if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4846                                                 if ( !inplace ) {
4847                                                         result.push( elem );
4848                                                 }
4849
4850                                         } else if ( inplace ) {
4851                                                 curLoop[i] = false;
4852                                         }
4853                                 }
4854                         }
4855
4856                         return false;
4857                 },
4858
4859                 ID: function( match ) {
4860                         return match[1].replace( rBackslash, "" );
4861                 },
4862
4863                 TAG: function( match, curLoop ) {
4864                         return match[1].replace( rBackslash, "" ).toLowerCase();
4865                 },
4866
4867                 CHILD: function( match ) {
4868                         if ( match[1] === "nth" ) {
4869                                 if ( !match[2] ) {
4870                                         Sizzle.error( match[0] );
4871                                 }
4872
4873                                 match[2] = match[2].replace(/^\+|\s*/g, '');
4874
4875                                 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4876                                 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4877                                         match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4878                                         !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4879
4880                                 // calculate the numbers (first)n+(last) including if they are negative
4881                                 match[2] = (test[1] + (test[2] || 1)) - 0;
4882                                 match[3] = test[3] - 0;
4883                         }
4884                         else if ( match[2] ) {
4885                                 Sizzle.error( match[0] );
4886                         }
4887
4888                         // TODO: Move to normal caching system
4889                         match[0] = done++;
4890
4891                         return match;
4892                 },
4893
4894                 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4895                         var name = match[1] = match[1].replace( rBackslash, "" );
4896                         
4897                         if ( !isXML && Expr.attrMap[name] ) {
4898                                 match[1] = Expr.attrMap[name];
4899                         }
4900
4901                         // Handle if an un-quoted value was used
4902                         match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4903
4904                         if ( match[2] === "~=" ) {
4905                                 match[4] = " " + match[4] + " ";
4906                         }
4907
4908                         return match;
4909                 },
4910
4911                 PSEUDO: function( match, curLoop, inplace, result, not ) {
4912                         if ( match[1] === "not" ) {
4913                                 // If we're dealing with a complex expression, or a simple one
4914                                 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4915                                         match[3] = Sizzle(match[3], null, null, curLoop);
4916
4917                                 } else {
4918                                         var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4919
4920                                         if ( !inplace ) {
4921                                                 result.push.apply( result, ret );
4922                                         }
4923
4924                                         return false;
4925                                 }
4926
4927                         } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4928                                 return true;
4929                         }
4930                         
4931                         return match;
4932                 },
4933
4934                 POS: function( match ) {
4935                         match.unshift( true );
4936
4937                         return match;
4938                 }
4939         },
4940         
4941         filters: {
4942                 enabled: function( elem ) {
4943                         return elem.disabled === false && elem.type !== "hidden";
4944                 },
4945
4946                 disabled: function( elem ) {
4947                         return elem.disabled === true;
4948                 },
4949
4950                 checked: function( elem ) {
4951                         return elem.checked === true;
4952                 },
4953                 
4954                 selected: function( elem ) {
4955                         // Accessing this property makes selected-by-default
4956                         // options in Safari work properly
4957                         if ( elem.parentNode ) {
4958                                 elem.parentNode.selectedIndex;
4959                         }
4960                         
4961                         return elem.selected === true;
4962                 },
4963
4964                 parent: function( elem ) {
4965                         return !!elem.firstChild;
4966                 },
4967
4968                 empty: function( elem ) {
4969                         return !elem.firstChild;
4970                 },
4971
4972                 has: function( elem, i, match ) {
4973                         return !!Sizzle( match[3], elem ).length;
4974                 },
4975
4976                 header: function( elem ) {
4977                         return (/h\d/i).test( elem.nodeName );
4978                 },
4979
4980                 text: function( elem ) {
4981                         var attr = elem.getAttribute( "type" ), type = elem.type;
4982                         // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 
4983                         // use getAttribute instead to test this case
4984                         return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4985                 },
4986
4987                 radio: function( elem ) {
4988                         return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4989                 },
4990
4991                 checkbox: function( elem ) {
4992                         return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4993                 },
4994
4995                 file: function( elem ) {
4996                         return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4997                 },
4998
4999                 password: function( elem ) {
5000                         return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
5001                 },
5002
5003                 submit: function( elem ) {
5004                         var name = elem.nodeName.toLowerCase();
5005                         return (name === "input" || name === "button") && "submit" === elem.type;
5006                 },
5007
5008                 image: function( elem ) {
5009                         return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
5010                 },
5011
5012                 reset: function( elem ) {
5013                         return elem.nodeName.toLowerCase() === "input" && "reset" === elem.type;
5014                 },
5015
5016                 button: function( elem ) {
5017                         var name = elem.nodeName.toLowerCase();
5018                         return name === "input" && "button" === elem.type || name === "button";
5019                 },
5020
5021                 input: function( elem ) {
5022                         return (/input|select|textarea|button/i).test( elem.nodeName );
5023                 },
5024
5025                 focus: function( elem ) {
5026                         return elem === elem.ownerDocument.activeElement;
5027                 }
5028         },
5029         setFilters: {
5030                 first: function( elem, i ) {
5031                         return i === 0;
5032                 },
5033
5034                 last: function( elem, i, match, array ) {
5035                         return i === array.length - 1;
5036                 },
5037
5038                 even: function( elem, i ) {
5039                         return i % 2 === 0;
5040                 },
5041
5042                 odd: function( elem, i ) {
5043                         return i % 2 === 1;
5044                 },
5045
5046                 lt: function( elem, i, match ) {
5047                         return i < match[3] - 0;
5048                 },
5049
5050                 gt: function( elem, i, match ) {
5051                         return i > match[3] - 0;
5052                 },
5053
5054                 nth: function( elem, i, match ) {
5055                         return match[3] - 0 === i;
5056                 },
5057
5058                 eq: function( elem, i, match ) {
5059                         return match[3] - 0 === i;
5060                 }
5061         },
5062         filter: {
5063                 PSEUDO: function( elem, match, i, array ) {
5064                         var name = match[1],
5065                                 filter = Expr.filters[ name ];
5066
5067                         if ( filter ) {
5068                                 return filter( elem, i, match, array );
5069
5070                         } else if ( name === "contains" ) {
5071                                 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
5072
5073                         } else if ( name === "not" ) {
5074                                 var not = match[3];
5075
5076                                 for ( var j = 0, l = not.length; j < l; j++ ) {
5077                                         if ( not[j] === elem ) {
5078                                                 return false;
5079                                         }
5080                                 }
5081
5082                                 return true;
5083
5084                         } else {
5085                                 Sizzle.error( name );
5086                         }
5087                 },
5088
5089                 CHILD: function( elem, match ) {
5090                         var type = match[1],
5091                                 node = elem;
5092
5093                         switch ( type ) {
5094                                 case "only":
5095                                 case "first":
5096                                         while ( (node = node.previousSibling) )  {
5097                                                 if ( node.nodeType === 1 ) { 
5098                                                         return false; 
5099                                                 }
5100                                         }
5101
5102                                         if ( type === "first" ) { 
5103                                                 return true; 
5104                                         }
5105
5106                                         node = elem;
5107
5108                                 case "last":
5109                                         while ( (node = node.nextSibling) )      {
5110                                                 if ( node.nodeType === 1 ) { 
5111                                                         return false; 
5112                                                 }
5113                                         }
5114
5115                                         return true;
5116
5117                                 case "nth":
5118                                         var first = match[2],
5119                                                 last = match[3];
5120
5121                                         if ( first === 1 && last === 0 ) {
5122                                                 return true;
5123                                         }
5124                                         
5125                                         var doneName = match[0],
5126                                                 parent = elem.parentNode;
5127         
5128                                         if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
5129                                                 var count = 0;
5130                                                 
5131                                                 for ( node = parent.firstChild; node; node = node.nextSibling ) {
5132                                                         if ( node.nodeType === 1 ) {
5133                                                                 node.nodeIndex = ++count;
5134                                                         }
5135                                                 } 
5136
5137                                                 parent.sizcache = doneName;
5138                                         }
5139                                         
5140                                         var diff = elem.nodeIndex - last;
5141
5142                                         if ( first === 0 ) {
5143                                                 return diff === 0;
5144
5145                                         } else {
5146                                                 return ( diff % first === 0 && diff / first >= 0 );
5147                                         }
5148                         }
5149                 },
5150
5151                 ID: function( elem, match ) {
5152                         return elem.nodeType === 1 && elem.getAttribute("id") === match;
5153                 },
5154
5155                 TAG: function( elem, match ) {
5156                         return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
5157                 },
5158                 
5159                 CLASS: function( elem, match ) {
5160                         return (" " + (elem.className || elem.getAttribute("class")) + " ")
5161                                 .indexOf( match ) > -1;
5162                 },
5163
5164                 ATTR: function( elem, match ) {
5165                         var name = match[1],
5166                                 result = Expr.attrHandle[ name ] ?
5167                                         Expr.attrHandle[ name ]( elem ) :
5168                                         elem[ name ] != null ?
5169                                                 elem[ name ] :
5170                                                 elem.getAttribute( name ),
5171                                 value = result + "",
5172                                 type = match[2],
5173                                 check = match[4];
5174
5175                         return result == null ?
5176                                 type === "!=" :
5177                                 type === "=" ?
5178                                 value === check :
5179                                 type === "*=" ?
5180                                 value.indexOf(check) >= 0 :
5181                                 type === "~=" ?
5182                                 (" " + value + " ").indexOf(check) >= 0 :
5183                                 !check ?
5184                                 value && result !== false :
5185                                 type === "!=" ?
5186                                 value !== check :
5187                                 type === "^=" ?
5188                                 value.indexOf(check) === 0 :
5189                                 type === "$=" ?
5190                                 value.substr(value.length - check.length) === check :
5191                                 type === "|=" ?
5192                                 value === check || value.substr(0, check.length + 1) === check + "-" :
5193                                 false;
5194                 },
5195
5196                 POS: function( elem, match, i, array ) {
5197                         var name = match[2],
5198                                 filter = Expr.setFilters[ name ];
5199
5200                         if ( filter ) {
5201                                 return filter( elem, i, match, array );
5202                         }
5203                 }
5204         }
5205 };
5206
5207 var origPOS = Expr.match.POS,
5208         fescape = function(all, num){
5209                 return "\\" + (num - 0 + 1);
5210         };
5211
5212 for ( var type in Expr.match ) {
5213         Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
5214         Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
5215 }
5216
5217 var makeArray = function( array, results ) {
5218         array = Array.prototype.slice.call( array, 0 );
5219
5220         if ( results ) {
5221                 results.push.apply( results, array );
5222                 return results;
5223         }
5224         
5225         return array;
5226 };
5227
5228 // Perform a simple check to determine if the browser is capable of
5229 // converting a NodeList to an array using builtin methods.
5230 // Also verifies that the returned array holds DOM nodes
5231 // (which is not the case in the Blackberry browser)
5232 try {
5233         Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
5234
5235 // Provide a fallback method if it does not work
5236 } catch( e ) {
5237         makeArray = function( array, results ) {
5238                 var i = 0,
5239                         ret = results || [];
5240
5241                 if ( toString.call(array) === "[object Array]" ) {
5242                         Array.prototype.push.apply( ret, array );
5243
5244                 } else {
5245                         if ( typeof array.length === "number" ) {
5246                                 for ( var l = array.length; i < l; i++ ) {
5247                                         ret.push( array[i] );
5248                                 }
5249
5250                         } else {
5251                                 for ( ; array[i]; i++ ) {
5252                                         ret.push( array[i] );
5253                                 }
5254                         }
5255                 }
5256
5257                 return ret;
5258         };
5259 }
5260
5261 var sortOrder, siblingCheck;
5262
5263 if ( document.documentElement.compareDocumentPosition ) {
5264         sortOrder = function( a, b ) {
5265                 if ( a === b ) {
5266                         hasDuplicate = true;
5267                         return 0;
5268                 }
5269
5270                 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
5271                         return a.compareDocumentPosition ? -1 : 1;
5272                 }
5273
5274                 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
5275         };
5276
5277 } else {
5278         sortOrder = function( a, b ) {
5279                 var al, bl,
5280                         ap = [],
5281                         bp = [],
5282                         aup = a.parentNode,
5283                         bup = b.parentNode,
5284                         cur = aup;
5285
5286                 // The nodes are identical, we can exit early
5287                 if ( a === b ) {
5288                         hasDuplicate = true;
5289                         return 0;
5290
5291                 // If the nodes are siblings (or identical) we can do a quick check
5292                 } else if ( aup === bup ) {
5293                         return siblingCheck( a, b );
5294
5295                 // If no parents were found then the nodes are disconnected
5296                 } else if ( !aup ) {
5297                         return -1;
5298
5299                 } else if ( !bup ) {
5300                         return 1;
5301                 }
5302
5303                 // Otherwise they're somewhere else in the tree so we need
5304                 // to build up a full list of the parentNodes for comparison
5305                 while ( cur ) {
5306                         ap.unshift( cur );
5307                         cur = cur.parentNode;
5308                 }
5309
5310                 cur = bup;
5311
5312                 while ( cur ) {
5313                         bp.unshift( cur );
5314                         cur = cur.parentNode;
5315                 }
5316
5317                 al = ap.length;
5318                 bl = bp.length;
5319
5320                 // Start walking down the tree looking for a discrepancy
5321                 for ( var i = 0; i < al && i < bl; i++ ) {
5322                         if ( ap[i] !== bp[i] ) {
5323                                 return siblingCheck( ap[i], bp[i] );
5324                         }
5325                 }
5326
5327                 // We ended someplace up the tree so do a sibling check
5328                 return i === al ?
5329                         siblingCheck( a, bp[i], -1 ) :
5330                         siblingCheck( ap[i], b, 1 );
5331         };
5332
5333         siblingCheck = function( a, b, ret ) {
5334                 if ( a === b ) {
5335                         return ret;
5336                 }
5337
5338                 var cur = a.nextSibling;
5339
5340                 while ( cur ) {
5341                         if ( cur === b ) {
5342                                 return -1;
5343                         }
5344
5345                         cur = cur.nextSibling;
5346                 }
5347
5348                 return 1;
5349         };
5350 }
5351
5352 // Utility function for retreiving the text value of an array of DOM nodes
5353 Sizzle.getText = function( elems ) {
5354         var ret = "", elem;
5355
5356         for ( var i = 0; elems[i]; i++ ) {
5357                 elem = elems[i];
5358
5359                 // Get the text from text nodes and CDATA nodes
5360                 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
5361                         ret += elem.nodeValue;
5362
5363                 // Traverse everything else, except comment nodes
5364                 } else if ( elem.nodeType !== 8 ) {
5365                         ret += Sizzle.getText( elem.childNodes );
5366                 }
5367         }
5368
5369         return ret;
5370 };
5371
5372 // Check to see if the browser returns elements by name when
5373 // querying by getElementById (and provide a workaround)
5374 (function(){
5375         // We're going to inject a fake input element with a specified name
5376         var form = document.createElement("div"),
5377                 id = "script" + (new Date()).getTime(),
5378                 root = document.documentElement;
5379
5380         form.innerHTML = "<a name='" + id + "'/>";
5381
5382         // Inject it into the root element, check its status, and remove it quickly
5383         root.insertBefore( form, root.firstChild );
5384
5385         // The workaround has to do additional checks after a getElementById
5386         // Which slows things down for other browsers (hence the branching)
5387         if ( document.getElementById( id ) ) {
5388                 Expr.find.ID = function( match, context, isXML ) {
5389                         if ( typeof context.getElementById !== "undefined" && !isXML ) {
5390                                 var m = context.getElementById(match[1]);
5391
5392                                 return m ?
5393                                         m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
5394                                                 [m] :
5395                                                 undefined :
5396                                         [];
5397                         }
5398                 };
5399
5400                 Expr.filter.ID = function( elem, match ) {
5401                         var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
5402
5403                         return elem.nodeType === 1 && node && node.nodeValue === match;
5404                 };
5405         }
5406
5407         root.removeChild( form );
5408
5409         // release memory in IE
5410         root = form = null;
5411 })();
5412
5413 (function(){
5414         // Check to see if the browser returns only elements
5415         // when doing getElementsByTagName("*")
5416
5417         // Create a fake element
5418         var div = document.createElement("div");
5419         div.appendChild( document.createComment("") );
5420
5421         // Make sure no comments are found
5422         if ( div.getElementsByTagName("*").length > 0 ) {
5423                 Expr.find.TAG = function( match, context ) {
5424                         var results = context.getElementsByTagName( match[1] );
5425
5426                         // Filter out possible comments
5427                         if ( match[1] === "*" ) {
5428                                 var tmp = [];
5429
5430                                 for ( var i = 0; results[i]; i++ ) {
5431                                         if ( results[i].nodeType === 1 ) {
5432                                                 tmp.push( results[i] );
5433                                         }
5434                                 }
5435
5436                                 results = tmp;
5437                         }
5438
5439                         return results;
5440                 };
5441         }
5442
5443         // Check to see if an attribute returns normalized href attributes
5444         div.innerHTML = "<a href='#'></a>";
5445
5446         if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
5447                         div.firstChild.getAttribute("href") !== "#" ) {
5448
5449                 Expr.attrHandle.href = function( elem ) {
5450                         return elem.getAttribute( "href", 2 );
5451                 };
5452         }
5453
5454         // release memory in IE
5455         div = null;
5456 })();
5457
5458 if ( document.querySelectorAll ) {
5459         (function(){
5460                 var oldSizzle = Sizzle,
5461                         div = document.createElement("div"),
5462                         id = "__sizzle__";
5463
5464                 div.innerHTML = "<p class='TEST'></p>";
5465
5466                 // Safari can't handle uppercase or unicode characters when
5467                 // in quirks mode.
5468                 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
5469                         return;
5470                 }
5471         
5472                 Sizzle = function( query, context, extra, seed ) {
5473                         context = context || document;
5474
5475                         // Only use querySelectorAll on non-XML documents
5476                         // (ID selectors don't work in non-HTML documents)
5477                         if ( !seed && !Sizzle.isXML(context) ) {
5478                                 // See if we find a selector to speed up
5479                                 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
5480                                 
5481                                 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
5482                                         // Speed-up: Sizzle("TAG")
5483                                         if ( match[1] ) {
5484                                                 return makeArray( context.getElementsByTagName( query ), extra );
5485                                         
5486                                         // Speed-up: Sizzle(".CLASS")
5487                                         } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
5488                                                 return makeArray( context.getElementsByClassName( match[2] ), extra );
5489                                         }
5490                                 }
5491                                 
5492                                 if ( context.nodeType === 9 ) {
5493                                         // Speed-up: Sizzle("body")
5494                                         // The body element only exists once, optimize finding it
5495                                         if ( query === "body" && context.body ) {
5496                                                 return makeArray( [ context.body ], extra );
5497                                                 
5498                                         // Speed-up: Sizzle("#ID")
5499                                         } else if ( match && match[3] ) {
5500                                                 var elem = context.getElementById( match[3] );
5501
5502                                                 // Check parentNode to catch when Blackberry 4.6 returns
5503                                                 // nodes that are no longer in the document #6963
5504                                                 if ( elem && elem.parentNode ) {
5505                                                         // Handle the case where IE and Opera return items
5506                                                         // by name instead of ID
5507                                                         if ( elem.id === match[3] ) {
5508                                                                 return makeArray( [ elem ], extra );
5509                                                         }
5510                                                         
5511                                                 } else {
5512                                                         return makeArray( [], extra );
5513                                                 }
5514                                         }
5515                                         
5516                                         try {
5517                                                 return makeArray( context.querySelectorAll(query), extra );
5518                                         } catch(qsaError) {}
5519
5520                                 // qSA works strangely on Element-rooted queries
5521                                 // We can work around this by specifying an extra ID on the root
5522                                 // and working up from there (Thanks to Andrew Dupont for the technique)
5523                                 // IE 8 doesn't work on object elements
5524                                 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5525                                         var oldContext = context,
5526                                                 old = context.getAttribute( "id" ),
5527                                                 nid = old || id,
5528                                                 hasParent = context.parentNode,
5529                                                 relativeHierarchySelector = /^\s*[+~]/.test( query );
5530
5531                                         if ( !old ) {
5532                                                 context.setAttribute( "id", nid );
5533                                         } else {
5534                                                 nid = nid.replace( /'/g, "\\$&" );
5535                                         }
5536                                         if ( relativeHierarchySelector && hasParent ) {
5537                                                 context = context.parentNode;
5538                                         }
5539
5540                                         try {
5541                                                 if ( !relativeHierarchySelector || hasParent ) {
5542                                                         return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
5543                                                 }
5544
5545                                         } catch(pseudoError) {
5546                                         } finally {
5547                                                 if ( !old ) {
5548                                                         oldContext.removeAttribute( "id" );
5549                                                 }
5550                                         }
5551                                 }
5552                         }
5553                 
5554                         return oldSizzle(query, context, extra, seed);
5555                 };
5556
5557                 for ( var prop in oldSizzle ) {
5558                         Sizzle[ prop ] = oldSizzle[ prop ];
5559                 }
5560
5561                 // release memory in IE
5562                 div = null;
5563         })();
5564 }
5565
5566 (function(){
5567         var html = document.documentElement,
5568                 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
5569
5570         if ( matches ) {
5571                 // Check to see if it's possible to do matchesSelector
5572                 // on a disconnected node (IE 9 fails this)
5573                 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
5574                         pseudoWorks = false;
5575
5576                 try {
5577                         // This should fail with an exception
5578                         // Gecko does not error, returns false instead
5579                         matches.call( document.documentElement, "[test!='']:sizzle" );
5580         
5581                 } catch( pseudoError ) {
5582                         pseudoWorks = true;
5583                 }
5584
5585                 Sizzle.matchesSelector = function( node, expr ) {
5586                         // Make sure that attribute selectors are quoted
5587                         expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
5588
5589                         if ( !Sizzle.isXML( node ) ) {
5590                                 try { 
5591                                         if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
5592                                                 var ret = matches.call( node, expr );
5593
5594                                                 // IE 9's matchesSelector returns false on disconnected nodes
5595                                                 if ( ret || !disconnectedMatch ||
5596                                                                 // As well, disconnected nodes are said to be in a document
5597                                                                 // fragment in IE 9, so check for that
5598                                                                 node.document && node.document.nodeType !== 11 ) {
5599                                                         return ret;
5600                                                 }
5601                                         }
5602                                 } catch(e) {}
5603                         }
5604
5605                         return Sizzle(expr, null, null, [node]).length > 0;
5606                 };
5607         }
5608 })();
5609
5610 (function(){
5611         var div = document.createElement("div");
5612
5613         div.innerHTML = "<div class='test e'></div><div class='test'></div>";
5614
5615         // Opera can't find a second classname (in 9.6)
5616         // Also, make sure that getElementsByClassName actually exists
5617         if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
5618                 return;
5619         }
5620
5621         // Safari caches class attributes, doesn't catch changes (in 3.2)
5622         div.lastChild.className = "e";
5623
5624         if ( div.getElementsByClassName("e").length === 1 ) {
5625                 return;
5626         }
5627         
5628         Expr.order.splice(1, 0, "CLASS");
5629         Expr.find.CLASS = function( match, context, isXML ) {
5630                 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5631                         return context.getElementsByClassName(match[1]);
5632                 }
5633         };
5634
5635         // release memory in IE
5636         div = null;
5637 })();
5638
5639 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5640         for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5641                 var elem = checkSet[i];
5642
5643                 if ( elem ) {
5644                         var match = false;
5645
5646                         elem = elem[dir];
5647
5648                         while ( elem ) {
5649                                 if ( elem.sizcache === doneName ) {
5650                                         match = checkSet[elem.sizset];
5651                                         break;
5652                                 }
5653
5654                                 if ( elem.nodeType === 1 && !isXML ){
5655                                         elem.sizcache = doneName;
5656                                         elem.sizset = i;
5657                                 }
5658
5659                                 if ( elem.nodeName.toLowerCase() === cur ) {
5660                                         match = elem;
5661                                         break;
5662                                 }
5663
5664                                 elem = elem[dir];
5665                         }
5666
5667                         checkSet[i] = match;
5668                 }
5669         }
5670 }
5671
5672 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5673         for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5674                 var elem = checkSet[i];
5675
5676                 if ( elem ) {
5677                         var match = false;
5678                         
5679                         elem = elem[dir];
5680
5681                         while ( elem ) {
5682                                 if ( elem.sizcache === doneName ) {
5683                                         match = checkSet[elem.sizset];
5684                                         break;
5685                                 }
5686
5687                                 if ( elem.nodeType === 1 ) {
5688                                         if ( !isXML ) {
5689                                                 elem.sizcache = doneName;
5690                                                 elem.sizset = i;
5691                                         }
5692
5693                                         if ( typeof cur !== "string" ) {
5694                                                 if ( elem === cur ) {
5695                                                         match = true;
5696                                                         break;
5697                                                 }
5698
5699                                         } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5700                                                 match = elem;
5701                                                 break;
5702                                         }
5703                                 }
5704
5705                                 elem = elem[dir];
5706                         }
5707
5708                         checkSet[i] = match;
5709                 }
5710         }
5711 }
5712
5713 if ( document.documentElement.contains ) {
5714         Sizzle.contains = function( a, b ) {
5715                 return a !== b && (a.contains ? a.contains(b) : true);
5716         };
5717
5718 } else if ( document.documentElement.compareDocumentPosition ) {
5719         Sizzle.contains = function( a, b ) {
5720                 return !!(a.compareDocumentPosition(b) & 16);
5721         };
5722
5723 } else {
5724         Sizzle.contains = function() {
5725                 return false;
5726         };
5727 }
5728
5729 Sizzle.isXML = function( elem ) {
5730         // documentElement is verified for cases where it doesn't yet exist
5731         // (such as loading iframes in IE - #4833) 
5732         var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5733
5734         return documentElement ? documentElement.nodeName !== "HTML" : false;
5735 };
5736
5737 var posProcess = function( selector, context ) {
5738         var match,
5739                 tmpSet = [],
5740                 later = "",
5741                 root = context.nodeType ? [context] : context;
5742
5743         // Position selectors must be done after the filter
5744         // And so must :not(positional) so we move all PSEUDOs to the end
5745         while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5746                 later += match[0];
5747                 selector = selector.replace( Expr.match.PSEUDO, "" );
5748         }
5749
5750         selector = Expr.relative[selector] ? selector + "*" : selector;
5751
5752         for ( var i = 0, l = root.length; i < l; i++ ) {
5753                 Sizzle( selector, root[i], tmpSet );
5754         }
5755
5756         return Sizzle.filter( later, tmpSet );
5757 };
5758
5759 // EXPOSE
5760 jQuery.find = Sizzle;
5761 jQuery.expr = Sizzle.selectors;
5762 jQuery.expr[":"] = jQuery.expr.filters;
5763 jQuery.unique = Sizzle.uniqueSort;
5764 jQuery.text = Sizzle.getText;
5765 jQuery.isXMLDoc = Sizzle.isXML;
5766 jQuery.contains = Sizzle.contains;
5767
5768
5769 })();
5770
5771
5772 var runtil = /Until$/,
5773         rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5774         // Note: This RegExp should be improved, or likely pulled from Sizzle
5775         rmultiselector = /,/,
5776         isSimple = /^.[^:#\[\.,]*$/,
5777         slice = Array.prototype.slice,
5778         POS = jQuery.expr.match.POS,
5779         // methods guaranteed to produce a unique set when starting from a unique set
5780         guaranteedUnique = {
5781                 children: true,
5782                 contents: true,
5783                 next: true,
5784                 prev: true
5785         };
5786
5787 jQuery.fn.extend({
5788         find: function( selector ) {
5789                 var self = this,
5790                         i, l;
5791
5792                 if ( typeof selector !== "string" ) {
5793                         return jQuery( selector ).filter(function() {
5794                                 for ( i = 0, l = self.length; i < l; i++ ) {
5795                                         if ( jQuery.contains( self[ i ], this ) ) {
5796                                                 return true;
5797                                         }
5798                                 }
5799                         });
5800                 }
5801
5802                 var ret = this.pushStack( "", "find", selector ),
5803                         length, n, r;
5804
5805                 for ( i = 0, l = this.length; i < l; i++ ) {
5806                         length = ret.length;
5807                         jQuery.find( selector, this[i], ret );
5808
5809                         if ( i > 0 ) {
5810                                 // Make sure that the results are unique
5811                                 for ( n = length; n < ret.length; n++ ) {
5812                                         for ( r = 0; r < length; r++ ) {
5813                                                 if ( ret[r] === ret[n] ) {
5814                                                         ret.splice(n--, 1);
5815                                                         break;
5816                                                 }
5817                                         }
5818                                 }
5819                         }
5820                 }
5821
5822                 return ret;
5823         },
5824
5825         has: function( target ) {
5826                 var targets = jQuery( target );
5827                 return this.filter(function() {
5828                         for ( var i = 0, l = targets.length; i < l; i++ ) {
5829                                 if ( jQuery.contains( this, targets[i] ) ) {
5830                                         return true;
5831                                 }
5832                         }
5833                 });
5834         },
5835
5836         not: function( selector ) {
5837                 return this.pushStack( winnow(this, selector, false), "not", selector);
5838         },
5839
5840         filter: function( selector ) {
5841                 return this.pushStack( winnow(this, selector, true), "filter", selector );
5842         },
5843
5844         is: function( selector ) {
5845                 return !!selector && ( typeof selector === "string" ?
5846                         jQuery.filter( selector, this ).length > 0 :
5847                         this.filter( selector ).length > 0 );
5848         },
5849
5850         closest: function( selectors, context ) {
5851                 var ret = [], i, l, cur = this[0];
5852                 
5853                 // Array
5854                 if ( jQuery.isArray( selectors ) ) {
5855                         var match, selector,
5856                                 matches = {},
5857                                 level = 1;
5858
5859                         if ( cur && selectors.length ) {
5860                                 for ( i = 0, l = selectors.length; i < l; i++ ) {
5861                                         selector = selectors[i];
5862
5863                                         if ( !matches[ selector ] ) {
5864                                                 matches[ selector ] = POS.test( selector ) ?
5865                                                         jQuery( selector, context || this.context ) :
5866                                                         selector;
5867                                         }
5868                                 }
5869
5870                                 while ( cur && cur.ownerDocument && cur !== context ) {
5871                                         for ( selector in matches ) {
5872                                                 match = matches[ selector ];
5873
5874                                                 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5875                                                         ret.push({ selector: selector, elem: cur, level: level });
5876                                                 }
5877                                         }
5878
5879                                         cur = cur.parentNode;
5880                                         level++;
5881                                 }
5882                         }
5883
5884                         return ret;
5885                 }
5886
5887                 // String
5888                 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5889                                 jQuery( selectors, context || this.context ) :
5890                                 0;
5891
5892                 for ( i = 0, l = this.length; i < l; i++ ) {
5893                         cur = this[i];
5894
5895                         while ( cur ) {
5896                                 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5897                                         ret.push( cur );
5898                                         break;
5899
5900                                 } else {
5901                                         cur = cur.parentNode;
5902                                         if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5903                                                 break;
5904                                         }
5905                                 }
5906                         }
5907                 }
5908
5909                 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5910
5911                 return this.pushStack( ret, "closest", selectors );
5912         },
5913
5914         // Determine the position of an element within
5915         // the matched set of elements
5916         index: function( elem ) {
5917                 if ( !elem || typeof elem === "string" ) {
5918                         return jQuery.inArray( this[0],
5919                                 // If it receives a string, the selector is used
5920                                 // If it receives nothing, the siblings are used
5921                                 elem ? jQuery( elem ) : this.parent().children() );
5922                 }
5923                 // Locate the position of the desired element
5924                 return jQuery.inArray(
5925                         // If it receives a jQuery object, the first element is used
5926                         elem.jquery ? elem[0] : elem, this );
5927         },
5928
5929         add: function( selector, context ) {
5930                 var set = typeof selector === "string" ?
5931                                 jQuery( selector, context ) :
5932                                 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5933                         all = jQuery.merge( this.get(), set );
5934
5935                 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5936                         all :
5937                         jQuery.unique( all ) );
5938         },
5939
5940         andSelf: function() {
5941                 return this.add( this.prevObject );
5942         }
5943 });
5944
5945 // A painfully simple check to see if an element is disconnected
5946 // from a document (should be improved, where feasible).
5947 function isDisconnected( node ) {
5948         return !node || !node.parentNode || node.parentNode.nodeType === 11;
5949 }
5950
5951 jQuery.each({
5952         parent: function( elem ) {
5953                 var parent = elem.parentNode;
5954                 return parent && parent.nodeType !== 11 ? parent : null;
5955         },
5956         parents: function( elem ) {
5957                 return jQuery.dir( elem, "parentNode" );
5958         },
5959         parentsUntil: function( elem, i, until ) {
5960                 return jQuery.dir( elem, "parentNode", until );
5961         },
5962         next: function( elem ) {
5963                 return jQuery.nth( elem, 2, "nextSibling" );
5964         },
5965         prev: function( elem ) {
5966                 return jQuery.nth( elem, 2, "previousSibling" );
5967         },
5968         nextAll: function( elem ) {
5969                 return jQuery.dir( elem, "nextSibling" );
5970         },
5971         prevAll: function( elem ) {
5972                 return jQuery.dir( elem, "previousSibling" );
5973         },
5974         nextUntil: function( elem, i, until ) {
5975                 return jQuery.dir( elem, "nextSibling", until );
5976         },
5977         prevUntil: function( elem, i, until ) {
5978                 return jQuery.dir( elem, "previousSibling", until );
5979         },
5980         siblings: function( elem ) {
5981                 return jQuery.sibling( elem.parentNode.firstChild, elem );
5982         },
5983         children: function( elem ) {
5984                 return jQuery.sibling( elem.firstChild );
5985         },
5986         contents: function( elem ) {
5987                 return jQuery.nodeName( elem, "iframe" ) ?
5988                         elem.contentDocument || elem.contentWindow.document :
5989                         jQuery.makeArray( elem.childNodes );
5990         }
5991 }, function( name, fn ) {
5992         jQuery.fn[ name ] = function( until, selector ) {
5993                 var ret = jQuery.map( this, fn, until ),
5994                         // The variable 'args' was introduced in
5995                         // https://github.com/jquery/jquery/commit/52a0238
5996                         // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5997                         // http://code.google.com/p/v8/issues/detail?id=1050
5998                         args = slice.call(arguments);
5999
6000                 if ( !runtil.test( name ) ) {
6001                         selector = until;
6002                 }
6003
6004                 if ( selector && typeof selector === "string" ) {
6005                         ret = jQuery.filter( selector, ret );
6006                 }
6007
6008                 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
6009
6010                 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
6011                         ret = ret.reverse();
6012                 }
6013
6014                 return this.pushStack( ret, name, args.join(",") );
6015         };
6016 });
6017
6018 jQuery.extend({
6019         filter: function( expr, elems, not ) {
6020                 if ( not ) {
6021                         expr = ":not(" + expr + ")";
6022                 }
6023
6024                 return elems.length === 1 ?
6025                         jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
6026                         jQuery.find.matches(expr, elems);
6027         },
6028
6029         dir: function( elem, dir, until ) {
6030                 var matched = [],
6031                         cur = elem[ dir ];
6032
6033                 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
6034                         if ( cur.nodeType === 1 ) {
6035                                 matched.push( cur );
6036                         }
6037                         cur = cur[dir];
6038                 }
6039                 return matched;
6040         },
6041
6042         nth: function( cur, result, dir, elem ) {
6043                 result = result || 1;
6044                 var num = 0;
6045
6046                 for ( ; cur; cur = cur[dir] ) {
6047                         if ( cur.nodeType === 1 && ++num === result ) {
6048                                 break;
6049                         }
6050                 }
6051
6052                 return cur;
6053         },
6054
6055         sibling: function( n, elem ) {
6056                 var r = [];
6057
6058                 for ( ; n; n = n.nextSibling ) {
6059                         if ( n.nodeType === 1 && n !== elem ) {
6060                                 r.push( n );
6061                         }
6062                 }
6063
6064                 return r;
6065         }
6066 });
6067
6068 // Implement the identical functionality for filter and not
6069 function winnow( elements, qualifier, keep ) {
6070
6071         // Can't pass null or undefined to indexOf in Firefox 4
6072         // Set to 0 to skip string check
6073         qualifier = qualifier || 0;
6074
6075         if ( jQuery.isFunction( qualifier ) ) {
6076                 return jQuery.grep(elements, function( elem, i ) {
6077                         var retVal = !!qualifier.call( elem, i, elem );
6078                         return retVal === keep;
6079                 });
6080
6081         } else if ( qualifier.nodeType ) {
6082                 return jQuery.grep(elements, function( elem, i ) {
6083                         return (elem === qualifier) === keep;
6084                 });
6085
6086         } else if ( typeof qualifier === "string" ) {
6087                 var filtered = jQuery.grep(elements, function( elem ) {
6088                         return elem.nodeType === 1;
6089                 });
6090
6091                 if ( isSimple.test( qualifier ) ) {
6092                         return jQuery.filter(qualifier, filtered, !keep);
6093                 } else {
6094                         qualifier = jQuery.filter( qualifier, filtered );
6095                 }
6096         }
6097
6098         return jQuery.grep(elements, function( elem, i ) {
6099                 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
6100         });
6101 }
6102
6103
6104
6105
6106 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
6107         rleadingWhitespace = /^\s+/,
6108         rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
6109         rtagName = /<([\w:]+)/,
6110         rtbody = /<tbody/i,
6111         rhtml = /<|&#?\w+;/,
6112         rnocache = /<(?:script|object|embed|option|style)/i,
6113         // checked="checked" or checked
6114         rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
6115         rscriptType = /\/(java|ecma)script/i,
6116         wrapMap = {
6117                 option: [ 1, "<select multiple='multiple'>", "</select>" ],
6118                 legend: [ 1, "<fieldset>", "</fieldset>" ],
6119                 thead: [ 1, "<table>", "</table>" ],
6120                 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
6121                 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
6122                 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
6123                 area: [ 1, "<map>", "</map>" ],
6124                 _default: [ 0, "", "" ]
6125         };
6126
6127 wrapMap.optgroup = wrapMap.option;
6128 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
6129 wrapMap.th = wrapMap.td;
6130
6131 // IE can't serialize <link> and <script> tags normally
6132 if ( !jQuery.support.htmlSerialize ) {
6133         wrapMap._default = [ 1, "div<div>", "</div>" ];
6134 }
6135
6136 jQuery.fn.extend({
6137         text: function( text ) {
6138                 if ( jQuery.isFunction(text) ) {
6139                         return this.each(function(i) {
6140                                 var self = jQuery( this );
6141
6142                                 self.text( text.call(this, i, self.text()) );
6143                         });
6144                 }
6145
6146                 if ( typeof text !== "object" && text !== undefined ) {
6147                         return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
6148                 }
6149
6150                 return jQuery.text( this );
6151         },
6152
6153         wrapAll: function( html ) {
6154                 if ( jQuery.isFunction( html ) ) {
6155                         return this.each(function(i) {
6156                                 jQuery(this).wrapAll( html.call(this, i) );
6157                         });
6158                 }
6159
6160                 if ( this[0] ) {
6161                         // The elements to wrap the target around
6162                         var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
6163
6164                         if ( this[0].parentNode ) {
6165                                 wrap.insertBefore( this[0] );
6166                         }
6167
6168                         wrap.map(function() {
6169                                 var elem = this;
6170
6171                                 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
6172                                         elem = elem.firstChild;
6173                                 }
6174
6175                                 return elem;
6176                         }).append( this );
6177                 }
6178
6179                 return this;
6180         },
6181
6182         wrapInner: function( html ) {
6183                 if ( jQuery.isFunction( html ) ) {
6184                         return this.each(function(i) {
6185                                 jQuery(this).wrapInner( html.call(this, i) );
6186                         });
6187                 }
6188
6189                 return this.each(function() {
6190                         var self = jQuery( this ),
6191                                 contents = self.contents();
6192
6193                         if ( contents.length ) {
6194                                 contents.wrapAll( html );
6195
6196                         } else {
6197                                 self.append( html );
6198                         }
6199                 });
6200         },
6201
6202         wrap: function( html ) {
6203                 return this.each(function() {
6204                         jQuery( this ).wrapAll( html );
6205                 });
6206         },
6207
6208         unwrap: function() {
6209                 return this.parent().each(function() {
6210                         if ( !jQuery.nodeName( this, "body" ) ) {
6211                                 jQuery( this ).replaceWith( this.childNodes );
6212                         }
6213                 }).end();
6214         },
6215
6216         append: function() {
6217                 return this.domManip(arguments, true, function( elem ) {
6218                         if ( this.nodeType === 1 ) {
6219                                 this.appendChild( elem );
6220                         }
6221                 });
6222         },
6223
6224         prepend: function() {
6225                 return this.domManip(arguments, true, function( elem ) {
6226                         if ( this.nodeType === 1 ) {
6227                                 this.insertBefore( elem, this.firstChild );
6228                         }
6229                 });
6230         },
6231
6232         before: function() {
6233                 if ( this[0] && this[0].parentNode ) {
6234                         return this.domManip(arguments, false, function( elem ) {
6235                                 this.parentNode.insertBefore( elem, this );
6236                         });
6237                 } else if ( arguments.length ) {
6238                         var set = jQuery(arguments[0]);
6239                         set.push.apply( set, this.toArray() );
6240                         return this.pushStack( set, "before", arguments );
6241                 }
6242         },
6243
6244         after: function() {
6245                 if ( this[0] && this[0].parentNode ) {
6246                         return this.domManip(arguments, false, function( elem ) {
6247                                 this.parentNode.insertBefore( elem, this.nextSibling );
6248                         });
6249                 } else if ( arguments.length ) {
6250                         var set = this.pushStack( this, "after", arguments );
6251                         set.push.apply( set, jQuery(arguments[0]).toArray() );
6252                         return set;
6253                 }
6254         },
6255
6256         // keepData is for internal use only--do not document
6257         remove: function( selector, keepData ) {
6258                 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
6259                         if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
6260                                 if ( !keepData && elem.nodeType === 1 ) {
6261                                         jQuery.cleanData( elem.getElementsByTagName("*") );
6262                                         jQuery.cleanData( [ elem ] );
6263                                 }
6264
6265                                 if ( elem.parentNode ) {
6266                                         elem.parentNode.removeChild( elem );
6267                                 }
6268                         }
6269                 }
6270
6271                 return this;
6272         },
6273
6274         empty: function() {
6275                 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
6276                         // Remove element nodes and prevent memory leaks
6277                         if ( elem.nodeType === 1 ) {
6278                                 jQuery.cleanData( elem.getElementsByTagName("*") );
6279                         }
6280
6281                         // Remove any remaining nodes
6282                         while ( elem.firstChild ) {
6283                                 elem.removeChild( elem.firstChild );
6284                         }
6285                 }
6286
6287                 return this;
6288         },
6289
6290         clone: function( dataAndEvents, deepDataAndEvents ) {
6291                 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6292                 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6293
6294                 return this.map( function () {
6295                         return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6296                 });
6297         },
6298
6299         html: function( value ) {
6300                 if ( value === undefined ) {
6301                         return this[0] && this[0].nodeType === 1 ?
6302                                 this[0].innerHTML.replace(rinlinejQuery, "") :
6303                                 null;
6304
6305                 // See if we can take a shortcut and just use innerHTML
6306                 } else if ( typeof value === "string" && !rnocache.test( value ) &&
6307                         (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
6308                         !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
6309
6310                         value = value.replace(rxhtmlTag, "<$1></$2>");
6311
6312                         try {
6313                                 for ( var i = 0, l = this.length; i < l; i++ ) {
6314                                         // Remove element nodes and prevent memory leaks
6315                                         if ( this[i].nodeType === 1 ) {
6316                                                 jQuery.cleanData( this[i].getElementsByTagName("*") );
6317                                                 this[i].innerHTML = value;
6318                                         }
6319                                 }
6320
6321                         // If using innerHTML throws an exception, use the fallback method
6322                         } catch(e) {
6323                                 this.empty().append( value );
6324                         }
6325
6326                 } else if ( jQuery.isFunction( value ) ) {
6327                         this.each(function(i){
6328                                 var self = jQuery( this );
6329
6330                                 self.html( value.call(this, i, self.html()) );
6331                         });
6332
6333                 } else {
6334                         this.empty().append( value );
6335                 }
6336
6337                 return this;
6338         },
6339
6340         replaceWith: function( value ) {
6341                 if ( this[0] && this[0].parentNode ) {
6342                         // Make sure that the elements are removed from the DOM before they are inserted
6343                         // this can help fix replacing a parent with child elements
6344                         if ( jQuery.isFunction( value ) ) {
6345                                 return this.each(function(i) {
6346                                         var self = jQuery(this), old = self.html();
6347                                         self.replaceWith( value.call( this, i, old ) );
6348                                 });
6349                         }
6350
6351                         if ( typeof value !== "string" ) {
6352                                 value = jQuery( value ).detach();
6353                         }
6354
6355                         return this.each(function() {
6356                                 var next = this.nextSibling,
6357                                         parent = this.parentNode;
6358
6359                                 jQuery( this ).remove();
6360
6361                                 if ( next ) {
6362                                         jQuery(next).before( value );
6363                                 } else {
6364                                         jQuery(parent).append( value );
6365                                 }
6366                         });
6367                 } else {
6368                         return this.length ?
6369                                 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
6370                                 this;
6371                 }
6372         },
6373
6374         detach: function( selector ) {
6375                 return this.remove( selector, true );
6376         },
6377
6378         domManip: function( args, table, callback ) {
6379                 var results, first, fragment, parent,
6380                         value = args[0],
6381                         scripts = [];
6382
6383                 // We can't cloneNode fragments that contain checked, in WebKit
6384                 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
6385                         return this.each(function() {
6386                                 jQuery(this).domManip( args, table, callback, true );
6387                         });
6388                 }
6389
6390                 if ( jQuery.isFunction(value) ) {
6391                         return this.each(function(i) {
6392                                 var self = jQuery(this);
6393                                 args[0] = value.call(this, i, table ? self.html() : undefined);
6394                                 self.domManip( args, table, callback );
6395                         });
6396                 }
6397
6398                 if ( this[0] ) {
6399                         parent = value && value.parentNode;
6400
6401                         // If we're in a fragment, just use that instead of building a new one
6402                         if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
6403                                 results = { fragment: parent };
6404
6405                         } else {
6406                                 results = jQuery.buildFragment( args, this, scripts );
6407                         }
6408
6409                         fragment = results.fragment;
6410
6411                         if ( fragment.childNodes.length === 1 ) {
6412                                 first = fragment = fragment.firstChild;
6413                         } else {
6414                                 first = fragment.firstChild;
6415                         }
6416
6417                         if ( first ) {
6418                                 table = table && jQuery.nodeName( first, "tr" );
6419
6420                                 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
6421                                         callback.call(
6422                                                 table ?
6423                                                         root(this[i], first) :
6424                                                         this[i],
6425                                                 // Make sure that we do not leak memory by inadvertently discarding
6426                                                 // the original fragment (which might have attached data) instead of
6427                                                 // using it; in addition, use the original fragment object for the last
6428                                                 // item instead of first because it can end up being emptied incorrectly
6429                                                 // in certain situations (Bug #8070).
6430                                                 // Fragments from the fragment cache must always be cloned and never used
6431                                                 // in place.
6432                                                 results.cacheable || (l > 1 && i < lastIndex) ?
6433                                                         jQuery.clone( fragment, true, true ) :
6434                                                         fragment
6435                                         );
6436                                 }
6437                         }
6438
6439                         if ( scripts.length ) {
6440                                 jQuery.each( scripts, evalScript );
6441                         }
6442                 }
6443
6444                 return this;
6445         }
6446 });
6447
6448 function root( elem, cur ) {
6449         return jQuery.nodeName(elem, "table") ?
6450                 (elem.getElementsByTagName("tbody")[0] ||
6451                 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
6452                 elem;
6453 }
6454
6455 function cloneCopyEvent( src, dest ) {
6456
6457         if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
6458                 return;
6459         }
6460
6461         var internalKey = jQuery.expando,
6462                 oldData = jQuery.data( src ),
6463                 curData = jQuery.data( dest, oldData );
6464
6465         // Switch to use the internal data object, if it exists, for the next
6466         // stage of data copying
6467         if ( (oldData = oldData[ internalKey ]) ) {
6468                 var events = oldData.events;
6469                                 curData = curData[ internalKey ] = jQuery.extend({}, oldData);
6470
6471                 if ( events ) {
6472                         delete curData.handle;
6473                         curData.events = {};
6474
6475                         for ( var type in events ) {
6476                                 for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
6477                                         jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
6478                                 }
6479                         }
6480                 }
6481         }
6482 }
6483
6484 function cloneFixAttributes( src, dest ) {
6485         var nodeName;
6486
6487         // We do not need to do anything for non-Elements
6488         if ( dest.nodeType !== 1 ) {
6489                 return;
6490         }
6491
6492         // clearAttributes removes the attributes, which we don't want,
6493         // but also removes the attachEvent events, which we *do* want
6494         if ( dest.clearAttributes ) {
6495                 dest.clearAttributes();
6496         }
6497
6498         // mergeAttributes, in contrast, only merges back on the
6499         // original attributes, not the events
6500         if ( dest.mergeAttributes ) {
6501                 dest.mergeAttributes( src );
6502         }
6503
6504         nodeName = dest.nodeName.toLowerCase();
6505
6506         // IE6-8 fail to clone children inside object elements that use
6507         // the proprietary classid attribute value (rather than the type
6508         // attribute) to identify the type of content to display
6509         if ( nodeName === "object" ) {
6510                 dest.outerHTML = src.outerHTML;
6511
6512         } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
6513                 // IE6-8 fails to persist the checked state of a cloned checkbox
6514                 // or radio button. Worse, IE6-7 fail to give the cloned element
6515                 // a checked appearance if the defaultChecked value isn't also set
6516                 if ( src.checked ) {
6517                         dest.defaultChecked = dest.checked = src.checked;
6518                 }
6519
6520                 // IE6-7 get confused and end up setting the value of a cloned
6521                 // checkbox/radio button to an empty string instead of "on"
6522                 if ( dest.value !== src.value ) {
6523                         dest.value = src.value;
6524                 }
6525
6526         // IE6-8 fails to return the selected option to the default selected
6527         // state when cloning options
6528         } else if ( nodeName === "option" ) {
6529                 dest.selected = src.defaultSelected;
6530
6531         // IE6-8 fails to set the defaultValue to the correct value when
6532         // cloning other types of input fields
6533         } else if ( nodeName === "input" || nodeName === "textarea" ) {
6534                 dest.defaultValue = src.defaultValue;
6535         }
6536
6537         // Event data gets referenced instead of copied if the expando
6538         // gets copied too
6539         dest.removeAttribute( jQuery.expando );
6540 }
6541
6542 jQuery.buildFragment = function( args, nodes, scripts ) {
6543         var fragment, cacheable, cacheresults,
6544                 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
6545
6546         // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6547         // Cloning options loses the selected state, so don't cache them
6548         // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6549         // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6550         if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
6551                 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
6552
6553                 cacheable = true;
6554
6555                 cacheresults = jQuery.fragments[ args[0] ];
6556                 if ( cacheresults && cacheresults !== 1 ) {
6557                         fragment = cacheresults;
6558                 }
6559         }
6560
6561         if ( !fragment ) {
6562                 fragment = doc.createDocumentFragment();
6563                 jQuery.clean( args, doc, fragment, scripts );
6564         }
6565
6566         if ( cacheable ) {
6567                 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
6568         }
6569
6570         return { fragment: fragment, cacheable: cacheable };
6571 };
6572
6573 jQuery.fragments = {};
6574
6575 jQuery.each({
6576         appendTo: "append",
6577         prependTo: "prepend",
6578         insertBefore: "before",
6579         insertAfter: "after",
6580         replaceAll: "replaceWith"
6581 }, function( name, original ) {
6582         jQuery.fn[ name ] = function( selector ) {
6583                 var ret = [],
6584                         insert = jQuery( selector ),
6585                         parent = this.length === 1 && this[0].parentNode;
6586
6587                 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
6588                         insert[ original ]( this[0] );
6589                         return this;
6590
6591                 } else {
6592                         for ( var i = 0, l = insert.length; i < l; i++ ) {
6593                                 var elems = (i > 0 ? this.clone(true) : this).get();
6594                                 jQuery( insert[i] )[ original ]( elems );
6595                                 ret = ret.concat( elems );
6596                         }
6597
6598                         return this.pushStack( ret, name, insert.selector );
6599                 }
6600         };
6601 });
6602
6603 function getAll( elem ) {
6604         if ( "getElementsByTagName" in elem ) {
6605                 return elem.getElementsByTagName( "*" );
6606         
6607         } else if ( "querySelectorAll" in elem ) {
6608                 return elem.querySelectorAll( "*" );
6609
6610         } else {
6611                 return [];
6612         }
6613 }
6614
6615 // Used in clean, fixes the defaultChecked property
6616 function fixDefaultChecked( elem ) {
6617         if ( elem.type === "checkbox" || elem.type === "radio" ) {
6618                 elem.defaultChecked = elem.checked;
6619         }
6620 }
6621 // Finds all inputs and passes them to fixDefaultChecked
6622 function findInputs( elem ) {
6623         if ( jQuery.nodeName( elem, "input" ) ) {
6624                 fixDefaultChecked( elem );
6625         } else if ( elem.getElementsByTagName ) {
6626                 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6627         }
6628 }
6629
6630 jQuery.extend({
6631         clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6632                 var clone = elem.cloneNode(true),
6633                                 srcElements,
6634                                 destElements,
6635                                 i;
6636
6637                 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6638                                 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6639                         // IE copies events bound via attachEvent when using cloneNode.
6640                         // Calling detachEvent on the clone will also remove the events
6641                         // from the original. In order to get around this, we use some
6642                         // proprietary methods to clear the events. Thanks to MooTools
6643                         // guys for this hotness.
6644
6645                         cloneFixAttributes( elem, clone );
6646
6647                         // Using Sizzle here is crazy slow, so we use getElementsByTagName
6648                         // instead
6649                         srcElements = getAll( elem );
6650                         destElements = getAll( clone );
6651
6652                         // Weird iteration because IE will replace the length property
6653                         // with an element if you are cloning the body and one of the
6654                         // elements on the page has a name or id of "length"
6655                         for ( i = 0; srcElements[i]; ++i ) {
6656                                 cloneFixAttributes( srcElements[i], destElements[i] );
6657                         }
6658                 }
6659
6660                 // Copy the events from the original to the clone
6661                 if ( dataAndEvents ) {
6662                         cloneCopyEvent( elem, clone );
6663
6664                         if ( deepDataAndEvents ) {
6665                                 srcElements = getAll( elem );
6666                                 destElements = getAll( clone );
6667
6668                                 for ( i = 0; srcElements[i]; ++i ) {
6669                                         cloneCopyEvent( srcElements[i], destElements[i] );
6670                                 }
6671                         }
6672                 }
6673
6674                 // Return the cloned set
6675                 return clone;
6676         },
6677
6678         clean: function( elems, context, fragment, scripts ) {
6679                 var checkScriptType;
6680
6681                 context = context || document;
6682
6683                 // !context.createElement fails in IE with an error but returns typeof 'object'
6684                 if ( typeof context.createElement === "undefined" ) {
6685                         context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6686                 }
6687
6688                 var ret = [];
6689
6690                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6691                         if ( typeof elem === "number" ) {
6692                                 elem += "";
6693                         }
6694
6695                         if ( !elem ) {
6696                                 continue;
6697                         }
6698
6699                         // Convert html string into DOM nodes
6700                         if ( typeof elem === "string" ) {
6701                                 if ( !rhtml.test( elem ) ) {
6702                                         elem = context.createTextNode( elem );
6703                                 } else {
6704                                         // Fix "XHTML"-style tags in all browsers
6705                                         elem = elem.replace(rxhtmlTag, "<$1></$2>");
6706
6707                                         // Trim whitespace, otherwise indexOf won't work as expected
6708                                         var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
6709                                                 wrap = wrapMap[ tag ] || wrapMap._default,
6710                                                 depth = wrap[0],
6711                                                 div = context.createElement("div");
6712
6713                                         // Go to html and back, then peel off extra wrappers
6714                                         div.innerHTML = wrap[1] + elem + wrap[2];
6715
6716                                         // Move to the right depth
6717                                         while ( depth-- ) {
6718                                                 div = div.lastChild;
6719                                         }
6720
6721                                         // Remove IE's autoinserted <tbody> from table fragments
6722                                         if ( !jQuery.support.tbody ) {
6723
6724                                                 // String was a <table>, *may* have spurious <tbody>
6725                                                 var hasBody = rtbody.test(elem),
6726                                                         tbody = tag === "table" && !hasBody ?
6727                                                                 div.firstChild && div.firstChild.childNodes :
6728
6729                                                                 // String was a bare <thead> or <tfoot>
6730                                                                 wrap[1] === "<table>" && !hasBody ?
6731                                                                         div.childNodes :
6732                                                                         [];
6733
6734                                                 for ( var j = tbody.length - 1; j >= 0 ; --j ) {
6735                                                         if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6736                                                                 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6737                                                         }
6738                                                 }
6739                                         }
6740
6741                                         // IE completely kills leading whitespace when innerHTML is used
6742                                         if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6743                                                 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6744                                         }
6745
6746                                         elem = div.childNodes;
6747                                 }
6748                         }
6749
6750                         // Resets defaultChecked for any radios and checkboxes
6751                         // about to be appended to the DOM in IE 6/7 (#8060)
6752                         var len;
6753                         if ( !jQuery.support.appendChecked ) {
6754                                 if ( elem[0] && typeof (len = elem.length) === "number" ) {
6755                                         for ( i = 0; i < len; i++ ) {
6756                                                 findInputs( elem[i] );
6757                                         }
6758                                 } else {
6759                                         findInputs( elem );
6760                                 }
6761                         }
6762
6763                         if ( elem.nodeType ) {
6764                                 ret.push( elem );
6765                         } else {
6766                                 ret = jQuery.merge( ret, elem );
6767                         }
6768                 }
6769
6770                 if ( fragment ) {
6771                         checkScriptType = function( elem ) {
6772                                 return !elem.type || rscriptType.test( elem.type );
6773                         };
6774                         for ( i = 0; ret[i]; i++ ) {
6775                                 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6776                                         scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6777
6778                                 } else {
6779                                         if ( ret[i].nodeType === 1 ) {
6780                                                 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6781
6782                                                 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6783                                         }
6784                                         fragment.appendChild( ret[i] );
6785                                 }
6786                         }
6787                 }
6788
6789                 return ret;
6790         },
6791
6792         cleanData: function( elems ) {
6793                 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6794                         deleteExpando = jQuery.support.deleteExpando;
6795
6796                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6797                         if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6798                                 continue;
6799                         }
6800
6801                         id = elem[ jQuery.expando ];
6802
6803                         if ( id ) {
6804                                 data = cache[ id ] && cache[ id ][ internalKey ];
6805
6806                                 if ( data && data.events ) {
6807                                         for ( var type in data.events ) {
6808                                                 if ( special[ type ] ) {
6809                                                         jQuery.event.remove( elem, type );
6810
6811                                                 // This is a shortcut to avoid jQuery.event.remove's overhead
6812                                                 } else {
6813                                                         jQuery.removeEvent( elem, type, data.handle );
6814                                                 }
6815                                         }
6816
6817                                         // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6818                                         if ( data.handle ) {
6819                                                 data.handle.elem = null;
6820                                         }
6821                                 }
6822
6823                                 if ( deleteExpando ) {
6824                                         delete elem[ jQuery.expando ];
6825
6826                                 } else if ( elem.removeAttribute ) {
6827                                         elem.removeAttribute( jQuery.expando );
6828                                 }
6829
6830                                 delete cache[ id ];
6831                         }
6832                 }
6833         }
6834 });
6835
6836 function evalScript( i, elem ) {
6837         if ( elem.src ) {
6838                 jQuery.ajax({
6839                         url: elem.src,
6840                         async: false,
6841                         dataType: "script"
6842                 });
6843         } else {
6844                 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
6845         }
6846
6847         if ( elem.parentNode ) {
6848                 elem.parentNode.removeChild( elem );
6849         }
6850 }
6851
6852
6853
6854
6855 var ralpha = /alpha\([^)]*\)/i,
6856         ropacity = /opacity=([^)]*)/,
6857         rdashAlpha = /-([a-z])/ig,
6858         // fixed for IE9, see #8346
6859         rupper = /([A-Z]|^ms)/g,
6860         rnumpx = /^-?\d+(?:px)?$/i,
6861         rnum = /^-?\d/,
6862         rrelNum = /^[+\-]=/,
6863         rrelNumFilter = /[^+\-\.\de]+/g,
6864
6865         cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6866         cssWidth = [ "Left", "Right" ],
6867         cssHeight = [ "Top", "Bottom" ],
6868         curCSS,
6869
6870         getComputedStyle,
6871         currentStyle,
6872
6873         fcamelCase = function( all, letter ) {
6874                 return letter.toUpperCase();
6875         };
6876
6877 jQuery.fn.css = function( name, value ) {
6878         // Setting 'undefined' is a no-op
6879         if ( arguments.length === 2 && value === undefined ) {
6880                 return this;
6881         }
6882
6883         return jQuery.access( this, name, value, true, function( elem, name, value ) {
6884                 return value !== undefined ?
6885                         jQuery.style( elem, name, value ) :
6886                         jQuery.css( elem, name );
6887         });
6888 };
6889
6890 jQuery.extend({
6891         // Add in style property hooks for overriding the default
6892         // behavior of getting and setting a style property
6893         cssHooks: {
6894                 opacity: {
6895                         get: function( elem, computed ) {
6896                                 if ( computed ) {
6897                                         // We should always get a number back from opacity
6898                                         var ret = curCSS( elem, "opacity", "opacity" );
6899                                         return ret === "" ? "1" : ret;
6900
6901                                 } else {
6902                                         return elem.style.opacity;
6903                                 }
6904                         }
6905                 }
6906         },
6907
6908         // Exclude the following css properties to add px
6909         cssNumber: {
6910                 "zIndex": true,
6911                 "fontWeight": true,
6912                 "opacity": true,
6913                 "zoom": true,
6914                 "lineHeight": true,
6915                 "widows": true,
6916                 "orphans": true
6917         },
6918
6919         // Add in properties whose names you wish to fix before
6920         // setting or getting the value
6921         cssProps: {
6922                 // normalize float css property
6923                 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6924         },
6925
6926         // Get and set the style property on a DOM Node
6927         style: function( elem, name, value, extra ) {
6928                 // Don't set styles on text and comment nodes
6929                 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6930                         return;
6931                 }
6932
6933                 // Make sure that we're working with the right name
6934                 var ret, type, origName = jQuery.camelCase( name ),
6935                         style = elem.style, hooks = jQuery.cssHooks[ origName ];
6936
6937                 name = jQuery.cssProps[ origName ] || origName;
6938
6939                 // Check if we're setting a value
6940                 if ( value !== undefined ) {
6941                         type = typeof value;
6942
6943                         // Make sure that NaN and null values aren't set. See: #7116
6944                         if ( type === "number" && isNaN( value ) || value == null ) {
6945                                 return;
6946                         }
6947
6948                         // convert relative number strings (+= or -=) to relative numbers. #7345
6949                         if ( type === "string" && rrelNum.test( value ) ) {
6950                                 value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
6951                         }
6952
6953                         // If a number was passed in, add 'px' to the (except for certain CSS properties)
6954                         if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6955                                 value += "px";
6956                         }
6957
6958                         // If a hook was provided, use that value, otherwise just set the specified value
6959                         if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6960                                 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6961                                 // Fixes bug #5509
6962                                 try {
6963                                         style[ name ] = value;
6964                                 } catch(e) {}
6965                         }
6966
6967                 } else {
6968                         // If a hook was provided get the non-computed value from there
6969                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6970                                 return ret;
6971                         }
6972
6973                         // Otherwise just get the value from the style object
6974                         return style[ name ];
6975                 }
6976         },
6977
6978         css: function( elem, name, extra ) {
6979                 var ret, hooks;
6980
6981                 // Make sure that we're working with the right name
6982                 name = jQuery.camelCase( name );
6983                 hooks = jQuery.cssHooks[ name ];
6984                 name = jQuery.cssProps[ name ] || name;
6985
6986                 // cssFloat needs a special treatment
6987                 if ( name === "cssFloat" ) {
6988                         name = "float";
6989                 }
6990
6991                 // If a hook was provided get the computed value from there
6992                 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6993                         return ret;
6994
6995                 // Otherwise, if a way to get the computed value exists, use that
6996                 } else if ( curCSS ) {
6997                         return curCSS( elem, name );
6998                 }
6999         },
7000
7001         // A method for quickly swapping in/out CSS properties to get correct calculations
7002         swap: function( elem, options, callback ) {
7003                 var old = {};
7004
7005                 // Remember the old values, and insert the new ones
7006                 for ( var name in options ) {
7007                         old[ name ] = elem.style[ name ];
7008                         elem.style[ name ] = options[ name ];
7009                 }
7010
7011                 callback.call( elem );
7012
7013                 // Revert the old values
7014                 for ( name in options ) {
7015                         elem.style[ name ] = old[ name ];
7016                 }
7017         },
7018
7019         camelCase: function( string ) {
7020                 return string.replace( rdashAlpha, fcamelCase );
7021         }
7022 });
7023
7024 // DEPRECATED, Use jQuery.css() instead
7025 jQuery.curCSS = jQuery.css;
7026
7027 jQuery.each(["height", "width"], function( i, name ) {
7028         jQuery.cssHooks[ name ] = {
7029                 get: function( elem, computed, extra ) {
7030                         var val;
7031
7032                         if ( computed ) {
7033                                 if ( elem.offsetWidth !== 0 ) {
7034                                         val = getWH( elem, name, extra );
7035
7036                                 } else {
7037                                         jQuery.swap( elem, cssShow, function() {
7038                                                 val = getWH( elem, name, extra );
7039                                         });
7040                                 }
7041
7042                                 if ( val <= 0 ) {
7043                                         val = curCSS( elem, name, name );
7044
7045                                         if ( val === "0px" && currentStyle ) {
7046                                                 val = currentStyle( elem, name, name );
7047                                         }
7048
7049                                         if ( val != null ) {
7050                                                 // Should return "auto" instead of 0, use 0 for
7051                                                 // temporary backwards-compat
7052                                                 return val === "" || val === "auto" ? "0px" : val;
7053                                         }
7054                                 }
7055
7056                                 if ( val < 0 || val == null ) {
7057                                         val = elem.style[ name ];
7058
7059                                         // Should return "auto" instead of 0, use 0 for
7060                                         // temporary backwards-compat
7061                                         return val === "" || val === "auto" ? "0px" : val;
7062                                 }
7063
7064                                 return typeof val === "string" ? val : val + "px";
7065                         }
7066                 },
7067
7068                 set: function( elem, value ) {
7069                         if ( rnumpx.test( value ) ) {
7070                                 // ignore negative width and height values #1599
7071                                 value = parseFloat(value);
7072
7073                                 if ( value >= 0 ) {
7074                                         return value + "px";
7075                                 }
7076
7077                         } else {
7078                                 return value;
7079                         }
7080                 }
7081         };
7082 });
7083
7084 if ( !jQuery.support.opacity ) {
7085         jQuery.cssHooks.opacity = {
7086                 get: function( elem, computed ) {
7087                         // IE uses filters for opacity
7088                         return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
7089                                 ( parseFloat( RegExp.$1 ) / 100 ) + "" :
7090                                 computed ? "1" : "";
7091                 },
7092
7093                 set: function( elem, value ) {
7094                         var style = elem.style,
7095                                 currentStyle = elem.currentStyle;
7096
7097                         // IE has trouble with opacity if it does not have layout
7098                         // Force it by setting the zoom level
7099                         style.zoom = 1;
7100
7101                         // Set the alpha filter to set the opacity
7102                         var opacity = jQuery.isNaN( value ) ?
7103                                 "" :
7104                                 "alpha(opacity=" + value * 100 + ")",
7105                                 filter = currentStyle && currentStyle.filter || style.filter || "";
7106
7107                         style.filter = ralpha.test( filter ) ?
7108                                 filter.replace( ralpha, opacity ) :
7109                                 filter + " " + opacity;
7110                 }
7111         };
7112 }
7113
7114 jQuery(function() {
7115         // This hook cannot be added until DOM ready because the support test
7116         // for it is not run until after DOM ready
7117         if ( !jQuery.support.reliableMarginRight ) {
7118                 jQuery.cssHooks.marginRight = {
7119                         get: function( elem, computed ) {
7120                                 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
7121                                 // Work around by temporarily setting element display to inline-block
7122                                 var ret;
7123                                 jQuery.swap( elem, { "display": "inline-block" }, function() {
7124                                         if ( computed ) {
7125                                                 ret = curCSS( elem, "margin-right", "marginRight" );
7126                                         } else {
7127                                                 ret = elem.style.marginRight;
7128                                         }
7129                                 });
7130                                 return ret;
7131                         }
7132                 };
7133         }
7134 });
7135
7136 if ( document.defaultView && document.defaultView.getComputedStyle ) {
7137         getComputedStyle = function( elem, name ) {
7138                 var ret, defaultView, computedStyle;
7139
7140                 name = name.replace( rupper, "-$1" ).toLowerCase();
7141
7142                 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
7143                         return undefined;
7144                 }
7145
7146                 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
7147                         ret = computedStyle.getPropertyValue( name );
7148                         if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
7149                                 ret = jQuery.style( elem, name );
7150                         }
7151                 }
7152
7153                 return ret;
7154         };
7155 }
7156
7157 if ( document.documentElement.currentStyle ) {
7158         currentStyle = function( elem, name ) {
7159                 var left,
7160                         ret = elem.currentStyle && elem.currentStyle[ name ],
7161                         rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
7162                         style = elem.style;
7163
7164                 // From the awesome hack by Dean Edwards
7165                 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
7166
7167                 // If we're not dealing with a regular pixel number
7168                 // but a number that has a weird ending, we need to convert it to pixels
7169                 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
7170                         // Remember the original values
7171                         left = style.left;
7172
7173                         // Put in the new values to get a computed value out
7174                         if ( rsLeft ) {
7175                                 elem.runtimeStyle.left = elem.currentStyle.left;
7176                         }
7177                         style.left = name === "fontSize" ? "1em" : (ret || 0);
7178                         ret = style.pixelLeft + "px";
7179
7180                         // Revert the changed values
7181                         style.left = left;
7182                         if ( rsLeft ) {
7183                                 elem.runtimeStyle.left = rsLeft;
7184                         }
7185                 }
7186
7187                 return ret === "" ? "auto" : ret;
7188         };
7189 }
7190
7191 curCSS = getComputedStyle || currentStyle;
7192
7193 function getWH( elem, name, extra ) {
7194         var which = name === "width" ? cssWidth : cssHeight,
7195                 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
7196
7197         if ( extra === "border" ) {
7198                 return val;
7199         }
7200
7201         jQuery.each( which, function() {
7202                 if ( !extra ) {
7203                         val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
7204                 }
7205
7206                 if ( extra === "margin" ) {
7207                         val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
7208
7209                 } else {
7210                         val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
7211                 }
7212         });
7213
7214         return val;
7215 }
7216
7217 if ( jQuery.expr && jQuery.expr.filters ) {
7218         jQuery.expr.filters.hidden = function( elem ) {
7219                 var width = elem.offsetWidth,
7220                         height = elem.offsetHeight;
7221
7222                 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
7223         };
7224
7225         jQuery.expr.filters.visible = function( elem ) {
7226                 return !jQuery.expr.filters.hidden( elem );
7227         };
7228 }
7229
7230
7231
7232
7233 var r20 = /%20/g,
7234         rbracket = /\[\]$/,
7235         rCRLF = /\r?\n/g,
7236         rhash = /#.*$/,
7237         rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
7238         rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
7239         // #7653, #8125, #8152: local protocol detection
7240         rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
7241         rnoContent = /^(?:GET|HEAD)$/,
7242         rprotocol = /^\/\//,
7243         rquery = /\?/,
7244         rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
7245         rselectTextarea = /^(?:select|textarea)/i,
7246         rspacesAjax = /\s+/,
7247         rts = /([?&])_=[^&]*/,
7248         rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
7249
7250         // Keep a copy of the old load method
7251         _load = jQuery.fn.load,
7252
7253         /* Prefilters
7254          * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
7255          * 2) These are called:
7256          *    - BEFORE asking for a transport
7257          *    - AFTER param serialization (s.data is a string if s.processData is true)
7258          * 3) key is the dataType
7259          * 4) the catchall symbol "*" can be used
7260          * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7261          */
7262         prefilters = {},
7263
7264         /* Transports bindings
7265          * 1) key is the dataType
7266          * 2) the catchall symbol "*" can be used
7267          * 3) selection will start with transport dataType and THEN go to "*" if needed
7268          */
7269         transports = {},
7270
7271         // Document location
7272         ajaxLocation,
7273
7274         // Document location segments
7275         ajaxLocParts;
7276
7277 // #8138, IE may throw an exception when accessing
7278 // a field from window.location if document.domain has been set
7279 try {
7280         ajaxLocation = location.href;
7281 } catch( e ) {
7282         // Use the href attribute of an A element
7283         // since IE will modify it given document.location
7284         ajaxLocation = document.createElement( "a" );
7285         ajaxLocation.href = "";
7286         ajaxLocation = ajaxLocation.href;
7287 }
7288
7289 // Segment location into parts
7290 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7291
7292 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7293 function addToPrefiltersOrTransports( structure ) {
7294
7295         // dataTypeExpression is optional and defaults to "*"
7296         return function( dataTypeExpression, func ) {
7297
7298                 if ( typeof dataTypeExpression !== "string" ) {
7299                         func = dataTypeExpression;
7300                         dataTypeExpression = "*";
7301                 }
7302
7303                 if ( jQuery.isFunction( func ) ) {
7304                         var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
7305                                 i = 0,
7306                                 length = dataTypes.length,
7307                                 dataType,
7308                                 list,
7309                                 placeBefore;
7310
7311                         // For each dataType in the dataTypeExpression
7312                         for(; i < length; i++ ) {
7313                                 dataType = dataTypes[ i ];
7314                                 // We control if we're asked to add before
7315                                 // any existing element
7316                                 placeBefore = /^\+/.test( dataType );
7317                                 if ( placeBefore ) {
7318                                         dataType = dataType.substr( 1 ) || "*";
7319                                 }
7320                                 list = structure[ dataType ] = structure[ dataType ] || [];
7321                                 // then we add to the structure accordingly
7322                                 list[ placeBefore ? "unshift" : "push" ]( func );
7323                         }
7324                 }
7325         };
7326 }
7327
7328 // Base inspection function for prefilters and transports
7329 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
7330                 dataType /* internal */, inspected /* internal */ ) {
7331
7332         dataType = dataType || options.dataTypes[ 0 ];
7333         inspected = inspected || {};
7334
7335         inspected[ dataType ] = true;
7336
7337         var list = structure[ dataType ],
7338                 i = 0,
7339                 length = list ? list.length : 0,
7340                 executeOnly = ( structure === prefilters ),
7341                 selection;
7342
7343         for(; i < length && ( executeOnly || !selection ); i++ ) {
7344                 selection = list[ i ]( options, originalOptions, jqXHR );
7345                 // If we got redirected to another dataType
7346                 // we try there if executing only and not done already
7347                 if ( typeof selection === "string" ) {
7348                         if ( !executeOnly || inspected[ selection ] ) {
7349                                 selection = undefined;
7350                         } else {
7351                                 options.dataTypes.unshift( selection );
7352                                 selection = inspectPrefiltersOrTransports(
7353                                                 structure, options, originalOptions, jqXHR, selection, inspected );
7354                         }
7355                 }
7356         }
7357         // If we're only executing or nothing was selected
7358         // we try the catchall dataType if not done already
7359         if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
7360                 selection = inspectPrefiltersOrTransports(
7361                                 structure, options, originalOptions, jqXHR, "*", inspected );
7362         }
7363         // unnecessary when only executing (prefilters)
7364         // but it'll be ignored by the caller in that case
7365         return selection;
7366 }
7367
7368 jQuery.fn.extend({
7369         load: function( url, params, callback ) {
7370                 if ( typeof url !== "string" && _load ) {
7371                         return _load.apply( this, arguments );
7372
7373                 // Don't do a request if no elements are being requested
7374                 } else if ( !this.length ) {
7375                         return this;
7376                 }
7377
7378                 var off = url.indexOf( " " );
7379                 if ( off >= 0 ) {
7380                         var selector = url.slice( off, url.length );
7381                         url = url.slice( 0, off );
7382                 }
7383
7384                 // Default to a GET request
7385                 var type = "GET";
7386
7387                 // If the second parameter was provided
7388                 if ( params ) {
7389                         // If it's a function
7390                         if ( jQuery.isFunction( params ) ) {
7391                                 // We assume that it's the callback
7392                                 callback = params;
7393                                 params = undefined;
7394
7395                         // Otherwise, build a param string
7396                         } else if ( typeof params === "object" ) {
7397                                 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
7398                                 type = "POST";
7399                         }
7400                 }
7401
7402                 var self = this;
7403
7404                 // Request the remote document
7405                 jQuery.ajax({
7406                         url: url,
7407                         type: type,
7408                         dataType: "html",
7409                         data: params,
7410                         // Complete callback (responseText is used internally)
7411                         complete: function( jqXHR, status, responseText ) {
7412                                 // Store the response as specified by the jqXHR object
7413                                 responseText = jqXHR.responseText;
7414                                 // If successful, inject the HTML into all the matched elements
7415                                 if ( jqXHR.isResolved() ) {
7416                                         // #4825: Get the actual response in case
7417                                         // a dataFilter is present in ajaxSettings
7418                                         jqXHR.done(function( r ) {
7419                                                 responseText = r;
7420                                         });
7421                                         // See if a selector was specified
7422                                         self.html( selector ?
7423                                                 // Create a dummy div to hold the results
7424                                                 jQuery("<div>")
7425                                                         // inject the contents of the document in, removing the scripts
7426                                                         // to avoid any 'Permission Denied' errors in IE
7427                                                         .append(responseText.replace(rscript, ""))
7428
7429                                                         // Locate the specified elements
7430                                                         .find(selector) :
7431
7432                                                 // If not, just inject the full result
7433                                                 responseText );
7434                                 }
7435
7436                                 if ( callback ) {
7437                                         self.each( callback, [ responseText, status, jqXHR ] );
7438                                 }
7439                         }
7440                 });
7441
7442                 return this;
7443         },
7444
7445         serialize: function() {
7446                 return jQuery.param( this.serializeArray() );
7447         },
7448
7449         serializeArray: function() {
7450                 return this.map(function(){
7451                         return this.elements ? jQuery.makeArray( this.elements ) : this;
7452                 })
7453                 .filter(function(){
7454                         return this.name && !this.disabled &&
7455                                 ( this.checked || rselectTextarea.test( this.nodeName ) ||
7456                                         rinput.test( this.type ) );
7457                 })
7458                 .map(function( i, elem ){
7459                         var val = jQuery( this ).val();
7460
7461                         return val == null ?
7462                                 null :
7463                                 jQuery.isArray( val ) ?
7464                                         jQuery.map( val, function( val, i ){
7465                                                 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7466                                         }) :
7467                                         { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7468                 }).get();
7469         }
7470 });
7471
7472 // Attach a bunch of functions for handling common AJAX events
7473 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7474         jQuery.fn[ o ] = function( f ){
7475                 return this.bind( o, f );
7476         };
7477 });
7478
7479 jQuery.each( [ "get", "post" ], function( i, method ) {
7480         jQuery[ method ] = function( url, data, callback, type ) {
7481                 // shift arguments if data argument was omitted
7482                 if ( jQuery.isFunction( data ) ) {
7483                         type = type || callback;
7484                         callback = data;
7485                         data = undefined;
7486                 }
7487
7488                 return jQuery.ajax({
7489                         type: method,
7490                         url: url,
7491                         data: data,
7492                         success: callback,
7493                         dataType: type
7494                 });
7495         };
7496 });
7497
7498 jQuery.extend({
7499
7500         getScript: function( url, callback ) {
7501                 return jQuery.get( url, undefined, callback, "script" );
7502         },
7503
7504         getJSON: function( url, data, callback ) {
7505                 return jQuery.get( url, data, callback, "json" );
7506         },
7507
7508         // Creates a full fledged settings object into target
7509         // with both ajaxSettings and settings fields.
7510         // If target is omitted, writes into ajaxSettings.
7511         ajaxSetup: function ( target, settings ) {
7512                 if ( !settings ) {
7513                         // Only one parameter, we extend ajaxSettings
7514                         settings = target;
7515                         target = jQuery.extend( true, jQuery.ajaxSettings, settings );
7516                 } else {
7517                         // target was provided, we extend into it
7518                         jQuery.extend( true, target, jQuery.ajaxSettings, settings );
7519                 }
7520                 // Flatten fields we don't want deep extended
7521                 for( var field in { context: 1, url: 1 } ) {
7522                         if ( field in settings ) {
7523                                 target[ field ] = settings[ field ];
7524                         } else if( field in jQuery.ajaxSettings ) {
7525                                 target[ field ] = jQuery.ajaxSettings[ field ];
7526                         }
7527                 }
7528                 return target;
7529         },
7530
7531         ajaxSettings: {
7532                 url: ajaxLocation,
7533                 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7534                 global: true,
7535                 type: "GET",
7536                 contentType: "application/x-www-form-urlencoded",
7537                 processData: true,
7538                 async: true,
7539                 /*
7540                 timeout: 0,
7541                 data: null,
7542                 dataType: null,
7543                 username: null,
7544                 password: null,
7545                 cache: null,
7546                 traditional: false,
7547                 headers: {},
7548                 */
7549
7550                 accepts: {
7551                         xml: "application/xml, text/xml",
7552                         html: "text/html",
7553                         text: "text/plain",
7554                         json: "application/json, text/javascript",
7555                         "*": "*/*"
7556                 },
7557
7558                 contents: {
7559                         xml: /xml/,
7560                         html: /html/,
7561                         json: /json/
7562                 },
7563
7564                 responseFields: {
7565                         xml: "responseXML",
7566                         text: "responseText"
7567                 },
7568
7569                 // List of data converters
7570                 // 1) key format is "source_type destination_type" (a single space in-between)
7571                 // 2) the catchall symbol "*" can be used for source_type
7572                 converters: {
7573
7574                         // Convert anything to text
7575                         "* text": window.String,
7576
7577                         // Text to html (true = no transformation)
7578                         "text html": true,
7579
7580                         // Evaluate text as a json expression
7581                         "text json": jQuery.parseJSON,
7582
7583                         // Parse text as xml
7584                         "text xml": jQuery.parseXML
7585                 }
7586         },
7587
7588         ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7589         ajaxTransport: addToPrefiltersOrTransports( transports ),
7590
7591         // Main method
7592         ajax: function( url, options ) {
7593
7594                 // If url is an object, simulate pre-1.5 signature
7595                 if ( typeof url === "object" ) {
7596                         options = url;
7597                         url = undefined;
7598                 }
7599
7600                 // Force options to be an object
7601                 options = options || {};
7602
7603                 var // Create the final options object
7604                         s = jQuery.ajaxSetup( {}, options ),
7605                         // Callbacks context
7606                         callbackContext = s.context || s,
7607                         // Context for global events
7608                         // It's the callbackContext if one was provided in the options
7609                         // and if it's a DOM node or a jQuery collection
7610                         globalEventContext = callbackContext !== s &&
7611                                 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7612                                                 jQuery( callbackContext ) : jQuery.event,
7613                         // Deferreds
7614                         deferred = jQuery.Deferred(),
7615                         completeDeferred = jQuery._Deferred(),
7616                         // Status-dependent callbacks
7617                         statusCode = s.statusCode || {},
7618                         // ifModified key
7619                         ifModifiedKey,
7620                         // Headers (they are sent all at once)
7621                         requestHeaders = {},
7622                         requestHeadersNames = {},
7623                         // Response headers
7624                         responseHeadersString,
7625                         responseHeaders,
7626                         // transport
7627                         transport,
7628                         // timeout handle
7629                         timeoutTimer,
7630                         // Cross-domain detection vars
7631                         parts,
7632                         // The jqXHR state
7633                         state = 0,
7634                         // To know if global events are to be dispatched
7635                         fireGlobals,
7636                         // Loop variable
7637                         i,
7638                         // Fake xhr
7639                         jqXHR = {
7640
7641                                 readyState: 0,
7642
7643                                 // Caches the header
7644                                 setRequestHeader: function( name, value ) {
7645                                         if ( !state ) {
7646                                                 var lname = name.toLowerCase();
7647                                                 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7648                                                 requestHeaders[ name ] = value;
7649                                         }
7650                                         return this;
7651                                 },
7652
7653                                 // Raw string
7654                                 getAllResponseHeaders: function() {
7655                                         return state === 2 ? responseHeadersString : null;
7656                                 },
7657
7658                                 // Builds headers hashtable if needed
7659                                 getResponseHeader: function( key ) {
7660                                         var match;
7661                                         if ( state === 2 ) {
7662                                                 if ( !responseHeaders ) {
7663                                                         responseHeaders = {};
7664                                                         while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7665                                                                 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7666                                                         }
7667                                                 }
7668                                                 match = responseHeaders[ key.toLowerCase() ];
7669                                         }
7670                                         return match === undefined ? null : match;
7671                                 },
7672
7673                                 // Overrides response content-type header
7674                                 overrideMimeType: function( type ) {
7675                                         if ( !state ) {
7676                                                 s.mimeType = type;
7677                                         }
7678                                         return this;
7679                                 },
7680
7681                                 // Cancel the request
7682                                 abort: function( statusText ) {
7683                                         statusText = statusText || "abort";
7684                                         if ( transport ) {
7685                                                 transport.abort( statusText );
7686                                         }
7687                                         done( 0, statusText );
7688                                         return this;
7689                                 }
7690                         };
7691
7692                 // Callback for when everything is done
7693                 // It is defined here because jslint complains if it is declared
7694                 // at the end of the function (which would be more logical and readable)
7695                 function done( status, statusText, responses, headers ) {
7696
7697                         // Called once
7698                         if ( state === 2 ) {
7699                                 return;
7700                         }
7701
7702                         // State is "done" now
7703                         state = 2;
7704
7705                         // Clear timeout if it exists
7706                         if ( timeoutTimer ) {
7707                                 clearTimeout( timeoutTimer );
7708                         }
7709
7710                         // Dereference transport for early garbage collection
7711                         // (no matter how long the jqXHR object will be used)
7712                         transport = undefined;
7713
7714                         // Cache response headers
7715                         responseHeadersString = headers || "";
7716
7717                         // Set readyState
7718                         jqXHR.readyState = status ? 4 : 0;
7719
7720                         var isSuccess,
7721                                 success,
7722                                 error,
7723                                 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7724                                 lastModified,
7725                                 etag;
7726
7727                         // If successful, handle type chaining
7728                         if ( status >= 200 && status < 300 || status === 304 ) {
7729
7730                                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7731                                 if ( s.ifModified ) {
7732
7733                                         if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7734                                                 jQuery.lastModified[ ifModifiedKey ] = lastModified;
7735                                         }
7736                                         if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7737                                                 jQuery.etag[ ifModifiedKey ] = etag;
7738                                         }
7739                                 }
7740
7741                                 // If not modified
7742                                 if ( status === 304 ) {
7743
7744                                         statusText = "notmodified";
7745                                         isSuccess = true;
7746
7747                                 // If we have data
7748                                 } else {
7749
7750                                         try {
7751                                                 success = ajaxConvert( s, response );
7752                                                 statusText = "success";
7753                                                 isSuccess = true;
7754                                         } catch(e) {
7755                                                 // We have a parsererror
7756                                                 statusText = "parsererror";
7757                                                 error = e;
7758                                         }
7759                                 }
7760                         } else {
7761                                 // We extract error from statusText
7762                                 // then normalize statusText and status for non-aborts
7763                                 error = statusText;
7764                                 if( !statusText || status ) {
7765                                         statusText = "error";
7766                                         if ( status < 0 ) {
7767                                                 status = 0;
7768                                         }
7769                                 }
7770                         }
7771
7772                         // Set data for the fake xhr object
7773                         jqXHR.status = status;
7774                         jqXHR.statusText = statusText;
7775
7776                         // Success/Error
7777                         if ( isSuccess ) {
7778                                 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7779                         } else {
7780                                 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7781                         }
7782
7783                         // Status-dependent callbacks
7784                         jqXHR.statusCode( statusCode );
7785                         statusCode = undefined;
7786
7787                         if ( fireGlobals ) {
7788                                 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7789                                                 [ jqXHR, s, isSuccess ? success : error ] );
7790                         }
7791
7792                         // Complete
7793                         completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7794
7795                         if ( fireGlobals ) {
7796                                 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
7797                                 // Handle the global AJAX counter
7798                                 if ( !( --jQuery.active ) ) {
7799                                         jQuery.event.trigger( "ajaxStop" );
7800                                 }
7801                         }
7802                 }
7803
7804                 // Attach deferreds
7805                 deferred.promise( jqXHR );
7806                 jqXHR.success = jqXHR.done;
7807                 jqXHR.error = jqXHR.fail;
7808                 jqXHR.complete = completeDeferred.done;
7809
7810                 // Status-dependent callbacks
7811                 jqXHR.statusCode = function( map ) {
7812                         if ( map ) {
7813                                 var tmp;
7814                                 if ( state < 2 ) {
7815                                         for( tmp in map ) {
7816                                                 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7817                                         }
7818                                 } else {
7819                                         tmp = map[ jqXHR.status ];
7820                                         jqXHR.then( tmp, tmp );
7821                                 }
7822                         }
7823                         return this;
7824                 };
7825
7826                 // Remove hash character (#7531: and string promotion)
7827                 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7828                 // We also use the url parameter if available
7829                 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7830
7831                 // Extract dataTypes list
7832                 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7833
7834                 // Determine if a cross-domain request is in order
7835                 if ( s.crossDomain == null ) {
7836                         parts = rurl.exec( s.url.toLowerCase() );
7837                         s.crossDomain = !!( parts &&
7838                                 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7839                                         ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7840                                                 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7841                         );
7842                 }
7843
7844                 // Convert data if not already a string
7845                 if ( s.data && s.processData && typeof s.data !== "string" ) {
7846                         s.data = jQuery.param( s.data, s.traditional );
7847                 }
7848
7849                 // Apply prefilters
7850                 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7851
7852                 // If request was aborted inside a prefiler, stop there
7853                 if ( state === 2 ) {
7854                         return false;
7855                 }
7856
7857                 // We can fire global events as of now if asked to
7858                 fireGlobals = s.global;
7859
7860                 // Uppercase the type
7861                 s.type = s.type.toUpperCase();
7862
7863                 // Determine if request has content
7864                 s.hasContent = !rnoContent.test( s.type );
7865
7866                 // Watch for a new set of requests
7867                 if ( fireGlobals && jQuery.active++ === 0 ) {
7868                         jQuery.event.trigger( "ajaxStart" );
7869                 }
7870
7871                 // More options handling for requests with no content
7872                 if ( !s.hasContent ) {
7873
7874                         // If data is available, append data to url
7875                         if ( s.data ) {
7876                                 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7877                         }
7878
7879                         // Get ifModifiedKey before adding the anti-cache parameter
7880                         ifModifiedKey = s.url;
7881
7882                         // Add anti-cache in url if needed
7883                         if ( s.cache === false ) {
7884
7885                                 var ts = jQuery.now(),
7886                                         // try replacing _= if it is there
7887                                         ret = s.url.replace( rts, "$1_=" + ts );
7888
7889                                 // if nothing was replaced, add timestamp to the end
7890                                 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7891                         }
7892                 }
7893
7894                 // Set the correct header, if data is being sent
7895                 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7896                         jqXHR.setRequestHeader( "Content-Type", s.contentType );
7897                 }
7898
7899                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7900                 if ( s.ifModified ) {
7901                         ifModifiedKey = ifModifiedKey || s.url;
7902                         if ( jQuery.lastModified[ ifModifiedKey ] ) {
7903                                 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7904                         }
7905                         if ( jQuery.etag[ ifModifiedKey ] ) {
7906                                 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7907                         }
7908                 }
7909
7910                 // Set the Accepts header for the server, depending on the dataType
7911                 jqXHR.setRequestHeader(
7912                         "Accept",
7913                         s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7914                                 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
7915                                 s.accepts[ "*" ]
7916                 );
7917
7918                 // Check for headers option
7919                 for ( i in s.headers ) {
7920                         jqXHR.setRequestHeader( i, s.headers[ i ] );
7921                 }
7922
7923                 // Allow custom headers/mimetypes and early abort
7924                 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7925                                 // Abort if not done already
7926                                 jqXHR.abort();
7927                                 return false;
7928
7929                 }
7930
7931                 // Install callbacks on deferreds
7932                 for ( i in { success: 1, error: 1, complete: 1 } ) {
7933                         jqXHR[ i ]( s[ i ] );
7934                 }
7935
7936                 // Get transport
7937                 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7938
7939                 // If no transport, we auto-abort
7940                 if ( !transport ) {
7941                         done( -1, "No Transport" );
7942                 } else {
7943                         jqXHR.readyState = 1;
7944                         // Send global event
7945                         if ( fireGlobals ) {
7946                                 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7947                         }
7948                         // Timeout
7949                         if ( s.async && s.timeout > 0 ) {
7950                                 timeoutTimer = setTimeout( function(){
7951                                         jqXHR.abort( "timeout" );
7952                                 }, s.timeout );
7953                         }
7954
7955                         try {
7956                                 state = 1;
7957                                 transport.send( requestHeaders, done );
7958                         } catch (e) {
7959                                 // Propagate exception as error if not done
7960                                 if ( status < 2 ) {
7961                                         done( -1, e );
7962                                 // Simply rethrow otherwise
7963                                 } else {
7964                                         jQuery.error( e );
7965                                 }
7966                         }
7967                 }
7968
7969                 return jqXHR;
7970         },
7971
7972         // Serialize an array of form elements or a set of
7973         // key/values into a query string
7974         param: function( a, traditional ) {
7975                 var s = [],
7976                         add = function( key, value ) {
7977                                 // If value is a function, invoke it and return its value
7978                                 value = jQuery.isFunction( value ) ? value() : value;
7979                                 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7980                         };
7981
7982                 // Set traditional to true for jQuery <= 1.3.2 behavior.
7983                 if ( traditional === undefined ) {
7984                         traditional = jQuery.ajaxSettings.traditional;
7985                 }
7986
7987                 // If an array was passed in, assume that it is an array of form elements.
7988                 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7989                         // Serialize the form elements
7990                         jQuery.each( a, function() {
7991                                 add( this.name, this.value );
7992                         });
7993
7994                 } else {
7995                         // If traditional, encode the "old" way (the way 1.3.2 or older
7996                         // did it), otherwise encode params recursively.
7997                         for ( var prefix in a ) {
7998                                 buildParams( prefix, a[ prefix ], traditional, add );
7999                         }
8000                 }
8001
8002                 // Return the resulting serialization
8003                 return s.join( "&" ).replace( r20, "+" );
8004         }
8005 });
8006
8007 function buildParams( prefix, obj, traditional, add ) {
8008         if ( jQuery.isArray( obj ) ) {
8009                 // Serialize array item.
8010                 jQuery.each( obj, function( i, v ) {
8011                         if ( traditional || rbracket.test( prefix ) ) {
8012                                 // Treat each array item as a scalar.
8013                                 add( prefix, v );
8014
8015                         } else {
8016                                 // If array item is non-scalar (array or object), encode its
8017                                 // numeric index to resolve deserialization ambiguity issues.
8018                                 // Note that rack (as of 1.0.0) can't currently deserialize
8019                                 // nested arrays properly, and attempting to do so may cause
8020                                 // a server error. Possible fixes are to modify rack's
8021                                 // deserialization algorithm or to provide an option or flag
8022                                 // to force array serialization to be shallow.
8023                                 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
8024                         }
8025                 });
8026
8027         } else if ( !traditional && obj != null && typeof obj === "object" ) {
8028                 // Serialize object item.
8029                 for ( var name in obj ) {
8030                         buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8031                 }
8032
8033         } else {
8034                 // Serialize scalar item.
8035                 add( prefix, obj );
8036         }
8037 }
8038
8039 // This is still on the jQuery object... for now
8040 // Want to move this to jQuery.ajax some day
8041 jQuery.extend({
8042
8043         // Counter for holding the number of active queries
8044         active: 0,
8045
8046         // Last-Modified header cache for next request
8047         lastModified: {},
8048         etag: {}
8049
8050 });
8051
8052 /* Handles responses to an ajax request:
8053  * - sets all responseXXX fields accordingly
8054  * - finds the right dataType (mediates between content-type and expected dataType)
8055  * - returns the corresponding response
8056  */
8057 function ajaxHandleResponses( s, jqXHR, responses ) {
8058
8059         var contents = s.contents,
8060                 dataTypes = s.dataTypes,
8061                 responseFields = s.responseFields,
8062                 ct,
8063                 type,
8064                 finalDataType,
8065                 firstDataType;
8066
8067         // Fill responseXXX fields
8068         for( type in responseFields ) {
8069                 if ( type in responses ) {
8070                         jqXHR[ responseFields[type] ] = responses[ type ];
8071                 }
8072         }
8073
8074         // Remove auto dataType and get content-type in the process
8075         while( dataTypes[ 0 ] === "*" ) {
8076                 dataTypes.shift();
8077                 if ( ct === undefined ) {
8078                         ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
8079                 }
8080         }
8081
8082         // Check if we're dealing with a known content-type
8083         if ( ct ) {
8084                 for ( type in contents ) {
8085                         if ( contents[ type ] && contents[ type ].test( ct ) ) {
8086                                 dataTypes.unshift( type );
8087                                 break;
8088                         }
8089                 }
8090         }
8091
8092         // Check to see if we have a response for the expected dataType
8093         if ( dataTypes[ 0 ] in responses ) {
8094                 finalDataType = dataTypes[ 0 ];
8095         } else {
8096                 // Try convertible dataTypes
8097                 for ( type in responses ) {
8098                         if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
8099                                 finalDataType = type;
8100                                 break;
8101                         }
8102                         if ( !firstDataType ) {
8103                                 firstDataType = type;
8104                         }
8105                 }
8106                 // Or just use first one
8107                 finalDataType = finalDataType || firstDataType;
8108         }
8109
8110         // If we found a dataType
8111         // We add the dataType to the list if needed
8112         // and return the corresponding response
8113         if ( finalDataType ) {
8114                 if ( finalDataType !== dataTypes[ 0 ] ) {
8115                         dataTypes.unshift( finalDataType );
8116                 }
8117                 return responses[ finalDataType ];
8118         }
8119 }
8120
8121 // Chain conversions given the request and the original response
8122 function ajaxConvert( s, response ) {
8123
8124         // Apply the dataFilter if provided
8125         if ( s.dataFilter ) {
8126                 response = s.dataFilter( response, s.dataType );
8127         }
8128
8129         var dataTypes = s.dataTypes,
8130                 converters = {},
8131                 i,
8132                 key,
8133                 length = dataTypes.length,
8134                 tmp,
8135                 // Current and previous dataTypes
8136                 current = dataTypes[ 0 ],
8137                 prev,
8138                 // Conversion expression
8139                 conversion,
8140                 // Conversion function
8141                 conv,
8142                 // Conversion functions (transitive conversion)
8143                 conv1,
8144                 conv2;
8145
8146         // For each dataType in the chain
8147         for( i = 1; i < length; i++ ) {
8148
8149                 // Create converters map
8150                 // with lowercased keys
8151                 if ( i === 1 ) {
8152                         for( key in s.converters ) {
8153                                 if( typeof key === "string" ) {
8154                                         converters[ key.toLowerCase() ] = s.converters[ key ];
8155                                 }
8156                         }
8157                 }
8158
8159                 // Get the dataTypes
8160                 prev = current;
8161                 current = dataTypes[ i ];
8162
8163                 // If current is auto dataType, update it to prev
8164                 if( current === "*" ) {
8165                         current = prev;
8166                 // If no auto and dataTypes are actually different
8167                 } else if ( prev !== "*" && prev !== current ) {
8168
8169                         // Get the converter
8170                         conversion = prev + " " + current;
8171                         conv = converters[ conversion ] || converters[ "* " + current ];
8172
8173                         // If there is no direct converter, search transitively
8174                         if ( !conv ) {
8175                                 conv2 = undefined;
8176                                 for( conv1 in converters ) {
8177                                         tmp = conv1.split( " " );
8178                                         if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
8179                                                 conv2 = converters[ tmp[1] + " " + current ];
8180                                                 if ( conv2 ) {
8181                                                         conv1 = converters[ conv1 ];
8182                                                         if ( conv1 === true ) {
8183                                                                 conv = conv2;
8184                                                         } else if ( conv2 === true ) {
8185                                                                 conv = conv1;
8186                                                         }
8187                                                         break;
8188                                                 }
8189                                         }
8190                                 }
8191                         }
8192                         // If we found no converter, dispatch an error
8193                         if ( !( conv || conv2 ) ) {
8194                                 jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
8195                         }
8196                         // If found converter is not an equivalence
8197                         if ( conv !== true ) {
8198                                 // Convert with 1 or 2 converters accordingly
8199                                 response = conv ? conv( response ) : conv2( conv1(response) );
8200                         }
8201                 }
8202         }
8203         return response;
8204 }
8205
8206
8207
8208
8209 var jsc = jQuery.now(),
8210         jsre = /(\=)\?(&|$)|\?\?/i;
8211
8212 // Default jsonp settings
8213 jQuery.ajaxSetup({
8214         jsonp: "callback",
8215         jsonpCallback: function() {
8216                 return jQuery.expando + "_" + ( jsc++ );
8217         }
8218 });
8219
8220 // Detect, normalize options and install callbacks for jsonp requests
8221 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
8222
8223         var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
8224                 ( typeof s.data === "string" );
8225
8226         if ( s.dataTypes[ 0 ] === "jsonp" ||
8227                 s.jsonp !== false && ( jsre.test( s.url ) ||
8228                                 inspectData && jsre.test( s.data ) ) ) {
8229
8230                 var responseContainer,
8231                         jsonpCallback = s.jsonpCallback =
8232                                 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
8233                         previous = window[ jsonpCallback ],
8234                         url = s.url,
8235                         data = s.data,
8236                         replace = "$1" + jsonpCallback + "$2";
8237
8238                 if ( s.jsonp !== false ) {
8239                         url = url.replace( jsre, replace );
8240                         if ( s.url === url ) {
8241                                 if ( inspectData ) {
8242                                         data = data.replace( jsre, replace );
8243                                 }
8244                                 if ( s.data === data ) {
8245                                         // Add callback manually
8246                                         url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
8247                                 }
8248                         }
8249                 }
8250
8251                 s.url = url;
8252                 s.data = data;
8253
8254                 // Install callback
8255                 window[ jsonpCallback ] = function( response ) {
8256                         responseContainer = [ response ];
8257                 };
8258
8259                 // Clean-up function
8260                 jqXHR.always(function() {
8261                         // Set callback back to previous value
8262                         window[ jsonpCallback ] = previous;
8263                         // Call if it was a function and we have a response
8264                         if ( responseContainer && jQuery.isFunction( previous ) ) {
8265                                 window[ jsonpCallback ]( responseContainer[ 0 ] );
8266                         }
8267                 });
8268
8269                 // Use data converter to retrieve json after script execution
8270                 s.converters["script json"] = function() {
8271                         if ( !responseContainer ) {
8272                                 jQuery.error( jsonpCallback + " was not called" );
8273                         }
8274                         return responseContainer[ 0 ];
8275                 };
8276
8277                 // force json dataType
8278                 s.dataTypes[ 0 ] = "json";
8279
8280                 // Delegate to script
8281                 return "script";
8282         }
8283 });
8284
8285
8286
8287
8288 // Install script dataType
8289 jQuery.ajaxSetup({
8290         accepts: {
8291                 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8292         },
8293         contents: {
8294                 script: /javascript|ecmascript/
8295         },
8296         converters: {
8297                 "text script": function( text ) {
8298                         jQuery.globalEval( text );
8299                         return text;
8300                 }
8301         }
8302 });
8303
8304 // Handle cache's special case and global
8305 jQuery.ajaxPrefilter( "script", function( s ) {
8306         if ( s.cache === undefined ) {
8307                 s.cache = false;
8308         }
8309         if ( s.crossDomain ) {
8310                 s.type = "GET";
8311                 s.global = false;
8312         }
8313 });
8314
8315 // Bind script tag hack transport
8316 jQuery.ajaxTransport( "script", function(s) {
8317
8318         // This transport only deals with cross domain requests
8319         if ( s.crossDomain ) {
8320
8321                 var script,
8322                         head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
8323
8324                 return {
8325
8326                         send: function( _, callback ) {
8327
8328                                 script = document.createElement( "script" );
8329
8330                                 script.async = "async";
8331
8332                                 if ( s.scriptCharset ) {
8333                                         script.charset = s.scriptCharset;
8334                                 }
8335
8336                                 script.src = s.url;
8337
8338                                 // Attach handlers for all browsers
8339                                 script.onload = script.onreadystatechange = function( _, isAbort ) {
8340
8341                                         if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
8342
8343                                                 // Handle memory leak in IE
8344                                                 script.onload = script.onreadystatechange = null;
8345
8346                                                 // Remove the script
8347                                                 if ( head && script.parentNode ) {
8348                                                         head.removeChild( script );
8349                                                 }
8350
8351                                                 // Dereference the script
8352                                                 script = undefined;
8353
8354                                                 // Callback if not abort
8355                                                 if ( !isAbort ) {
8356                                                         callback( 200, "success" );
8357                                                 }
8358                                         }
8359                                 };
8360                                 // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
8361                                 // This arises when a base node is used (#2709 and #4378).
8362                                 head.insertBefore( script, head.firstChild );
8363                         },
8364
8365                         abort: function() {
8366                                 if ( script ) {
8367                                         script.onload( 0, 1 );
8368                                 }
8369                         }
8370                 };
8371         }
8372 });
8373
8374
8375
8376
8377 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
8378         xhrOnUnloadAbort = window.ActiveXObject ? function() {
8379                 // Abort all pending requests
8380                 for ( var key in xhrCallbacks ) {
8381                         xhrCallbacks[ key ]( 0, 1 );
8382                 }
8383         } : false,
8384         xhrId = 0,
8385         xhrCallbacks;
8386
8387 // Functions to create xhrs
8388 function createStandardXHR() {
8389         try {
8390                 return new window.XMLHttpRequest();
8391         } catch( e ) {}
8392 }
8393
8394 function createActiveXHR() {
8395         try {
8396                 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8397         } catch( e ) {}
8398 }
8399
8400 // Create the request object
8401 // (This is still attached to ajaxSettings for backward compatibility)
8402 jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8403         /* Microsoft failed to properly
8404          * implement the XMLHttpRequest in IE7 (can't request local files),
8405          * so we use the ActiveXObject when it is available
8406          * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8407          * we need a fallback.
8408          */
8409         function() {
8410                 return !this.isLocal && createStandardXHR() || createActiveXHR();
8411         } :
8412         // For all other browsers, use the standard XMLHttpRequest object
8413         createStandardXHR;
8414
8415 // Determine support properties
8416 (function( xhr ) {
8417         jQuery.extend( jQuery.support, {
8418                 ajax: !!xhr,
8419                 cors: !!xhr && ( "withCredentials" in xhr )
8420         });
8421 })( jQuery.ajaxSettings.xhr() );
8422
8423 // Create transport if the browser can provide an xhr
8424 if ( jQuery.support.ajax ) {
8425
8426         jQuery.ajaxTransport(function( s ) {
8427                 // Cross domain only allowed if supported through XMLHttpRequest
8428                 if ( !s.crossDomain || jQuery.support.cors ) {
8429
8430                         var callback;
8431
8432                         return {
8433                                 send: function( headers, complete ) {
8434
8435                                         // Get a new xhr
8436                                         var xhr = s.xhr(),
8437                                                 handle,
8438                                                 i;
8439
8440                                         // Open the socket
8441                                         // Passing null username, generates a login popup on Opera (#2865)
8442                                         if ( s.username ) {
8443                                                 xhr.open( s.type, s.url, s.async, s.username, s.password );
8444                                         } else {
8445                                                 xhr.open( s.type, s.url, s.async );
8446                                         }
8447
8448                                         // Apply custom fields if provided
8449                                         if ( s.xhrFields ) {
8450                                                 for ( i in s.xhrFields ) {
8451                                                         xhr[ i ] = s.xhrFields[ i ];
8452                                                 }
8453                                         }
8454
8455                                         // Override mime type if needed
8456                                         if ( s.mimeType && xhr.overrideMimeType ) {
8457                                                 xhr.overrideMimeType( s.mimeType );
8458                                         }
8459
8460                                         // X-Requested-With header
8461                                         // For cross-domain requests, seeing as conditions for a preflight are
8462                                         // akin to a jigsaw puzzle, we simply never set it to be sure.
8463                                         // (it can always be set on a per-request basis or even using ajaxSetup)
8464                                         // For same-domain requests, won't change header if already provided.
8465                                         if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8466                                                 headers[ "X-Requested-With" ] = "XMLHttpRequest";
8467                                         }
8468
8469                                         // Need an extra try/catch for cross domain requests in Firefox 3
8470                                         try {
8471                                                 for ( i in headers ) {
8472                                                         xhr.setRequestHeader( i, headers[ i ] );
8473                                                 }
8474                                         } catch( _ ) {}
8475
8476                                         // Do send the request
8477                                         // This may raise an exception which is actually
8478                                         // handled in jQuery.ajax (so no try/catch here)
8479                                         xhr.send( ( s.hasContent && s.data ) || null );
8480
8481                                         // Listener
8482                                         callback = function( _, isAbort ) {
8483
8484                                                 var status,
8485                                                         statusText,
8486                                                         responseHeaders,
8487                                                         responses,
8488                                                         xml;
8489
8490                                                 // Firefox throws exceptions when accessing properties
8491                                                 // of an xhr when a network error occured
8492                                                 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8493                                                 try {
8494
8495                                                         // Was never called and is aborted or complete
8496                                                         if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8497
8498                                                                 // Only called once
8499                                                                 callback = undefined;
8500
8501                                                                 // Do not keep as active anymore
8502                                                                 if ( handle ) {
8503                                                                         xhr.onreadystatechange = jQuery.noop;
8504                                                                         if ( xhrOnUnloadAbort ) {
8505                                                                                 delete xhrCallbacks[ handle ];
8506                                                                         }
8507                                                                 }
8508
8509                                                                 // If it's an abort
8510                                                                 if ( isAbort ) {
8511                                                                         // Abort it manually if needed
8512                                                                         if ( xhr.readyState !== 4 ) {
8513                                                                                 xhr.abort();
8514                                                                         }
8515                                                                 } else {
8516                                                                         status = xhr.status;
8517                                                                         responseHeaders = xhr.getAllResponseHeaders();
8518                                                                         responses = {};
8519                                                                         xml = xhr.responseXML;
8520
8521                                                                         // Construct response list
8522                                                                         if ( xml && xml.documentElement /* #4958 */ ) {
8523                                                                                 responses.xml = xml;
8524                                                                         }
8525                                                                         responses.text = xhr.responseText;
8526
8527                                                                         // Firefox throws an exception when accessing
8528                                                                         // statusText for faulty cross-domain requests
8529                                                                         try {
8530                                                                                 statusText = xhr.statusText;
8531                                                                         } catch( e ) {
8532                                                                                 // We normalize with Webkit giving an empty statusText
8533                                                                                 statusText = "";
8534                                                                         }
8535
8536                                                                         // Filter status for non standard behaviors
8537
8538                                                                         // If the request is local and we have data: assume a success
8539                                                                         // (success with no data won't get notified, that's the best we
8540                                                                         // can do given current implementations)
8541                                                                         if ( !status && s.isLocal && !s.crossDomain ) {
8542                                                                                 status = responses.text ? 200 : 404;
8543                                                                         // IE - #1450: sometimes returns 1223 when it should be 204
8544                                                                         } else if ( status === 1223 ) {
8545                                                                                 status = 204;
8546                                                                         }
8547                                                                 }
8548                                                         }
8549                                                 } catch( firefoxAccessException ) {
8550                                                         if ( !isAbort ) {
8551                                                                 complete( -1, firefoxAccessException );
8552                                                         }
8553                                                 }
8554
8555                                                 // Call complete if needed
8556                                                 if ( responses ) {
8557                                                         complete( status, statusText, responses, responseHeaders );
8558                                                 }
8559                                         };
8560
8561                                         // if we're in sync mode or it's in cache
8562                                         // and has been retrieved directly (IE6 & IE7)
8563                                         // we need to manually fire the callback
8564                                         if ( !s.async || xhr.readyState === 4 ) {
8565                                                 callback();
8566                                         } else {
8567                                                 handle = ++xhrId;
8568                                                 if ( xhrOnUnloadAbort ) {
8569                                                         // Create the active xhrs callbacks list if needed
8570                                                         // and attach the unload handler
8571                                                         if ( !xhrCallbacks ) {
8572                                                                 xhrCallbacks = {};
8573                                                                 jQuery( window ).unload( xhrOnUnloadAbort );
8574                                                         }
8575                                                         // Add to list of active xhrs callbacks
8576                                                         xhrCallbacks[ handle ] = callback;
8577                                                 }
8578                                                 xhr.onreadystatechange = callback;
8579                                         }
8580                                 },
8581
8582                                 abort: function() {
8583                                         if ( callback ) {
8584                                                 callback(0,1);
8585                                         }
8586                                 }
8587                         };
8588                 }
8589         });
8590 }
8591
8592
8593
8594
8595 var elemdisplay = {},
8596         iframe, iframeDoc,
8597         rfxtypes = /^(?:toggle|show|hide)$/,
8598         rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
8599         timerId,
8600         fxAttrs = [
8601                 // height animations
8602                 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
8603                 // width animations
8604                 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
8605                 // opacity animations
8606                 [ "opacity" ]
8607         ],
8608         fxNow,
8609         requestAnimationFrame = window.webkitRequestAnimationFrame ||
8610             window.mozRequestAnimationFrame ||
8611             window.oRequestAnimationFrame;
8612
8613 jQuery.fn.extend({
8614         show: function( speed, easing, callback ) {
8615                 var elem, display;
8616
8617                 if ( speed || speed === 0 ) {
8618                         return this.animate( genFx("show", 3), speed, easing, callback);
8619
8620                 } else {
8621                         for ( var i = 0, j = this.length; i < j; i++ ) {
8622                                 elem = this[i];
8623
8624                                 if ( elem.style ) {
8625                                         display = elem.style.display;
8626
8627                                         // Reset the inline display of this element to learn if it is
8628                                         // being hidden by cascaded rules or not
8629                                         if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
8630                                                 display = elem.style.display = "";
8631                                         }
8632
8633                                         // Set elements which have been overridden with display: none
8634                                         // in a stylesheet to whatever the default browser style is
8635                                         // for such an element
8636                                         if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
8637                                                 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
8638                                         }
8639                                 }
8640                         }
8641
8642                         // Set the display of most of the elements in a second loop
8643                         // to avoid the constant reflow
8644                         for ( i = 0; i < j; i++ ) {
8645                                 elem = this[i];
8646
8647                                 if ( elem.style ) {
8648                                         display = elem.style.display;
8649
8650                                         if ( display === "" || display === "none" ) {
8651                                                 elem.style.display = jQuery._data(elem, "olddisplay") || "";
8652                                         }
8653                                 }
8654                         }
8655
8656                         return this;
8657                 }
8658         },
8659
8660         hide: function( speed, easing, callback ) {
8661                 if ( speed || speed === 0 ) {
8662                         return this.animate( genFx("hide", 3), speed, easing, callback);
8663
8664                 } else {
8665                         for ( var i = 0, j = this.length; i < j; i++ ) {
8666                                 if ( this[i].style ) {
8667                                         var display = jQuery.css( this[i], "display" );
8668
8669                                         if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8670                                                 jQuery._data( this[i], "olddisplay", display );
8671                                         }
8672                                 }
8673                         }
8674
8675                         // Set the display of the elements in a second loop
8676                         // to avoid the constant reflow
8677                         for ( i = 0; i < j; i++ ) {
8678                                 if ( this[i].style ) {
8679                                         this[i].style.display = "none";
8680                                 }
8681                         }
8682
8683                         return this;
8684                 }
8685         },
8686
8687         // Save the old toggle function
8688         _toggle: jQuery.fn.toggle,
8689
8690         toggle: function( fn, fn2, callback ) {
8691                 var bool = typeof fn === "boolean";
8692
8693                 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8694                         this._toggle.apply( this, arguments );
8695
8696                 } else if ( fn == null || bool ) {
8697                         this.each(function() {
8698                                 var state = bool ? fn : jQuery(this).is(":hidden");
8699                                 jQuery(this)[ state ? "show" : "hide" ]();
8700                         });
8701
8702                 } else {
8703                         this.animate(genFx("toggle", 3), fn, fn2, callback);
8704                 }
8705
8706                 return this;
8707         },
8708
8709         fadeTo: function( speed, to, easing, callback ) {
8710                 return this.filter(":hidden").css("opacity", 0).show().end()
8711                                         .animate({opacity: to}, speed, easing, callback);
8712         },
8713
8714         animate: function( prop, speed, easing, callback ) {
8715                 var optall = jQuery.speed(speed, easing, callback);
8716
8717                 if ( jQuery.isEmptyObject( prop ) ) {
8718                         return this.each( optall.complete, [ false ] );
8719                 }
8720
8721                 return this[ optall.queue === false ? "each" : "queue" ](function() {
8722                         // XXX 'this' does not always have a nodeName when running the
8723                         // test suite
8724
8725                         if ( optall.queue === false ) {
8726                                 jQuery._mark( this );
8727                         }
8728
8729                         var opt = jQuery.extend({}, optall),
8730                                 isElement = this.nodeType === 1,
8731                                 hidden = isElement && jQuery(this).is(":hidden"),
8732                                 name, val, p,
8733                                 display, e,
8734                                 parts, start, end, unit;
8735
8736                         // will store per property easing and be used to determine when an animation is complete
8737                         opt.animatedProperties = {};
8738
8739                         for ( p in prop ) {
8740
8741                                 // property name normalization
8742                                 name = jQuery.camelCase( p );
8743                                 if ( p !== name ) {
8744                                         prop[ name ] = prop[ p ];
8745                                         delete prop[ p ];
8746                                 }
8747
8748                                 val = prop[name];
8749
8750                                 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8751                                         return opt.complete.call(this);
8752                                 }
8753
8754                                 if ( isElement && ( name === "height" || name === "width" ) ) {
8755                                         // Make sure that nothing sneaks out
8756                                         // Record all 3 overflow attributes because IE does not
8757                                         // change the overflow attribute when overflowX and
8758                                         // overflowY are set to the same value
8759                                         opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8760
8761                                         // Set display property to inline-block for height/width
8762                                         // animations on inline elements that are having width/height
8763                                         // animated
8764                                         if ( jQuery.css( this, "display" ) === "inline" &&
8765                                                         jQuery.css( this, "float" ) === "none" ) {
8766                                                 if ( !jQuery.support.inlineBlockNeedsLayout ) {
8767                                                         this.style.display = "inline-block";
8768
8769                                                 } else {
8770                                                         display = defaultDisplay(this.nodeName);
8771
8772                                                         // inline-level elements accept inline-block;
8773                                                         // block-level elements need to be inline with layout
8774                                                         if ( display === "inline" ) {
8775                                                                 this.style.display = "inline-block";
8776
8777                                                         } else {
8778                                                                 this.style.display = "inline";
8779                                                                 this.style.zoom = 1;
8780                                                         }
8781                                                 }
8782                                         }
8783                                 }
8784
8785                                 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8786                                 opt.animatedProperties[name] = jQuery.isArray( val ) ?
8787                                         val[1]:
8788                                         opt.specialEasing && opt.specialEasing[name] || opt.easing || 'swing';
8789                         }
8790
8791                         if ( opt.overflow != null ) {
8792                                 this.style.overflow = "hidden";
8793                         }
8794
8795                         for ( p in prop ) {
8796                                 e = new jQuery.fx( this, opt, p );
8797
8798                                 val = prop[p];
8799
8800                                 if ( rfxtypes.test(val) ) {
8801                                         e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8802
8803                                 } else {
8804                                         parts = rfxnum.exec(val);
8805                                         start = e.cur();
8806
8807                                         if ( parts ) {
8808                                                 end = parseFloat( parts[2] );
8809                                                 unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" );
8810
8811                                                 // We need to compute starting value
8812                                                 if ( unit !== "px" ) {
8813                                                         jQuery.style( this, p, (end || 1) + unit);
8814                                                         start = ((end || 1) / e.cur()) * start;
8815                                                         jQuery.style( this, p, start + unit);
8816                                                 }
8817
8818                                                 // If a +=/-= token was provided, we're doing a relative animation
8819                                                 if ( parts[1] ) {
8820                                                         end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
8821                                                 }
8822
8823                                                 e.custom( start, end, unit );
8824
8825                                         } else {
8826                                                 e.custom( start, val, "" );
8827                                         }
8828                                 }
8829                         }
8830
8831                         // For JS strict compliance
8832                         return true;
8833                 });
8834         },
8835
8836         stop: function( clearQueue, gotoEnd ) {
8837                 if ( clearQueue ) {
8838                         this.queue([]);
8839                 }
8840
8841                 this.each(function() {
8842                         var timers = jQuery.timers,
8843                                 i = timers.length;
8844                         // clear marker counters if we know they won't be
8845                         if ( !gotoEnd ) {
8846                                 jQuery._unmark( true, this );
8847                         }
8848                         // go in reverse order so anything added to the queue during the loop is ignored
8849                         while ( i-- ) {
8850                                 if ( timers[i].elem === this ) {
8851                                         if (gotoEnd) {
8852                                                 // force the next step to be the last
8853                                                 timers[i](true);
8854                                         }
8855
8856                                         timers.splice(i, 1);
8857                                 }
8858                         }
8859                 });
8860
8861                 // start the next in the queue if the last step wasn't forced
8862                 if ( !gotoEnd ) {
8863                         this.dequeue();
8864                 }
8865
8866                 return this;
8867         }
8868
8869 });
8870
8871 // Animations created synchronously will run synchronously
8872 function createFxNow() {
8873         setTimeout( clearFxNow, 0 );
8874         return ( fxNow = jQuery.now() );
8875 }
8876
8877 function clearFxNow() {
8878         fxNow = undefined;
8879 }
8880
8881 // Generate parameters to create a standard animation
8882 function genFx( type, num ) {
8883         var obj = {};
8884
8885         jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8886                 obj[ this ] = type;
8887         });
8888
8889         return obj;
8890 }
8891
8892 // Generate shortcuts for custom animations
8893 jQuery.each({
8894         slideDown: genFx("show", 1),
8895         slideUp: genFx("hide", 1),
8896         slideToggle: genFx("toggle", 1),
8897         fadeIn: { opacity: "show" },
8898         fadeOut: { opacity: "hide" },
8899         fadeToggle: { opacity: "toggle" }
8900 }, function( name, props ) {
8901         jQuery.fn[ name ] = function( speed, easing, callback ) {
8902                 return this.animate( props, speed, easing, callback );
8903         };
8904 });
8905
8906 jQuery.extend({
8907         speed: function( speed, easing, fn ) {
8908                 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8909                         complete: fn || !fn && easing ||
8910                                 jQuery.isFunction( speed ) && speed,
8911                         duration: speed,
8912                         easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8913                 };
8914
8915                 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8916                         opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8917
8918                 // Queueing
8919                 opt.old = opt.complete;
8920                 opt.complete = function( noUnmark ) {
8921                         if ( opt.queue !== false ) {
8922                                 jQuery.dequeue( this );
8923                         } else if ( noUnmark !== false ) {
8924                                 jQuery._unmark( this );
8925                         }
8926
8927                         if ( jQuery.isFunction( opt.old ) ) {
8928                                 opt.old.call( this );
8929                         }
8930                 };
8931
8932                 return opt;
8933         },
8934
8935         easing: {
8936                 linear: function( p, n, firstNum, diff ) {
8937                         return firstNum + diff * p;
8938                 },
8939                 swing: function( p, n, firstNum, diff ) {
8940                         return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8941                 }
8942         },
8943
8944         timers: [],
8945
8946         fx: function( elem, options, prop ) {
8947                 this.options = options;
8948                 this.elem = elem;
8949                 this.prop = prop;
8950
8951                 options.orig = options.orig || {};
8952         }
8953
8954 });
8955
8956 jQuery.fx.prototype = {
8957         // Simple function for setting a style value
8958         update: function() {
8959                 if ( this.options.step ) {
8960                         this.options.step.call( this.elem, this.now, this );
8961                 }
8962
8963                 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8964         },
8965
8966         // Get the current size
8967         cur: function() {
8968                 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8969                         return this.elem[ this.prop ];
8970                 }
8971
8972                 var parsed,
8973                         r = jQuery.css( this.elem, this.prop );
8974                 // Empty strings, null, undefined and "auto" are converted to 0,
8975                 // complex values such as "rotate(1rad)" are returned as is,
8976                 // simple values such as "10px" are parsed to Float.
8977                 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8978         },
8979
8980         // Start an animation from one number to another
8981         custom: function( from, to, unit ) {
8982                 var self = this,
8983                         fx = jQuery.fx,
8984                         raf;
8985
8986                 this.startTime = fxNow || createFxNow();
8987                 this.start = from;
8988                 this.end = to;
8989                 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8990                 this.now = this.start;
8991                 this.pos = this.state = 0;
8992
8993                 function t( gotoEnd ) {
8994                         return self.step(gotoEnd);
8995                 }
8996
8997                 t.elem = this.elem;
8998
8999                 if ( t() && jQuery.timers.push(t) && !timerId ) {
9000                         // Use requestAnimationFrame instead of setInterval if available
9001                         if ( requestAnimationFrame ) {
9002                                 timerId = 1;
9003                                 raf = function() {
9004                                         // When timerId gets set to null at any point, this stops
9005                                         if ( timerId ) {
9006                                                 requestAnimationFrame( raf );
9007                                                 fx.tick();
9008                                         }
9009                                 };
9010                                 requestAnimationFrame( raf );
9011                         } else {
9012                                 timerId = setInterval( fx.tick, fx.interval );
9013                         }
9014                 }
9015         },
9016
9017         // Simple 'show' function
9018         show: function() {
9019                 // Remember where we started, so that we can go back to it later
9020                 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
9021                 this.options.show = true;
9022
9023                 // Begin the animation
9024                 // Make sure that we start at a small width/height to avoid any
9025                 // flash of content
9026                 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
9027
9028                 // Start by showing the element
9029                 jQuery( this.elem ).show();
9030         },
9031
9032         // Simple 'hide' function
9033         hide: function() {
9034                 // Remember where we started, so that we can go back to it later
9035                 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
9036                 this.options.hide = true;
9037
9038                 // Begin the animation
9039                 this.custom(this.cur(), 0);
9040         },
9041
9042         // Each step of an animation
9043         step: function( gotoEnd ) {
9044                 var t = fxNow || createFxNow(),
9045                         done = true,
9046                         elem = this.elem,
9047                         options = this.options,
9048                         i, n;
9049
9050                 if ( gotoEnd || t >= options.duration + this.startTime ) {
9051                         this.now = this.end;
9052                         this.pos = this.state = 1;
9053                         this.update();
9054
9055                         options.animatedProperties[ this.prop ] = true;
9056
9057                         for ( i in options.animatedProperties ) {
9058                                 if ( options.animatedProperties[i] !== true ) {
9059                                         done = false;
9060                                 }
9061                         }
9062
9063                         if ( done ) {
9064                                 // Reset the overflow
9065                                 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
9066
9067                                         jQuery.each( [ "", "X", "Y" ], function (index, value) {
9068                                                 elem.style[ "overflow" + value ] = options.overflow[index];
9069                                         });
9070                                 }
9071
9072                                 // Hide the element if the "hide" operation was done
9073                                 if ( options.hide ) {
9074                                         jQuery(elem).hide();
9075                                 }
9076
9077                                 // Reset the properties, if the item has been hidden or shown
9078                                 if ( options.hide || options.show ) {
9079                                         for ( var p in options.animatedProperties ) {
9080                                                 jQuery.style( elem, p, options.orig[p] );
9081                                         }
9082                                 }
9083
9084                                 // Execute the complete function
9085                                 options.complete.call( elem );
9086                         }
9087
9088                         return false;
9089
9090                 } else {
9091                         // classical easing cannot be used with an Infinity duration
9092                         if ( options.duration == Infinity ) {
9093                                 this.now = t;
9094                         } else {
9095                                 n = t - this.startTime;
9096
9097                                 this.state = n / options.duration;
9098                                 // Perform the easing function, defaults to swing
9099                                 this.pos = jQuery.easing[options.animatedProperties[this.prop]](this.state, n, 0, 1, options.duration);
9100                                 this.now = this.start + ((this.end - this.start) * this.pos);
9101                         }
9102                         // Perform the next step of the animation
9103                         this.update();
9104                 }
9105
9106                 return true;
9107         }
9108 };
9109
9110 jQuery.extend( jQuery.fx, {
9111         tick: function() {
9112                 var timers = jQuery.timers,
9113                         i = timers.length;
9114                 while ( i-- ) {
9115                         if ( !timers[i]() ) {
9116                                 timers.splice(i, 1);
9117                         }
9118                 }
9119
9120                 if ( !timers.length ) {
9121                         jQuery.fx.stop();
9122                 }
9123         },
9124
9125         interval: 13,
9126
9127         stop: function() {
9128                 clearInterval( timerId );
9129                 timerId = null;
9130         },
9131
9132         speeds: {
9133                 slow: 600,
9134                 fast: 200,
9135                 // Default speed
9136                 _default: 400
9137         },
9138
9139         step: {
9140                 opacity: function( fx ) {
9141                         jQuery.style( fx.elem, "opacity", fx.now );
9142                 },
9143
9144                 _default: function( fx ) {
9145                         if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
9146                                 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
9147                         } else {
9148                                 fx.elem[ fx.prop ] = fx.now;
9149                         }
9150                 }
9151         }
9152 });
9153
9154 if ( jQuery.expr && jQuery.expr.filters ) {
9155         jQuery.expr.filters.animated = function( elem ) {
9156                 return jQuery.grep(jQuery.timers, function( fn ) {
9157                         return elem === fn.elem;
9158                 }).length;
9159         };
9160 }
9161
9162 // Try to restore the default display value of an element
9163 function defaultDisplay( nodeName ) {
9164
9165         if ( !elemdisplay[ nodeName ] ) {
9166
9167                 var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
9168                         display = elem.css( "display" );
9169
9170                 elem.remove();
9171
9172                 // If the simple way fails,
9173                 // get element's real default display by attaching it to a temp iframe
9174                 if ( display === "none" || display === "" ) {
9175                         // No iframe to use yet, so create it
9176                         if ( !iframe ) {
9177                                 iframe = document.createElement( "iframe" );
9178                                 iframe.frameBorder = iframe.width = iframe.height = 0;
9179                         }
9180
9181                         document.body.appendChild( iframe );
9182
9183                         // Create a cacheable copy of the iframe document on first call.
9184                         // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
9185                         // document to it, Webkit & Firefox won't allow reusing the iframe document
9186                         if ( !iframeDoc || !iframe.createElement ) {
9187                                 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
9188                                 iframeDoc.write( "<!doctype><html><body></body></html>" );
9189                         }
9190
9191                         elem = iframeDoc.createElement( nodeName );
9192
9193                         iframeDoc.body.appendChild( elem );
9194
9195                         display = jQuery.css( elem, "display" );
9196
9197                         document.body.removeChild( iframe );
9198                 }
9199
9200                 // Store the correct default display
9201                 elemdisplay[ nodeName ] = display;
9202         }
9203
9204         return elemdisplay[ nodeName ];
9205 }
9206
9207
9208
9209
9210 var rtable = /^t(?:able|d|h)$/i,
9211         rroot = /^(?:body|html)$/i;
9212
9213 if ( "getBoundingClientRect" in document.documentElement ) {
9214         jQuery.fn.offset = function( options ) {
9215                 var elem = this[0], box;
9216
9217                 if ( options ) {
9218                         return this.each(function( i ) {
9219                                 jQuery.offset.setOffset( this, options, i );
9220                         });
9221                 }
9222
9223                 if ( !elem || !elem.ownerDocument ) {
9224                         return null;
9225                 }
9226
9227                 if ( elem === elem.ownerDocument.body ) {
9228                         return jQuery.offset.bodyOffset( elem );
9229                 }
9230
9231                 try {
9232                         box = elem.getBoundingClientRect();
9233                 } catch(e) {}
9234
9235                 var doc = elem.ownerDocument,
9236                         docElem = doc.documentElement;
9237
9238                 // Make sure we're not dealing with a disconnected DOM node
9239                 if ( !box || !jQuery.contains( docElem, elem ) ) {
9240                         return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
9241                 }
9242
9243                 var body = doc.body,
9244                         win = getWindow(doc),
9245                         clientTop  = docElem.clientTop  || body.clientTop  || 0,
9246                         clientLeft = docElem.clientLeft || body.clientLeft || 0,
9247                         scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
9248                         scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
9249                         top  = box.top  + scrollTop  - clientTop,
9250                         left = box.left + scrollLeft - clientLeft;
9251
9252                 return { top: top, left: left };
9253         };
9254
9255 } else {
9256         jQuery.fn.offset = function( options ) {
9257                 var elem = this[0];
9258
9259                 if ( options ) {
9260                         return this.each(function( i ) {
9261                                 jQuery.offset.setOffset( this, options, i );
9262                         });
9263                 }
9264
9265                 if ( !elem || !elem.ownerDocument ) {
9266                         return null;
9267                 }
9268
9269                 if ( elem === elem.ownerDocument.body ) {
9270                         return jQuery.offset.bodyOffset( elem );
9271                 }
9272
9273                 jQuery.offset.initialize();
9274
9275                 var computedStyle,
9276                         offsetParent = elem.offsetParent,
9277                         prevOffsetParent = elem,
9278                         doc = elem.ownerDocument,
9279                         docElem = doc.documentElement,
9280                         body = doc.body,
9281                         defaultView = doc.defaultView,
9282                         prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
9283                         top = elem.offsetTop,
9284                         left = elem.offsetLeft;
9285
9286                 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
9287                         if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
9288                                 break;
9289                         }
9290
9291                         computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
9292                         top  -= elem.scrollTop;
9293                         left -= elem.scrollLeft;
9294
9295                         if ( elem === offsetParent ) {
9296                                 top  += elem.offsetTop;
9297                                 left += elem.offsetLeft;
9298
9299                                 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
9300                                         top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
9301                                         left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9302                                 }
9303
9304                                 prevOffsetParent = offsetParent;
9305                                 offsetParent = elem.offsetParent;
9306                         }
9307
9308                         if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
9309                                 top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
9310                                 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9311                         }
9312
9313                         prevComputedStyle = computedStyle;
9314                 }
9315
9316                 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
9317                         top  += body.offsetTop;
9318                         left += body.offsetLeft;
9319                 }
9320
9321                 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
9322                         top  += Math.max( docElem.scrollTop, body.scrollTop );
9323                         left += Math.max( docElem.scrollLeft, body.scrollLeft );
9324                 }
9325
9326                 return { top: top, left: left };
9327         };
9328 }
9329
9330 jQuery.offset = {
9331         initialize: function() {
9332                 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
9333                         html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
9334
9335                 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
9336
9337                 container.innerHTML = html;
9338                 body.insertBefore( container, body.firstChild );
9339                 innerDiv = container.firstChild;
9340                 checkDiv = innerDiv.firstChild;
9341                 td = innerDiv.nextSibling.firstChild.firstChild;
9342
9343                 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
9344                 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
9345
9346                 checkDiv.style.position = "fixed";
9347                 checkDiv.style.top = "20px";
9348
9349                 // safari subtracts parent border width here which is 5px
9350                 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
9351                 checkDiv.style.position = checkDiv.style.top = "";
9352
9353                 innerDiv.style.overflow = "hidden";
9354                 innerDiv.style.position = "relative";
9355
9356                 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
9357
9358                 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
9359
9360                 body.removeChild( container );
9361                 jQuery.offset.initialize = jQuery.noop;
9362         },
9363
9364         bodyOffset: function( body ) {
9365                 var top = body.offsetTop,
9366                         left = body.offsetLeft;
9367
9368                 jQuery.offset.initialize();
9369
9370                 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
9371                         top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9372                         left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9373                 }
9374
9375                 return { top: top, left: left };
9376         },
9377
9378         setOffset: function( elem, options, i ) {
9379                 var position = jQuery.css( elem, "position" );
9380
9381                 // set position first, in-case top/left are set even on static elem
9382                 if ( position === "static" ) {
9383                         elem.style.position = "relative";
9384                 }
9385
9386                 var curElem = jQuery( elem ),
9387                         curOffset = curElem.offset(),
9388                         curCSSTop = jQuery.css( elem, "top" ),
9389                         curCSSLeft = jQuery.css( elem, "left" ),
9390                         calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9391                         props = {}, curPosition = {}, curTop, curLeft;
9392
9393                 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9394                 if ( calculatePosition ) {
9395                         curPosition = curElem.position();
9396                         curTop = curPosition.top;
9397                         curLeft = curPosition.left;
9398                 } else {
9399                         curTop = parseFloat( curCSSTop ) || 0;
9400                         curLeft = parseFloat( curCSSLeft ) || 0;
9401                 }
9402
9403                 if ( jQuery.isFunction( options ) ) {
9404                         options = options.call( elem, i, curOffset );
9405                 }
9406
9407                 if (options.top != null) {
9408                         props.top = (options.top - curOffset.top) + curTop;
9409                 }
9410                 if (options.left != null) {
9411                         props.left = (options.left - curOffset.left) + curLeft;
9412                 }
9413
9414                 if ( "using" in options ) {
9415                         options.using.call( elem, props );
9416                 } else {
9417                         curElem.css( props );
9418                 }
9419         }
9420 };
9421
9422
9423 jQuery.fn.extend({
9424         position: function() {
9425                 if ( !this[0] ) {
9426                         return null;
9427                 }
9428
9429                 var elem = this[0],
9430
9431                 // Get *real* offsetParent
9432                 offsetParent = this.offsetParent(),
9433
9434                 // Get correct offsets
9435                 offset       = this.offset(),
9436                 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9437
9438                 // Subtract element margins
9439                 // note: when an element has margin: auto the offsetLeft and marginLeft
9440                 // are the same in Safari causing offset.left to incorrectly be 0
9441                 offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9442                 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9443
9444                 // Add offsetParent borders
9445                 parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9446                 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9447
9448                 // Subtract the two offsets
9449                 return {
9450                         top:  offset.top  - parentOffset.top,
9451                         left: offset.left - parentOffset.left
9452                 };
9453         },
9454
9455         offsetParent: function() {
9456                 return this.map(function() {
9457                         var offsetParent = this.offsetParent || document.body;
9458                         while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9459                                 offsetParent = offsetParent.offsetParent;
9460                         }
9461                         return offsetParent;
9462                 });
9463         }
9464 });
9465
9466
9467 // Create scrollLeft and scrollTop methods
9468 jQuery.each( ["Left", "Top"], function( i, name ) {
9469         var method = "scroll" + name;
9470
9471         jQuery.fn[ method ] = function( val ) {
9472                 var elem, win;
9473
9474                 if ( val === undefined ) {
9475                         elem = this[ 0 ];
9476
9477                         if ( !elem ) {
9478                                 return null;
9479                         }
9480
9481                         win = getWindow( elem );
9482
9483                         // Return the scroll offset
9484                         return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
9485                                 jQuery.support.boxModel && win.document.documentElement[ method ] ||
9486                                         win.document.body[ method ] :
9487                                 elem[ method ];
9488                 }
9489
9490                 // Set the scroll offset
9491                 return this.each(function() {
9492                         win = getWindow( this );
9493
9494                         if ( win ) {
9495                                 win.scrollTo(
9496                                         !i ? val : jQuery( win ).scrollLeft(),
9497                                          i ? val : jQuery( win ).scrollTop()
9498                                 );
9499
9500                         } else {
9501                                 this[ method ] = val;
9502                         }
9503                 });
9504         };
9505 });
9506
9507 function getWindow( elem ) {
9508         return jQuery.isWindow( elem ) ?
9509                 elem :
9510                 elem.nodeType === 9 ?
9511                         elem.defaultView || elem.parentWindow :
9512                         false;
9513 }
9514
9515
9516
9517
9518 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
9519 jQuery.each([ "Height", "Width" ], function( i, name ) {
9520
9521         var type = name.toLowerCase();
9522
9523         // innerHeight and innerWidth
9524         jQuery.fn["inner" + name] = function() {
9525                 return this[0] ?
9526                         parseFloat( jQuery.css( this[0], type, "padding" ) ) :
9527                         null;
9528         };
9529
9530         // outerHeight and outerWidth
9531         jQuery.fn["outer" + name] = function( margin ) {
9532                 return this[0] ?
9533                         parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
9534                         null;
9535         };
9536
9537         jQuery.fn[ type ] = function( size ) {
9538                 // Get window width or height
9539                 var elem = this[0];
9540                 if ( !elem ) {
9541                         return size == null ? null : this;
9542                 }
9543
9544                 if ( jQuery.isFunction( size ) ) {
9545                         return this.each(function( i ) {
9546                                 var self = jQuery( this );
9547                                 self[ type ]( size.call( this, i, self[ type ]() ) );
9548                         });
9549                 }
9550
9551                 if ( jQuery.isWindow( elem ) ) {
9552                         // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
9553                         // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
9554                         var docElemProp = elem.document.documentElement[ "client" + name ];
9555                         return elem.document.compatMode === "CSS1Compat" && docElemProp ||
9556                                 elem.document.body[ "client" + name ] || docElemProp;
9557
9558                 // Get document width or height
9559                 } else if ( elem.nodeType === 9 ) {
9560                         // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
9561                         return Math.max(
9562                                 elem.documentElement["client" + name],
9563                                 elem.body["scroll" + name], elem.documentElement["scroll" + name],
9564                                 elem.body["offset" + name], elem.documentElement["offset" + name]
9565                         );
9566
9567                 // Get or set width or height on the element
9568                 } else if ( size === undefined ) {
9569                         var orig = jQuery.css( elem, type ),
9570                                 ret = parseFloat( orig );
9571
9572                         return jQuery.isNaN( ret ) ? orig : ret;
9573
9574                 // Set the width or height on the element (default to pixels if value is unitless)
9575                 } else {
9576                         return this.css( type, typeof size === "string" ? size : size + "px" );
9577                 }
9578         };
9579
9580 });
9581
9582
9583 window.jQuery = window.$ = jQuery;
9584 })(window);
9585 /*!
9586  * jQuery UI 1.8.12
9587  *
9588  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
9589  * licensed under MIT 
9590  * http://jquery.org/license
9591  *
9592  * http://docs.jquery.com/UI
9593  */
9594 (function( $, undefined ) {
9595
9596 // prevent duplicate loading
9597 // this is only a problem because we proxy existing functions
9598 // and we don't want to double proxy them
9599 $.ui = $.ui || {};
9600 if ( $.ui.version ) {
9601         return;
9602 }
9603
9604 $.extend( $.ui, {
9605         version: "1.8.12",
9606
9607         keyCode: {
9608                 ALT: 18,
9609                 BACKSPACE: 8,
9610                 CAPS_LOCK: 20,
9611                 COMMA: 188,
9612                 COMMAND: 91,
9613                 COMMAND_LEFT: 91, // COMMAND
9614                 COMMAND_RIGHT: 93,
9615                 CONTROL: 17,
9616                 DELETE: 46,
9617                 DOWN: 40,
9618                 END: 35,
9619                 ENTER: 13,
9620                 ESCAPE: 27,
9621                 HOME: 36,
9622                 INSERT: 45,
9623                 LEFT: 37,
9624                 MENU: 93, // COMMAND_RIGHT
9625                 NUMPAD_ADD: 107,
9626                 NUMPAD_DECIMAL: 110,
9627                 NUMPAD_DIVIDE: 111,
9628                 NUMPAD_ENTER: 108,
9629                 NUMPAD_MULTIPLY: 106,
9630                 NUMPAD_SUBTRACT: 109,
9631                 PAGE_DOWN: 34,
9632                 PAGE_UP: 33,
9633                 PERIOD: 190,
9634                 RIGHT: 39,
9635                 SHIFT: 16,
9636                 SPACE: 32,
9637                 TAB: 9,
9638                 UP: 38,
9639                 WINDOWS: 91 // COMMAND
9640         }
9641 });
9642
9643 // plugins
9644 $.fn.extend({
9645         _focus: $.fn.focus,
9646         focus: function( delay, fn ) {
9647                 return typeof delay === "number" ?
9648                         this.each(function() {
9649                                 var elem = this;
9650                                 setTimeout(function() {
9651                                         $( elem ).focus();
9652                                         if ( fn ) {
9653                                                 fn.call( elem );
9654                                         }
9655                                 }, delay );
9656                         }) :
9657                         this._focus.apply( this, arguments );
9658         },
9659
9660         scrollParent: function() {
9661                 var scrollParent;
9662                 if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
9663                         scrollParent = this.parents().filter(function() {
9664                                 return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
9665                         }).eq(0);
9666                 } else {
9667                         scrollParent = this.parents().filter(function() {
9668                                 return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
9669                         }).eq(0);
9670                 }
9671
9672                 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
9673         },
9674
9675         zIndex: function( zIndex ) {
9676                 if ( zIndex !== undefined ) {
9677                         return this.css( "zIndex", zIndex );
9678                 }
9679
9680                 if ( this.length ) {
9681                         var elem = $( this[ 0 ] ), position, value;
9682                         while ( elem.length && elem[ 0 ] !== document ) {
9683                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
9684                                 // This makes behavior of this function consistent across browsers
9685                                 // WebKit always returns auto if the element is positioned
9686                                 position = elem.css( "position" );
9687                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
9688                                         // IE returns 0 when zIndex is not specified
9689                                         // other browsers return a string
9690                                         // we ignore the case of nested elements with an explicit value of 0
9691                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
9692                                         value = parseInt( elem.css( "zIndex" ), 10 );
9693                                         if ( !isNaN( value ) && value !== 0 ) {
9694                                                 return value;
9695                                         }
9696                                 }
9697                                 elem = elem.parent();
9698                         }
9699                 }
9700
9701                 return 0;
9702         },
9703
9704         disableSelection: function() {
9705                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
9706                         ".ui-disableSelection", function( event ) {
9707                                 event.preventDefault();
9708                         });
9709         },
9710
9711         enableSelection: function() {
9712                 return this.unbind( ".ui-disableSelection" );
9713         }
9714 });
9715
9716 $.each( [ "Width", "Height" ], function( i, name ) {
9717         var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
9718                 type = name.toLowerCase(),
9719                 orig = {
9720                         innerWidth: $.fn.innerWidth,
9721                         innerHeight: $.fn.innerHeight,
9722                         outerWidth: $.fn.outerWidth,
9723                         outerHeight: $.fn.outerHeight
9724                 };
9725
9726         function reduce( elem, size, border, margin ) {
9727                 $.each( side, function() {
9728                         size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
9729                         if ( border ) {
9730                                 size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
9731                         }
9732                         if ( margin ) {
9733                                 size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
9734                         }
9735                 });
9736                 return size;
9737         }
9738
9739         $.fn[ "inner" + name ] = function( size ) {
9740                 if ( size === undefined ) {
9741                         return orig[ "inner" + name ].call( this );
9742                 }
9743
9744                 return this.each(function() {
9745                         $( this ).css( type, reduce( this, size ) + "px" );
9746                 });
9747         };
9748
9749         $.fn[ "outer" + name] = function( size, margin ) {
9750                 if ( typeof size !== "number" ) {
9751                         return orig[ "outer" + name ].call( this, size );
9752                 }
9753
9754                 return this.each(function() {
9755                         $( this).css( type, reduce( this, size, true, margin ) + "px" );
9756                 });
9757         };
9758 });
9759
9760 // selectors
9761 function visible( element ) {
9762         return !$( element ).parents().andSelf().filter(function() {
9763                 return $.curCSS( this, "visibility" ) === "hidden" ||
9764                         $.expr.filters.hidden( this );
9765         }).length;
9766 }
9767
9768 $.extend( $.expr[ ":" ], {
9769         data: function( elem, i, match ) {
9770                 return !!$.data( elem, match[ 3 ] );
9771         },
9772
9773         focusable: function( element ) {
9774                 var nodeName = element.nodeName.toLowerCase(),
9775                         tabIndex = $.attr( element, "tabindex" );
9776                 if ( "area" === nodeName ) {
9777                         var map = element.parentNode,
9778                                 mapName = map.name,
9779                                 img;
9780                         if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
9781                                 return false;
9782                         }
9783                         img = $( "img[usemap=#" + mapName + "]" )[0];
9784                         return !!img && visible( img );
9785                 }
9786                 return ( /input|select|textarea|button|object/.test( nodeName )
9787                         ? !element.disabled
9788                         : "a" == nodeName
9789                                 ? element.href || !isNaN( tabIndex )
9790                                 : !isNaN( tabIndex ))
9791                         // the element and all of its ancestors must be visible
9792                         && visible( element );
9793         },
9794
9795         tabbable: function( element ) {
9796                 var tabIndex = $.attr( element, "tabindex" );
9797                 return ( isNaN( tabIndex ) || tabIndex >= 0 ) && $( element ).is( ":focusable" );
9798         }
9799 });
9800
9801 // support
9802 $(function() {
9803         var body = document.body,
9804                 div = body.appendChild( div = document.createElement( "div" ) );
9805
9806         $.extend( div.style, {
9807                 minHeight: "100px",
9808                 height: "auto",
9809                 padding: 0,
9810                 borderWidth: 0
9811         });
9812
9813         $.support.minHeight = div.offsetHeight === 100;
9814         $.support.selectstart = "onselectstart" in div;
9815
9816         // set display to none to avoid a layout bug in IE
9817         // http://dev.jquery.com/ticket/4014
9818         body.removeChild( div ).style.display = "none";
9819 });
9820
9821
9822
9823
9824
9825 // deprecated
9826 $.extend( $.ui, {
9827         // $.ui.plugin is deprecated.  Use the proxy pattern instead.
9828         plugin: {
9829                 add: function( module, option, set ) {
9830                         var proto = $.ui[ module ].prototype;
9831                         for ( var i in set ) {
9832                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
9833                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
9834                         }
9835                 },
9836                 call: function( instance, name, args ) {
9837                         var set = instance.plugins[ name ];
9838                         if ( !set || !instance.element[ 0 ].parentNode ) {
9839                                 return;
9840                         }
9841         
9842                         for ( var i = 0; i < set.length; i++ ) {
9843                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
9844                                         set[ i ][ 1 ].apply( instance.element, args );
9845                                 }
9846                         }
9847                 }
9848         },
9849         
9850         // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
9851         contains: function( a, b ) {
9852                 return document.compareDocumentPosition ?
9853                         a.compareDocumentPosition( b ) & 16 :
9854                         a !== b && a.contains( b );
9855         },
9856         
9857         // only used by resizable
9858         hasScroll: function( el, a ) {
9859         
9860                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
9861                 if ( $( el ).css( "overflow" ) === "hidden") {
9862                         return false;
9863                 }
9864         
9865                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
9866                         has = false;
9867         
9868                 if ( el[ scroll ] > 0 ) {
9869                         return true;
9870                 }
9871         
9872                 // TODO: determine which cases actually cause this to happen
9873                 // if the element doesn't have the scroll set, see if it's possible to
9874                 // set the scroll
9875                 el[ scroll ] = 1;
9876                 has = ( el[ scroll ] > 0 );
9877                 el[ scroll ] = 0;
9878                 return has;
9879         },
9880         
9881         // these are odd functions, fix the API or move into individual plugins
9882         isOverAxis: function( x, reference, size ) {
9883                 //Determines when x coordinate is over "b" element axis
9884                 return ( x > reference ) && ( x < ( reference + size ) );
9885         },
9886         isOver: function( y, x, top, left, height, width ) {
9887                 //Determines when x, y coordinates is over "b" element
9888                 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
9889         }
9890 });
9891
9892 })( jQuery );
9893 /*!
9894  * jQuery UI Widget 1.8.12
9895  *
9896  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
9897  * Dual licensed under the MIT or GPL Version 2 licenses.
9898  * http://jquery.org/license
9899  *
9900  * http://docs.jquery.com/UI/Widget
9901  */
9902 (function( $, undefined ) {
9903
9904 // jQuery 1.4+
9905 if ( $.cleanData ) {
9906         var _cleanData = $.cleanData;
9907         $.cleanData = function( elems ) {
9908                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
9909                         $( elem ).triggerHandler( "remove" );
9910                 }
9911                 _cleanData( elems );
9912         };
9913 } else {
9914         var _remove = $.fn.remove;
9915         $.fn.remove = function( selector, keepData ) {
9916                 return this.each(function() {
9917                         if ( !keepData ) {
9918                                 if ( !selector || $.filter( selector, [ this ] ).length ) {
9919                                         $( "*", this ).add( [ this ] ).each(function() {
9920                                                 $( this ).triggerHandler( "remove" );
9921                                         });
9922                                 }
9923                         }
9924                         return _remove.call( $(this), selector, keepData );
9925                 });
9926         };
9927 }
9928
9929 $.widget = function( name, base, prototype ) {
9930         var namespace = name.split( "." )[ 0 ],
9931                 fullName;
9932         name = name.split( "." )[ 1 ];
9933         fullName = namespace + "-" + name;
9934
9935         if ( !prototype ) {
9936                 prototype = base;
9937                 base = $.Widget;
9938         }
9939
9940         // create selector for plugin
9941         $.expr[ ":" ][ fullName ] = function( elem ) {
9942                 return !!$.data( elem, name );
9943         };
9944
9945         $[ namespace ] = $[ namespace ] || {};
9946         $[ namespace ][ name ] = function( options, element ) {
9947                 // allow instantiation without initializing for simple inheritance
9948                 if ( arguments.length ) {
9949                         this._createWidget( options, element );
9950                 }
9951         };
9952
9953         var basePrototype = new base();
9954         // we need to make the options hash a property directly on the new instance
9955         // otherwise we'll modify the options hash on the prototype that we're
9956         // inheriting from
9957 //      $.each( basePrototype, function( key, val ) {
9958 //              if ( $.isPlainObject(val) ) {
9959 //                      basePrototype[ key ] = $.extend( {}, val );
9960 //              }
9961 //      });
9962         basePrototype.options = $.extend( true, {}, basePrototype.options );
9963         $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
9964                 namespace: namespace,
9965                 widgetName: name,
9966                 widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
9967                 widgetBaseClass: fullName
9968         }, prototype );
9969
9970         $.widget.bridge( name, $[ namespace ][ name ] );
9971 };
9972
9973 $.widget.bridge = function( name, object ) {
9974         $.fn[ name ] = function( options ) {
9975                 var isMethodCall = typeof options === "string",
9976                         args = Array.prototype.slice.call( arguments, 1 ),
9977                         returnValue = this;
9978
9979                 // allow multiple hashes to be passed on init
9980                 options = !isMethodCall && args.length ?
9981                         $.extend.apply( null, [ true, options ].concat(args) ) :
9982                         options;
9983
9984                 // prevent calls to internal methods
9985                 if ( isMethodCall && options.charAt( 0 ) === "_" ) {
9986                         return returnValue;
9987                 }
9988
9989                 if ( isMethodCall ) {
9990                         this.each(function() {
9991                                 var instance = $.data( this, name ),
9992                                         methodValue = instance && $.isFunction( instance[options] ) ?
9993                                                 instance[ options ].apply( instance, args ) :
9994                                                 instance;
9995                                 // TODO: add this back in 1.9 and use $.error() (see #5972)
9996 //                              if ( !instance ) {
9997 //                                      throw "cannot call methods on " + name + " prior to initialization; " +
9998 //                                              "attempted to call method '" + options + "'";
9999 //                              }
10000 //                              if ( !$.isFunction( instance[options] ) ) {
10001 //                                      throw "no such method '" + options + "' for " + name + " widget instance";
10002 //                              }
10003 //                              var methodValue = instance[ options ].apply( instance, args );
10004                                 if ( methodValue !== instance && methodValue !== undefined ) {
10005                                         returnValue = methodValue;
10006                                         return false;
10007                                 }
10008                         });
10009                 } else {
10010                         this.each(function() {
10011                                 var instance = $.data( this, name );
10012                                 if ( instance ) {
10013                                         instance.option( options || {} )._init();
10014                                 } else {
10015                                         $.data( this, name, new object( options, this ) );
10016                                 }
10017                         });
10018                 }
10019
10020                 return returnValue;
10021         };
10022 };
10023
10024 $.Widget = function( options, element ) {
10025         // allow instantiation without initializing for simple inheritance
10026         if ( arguments.length ) {
10027                 this._createWidget( options, element );
10028         }
10029 };
10030
10031 $.Widget.prototype = {
10032         widgetName: "widget",
10033         widgetEventPrefix: "",
10034         options: {
10035                 disabled: false
10036         },
10037         _createWidget: function( options, element ) {
10038                 // $.widget.bridge stores the plugin instance, but we do it anyway
10039                 // so that it's stored even before the _create function runs
10040                 $.data( element, this.widgetName, this );
10041                 this.element = $( element );
10042                 this.options = $.extend( true, {},
10043                         this.options,
10044                         this._getCreateOptions(),
10045                         options );
10046
10047                 var self = this;
10048                 this.element.bind( "remove." + this.widgetName, function() {
10049                         self.destroy();
10050                 });
10051
10052                 this._create();
10053                 this._trigger( "create" );
10054                 this._init();
10055         },
10056         _getCreateOptions: function() {
10057                 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
10058         },
10059         _create: function() {},
10060         _init: function() {},
10061
10062         destroy: function() {
10063                 this.element
10064                         .unbind( "." + this.widgetName )
10065                         .removeData( this.widgetName );
10066                 this.widget()
10067                         .unbind( "." + this.widgetName )
10068                         .removeAttr( "aria-disabled" )
10069                         .removeClass(
10070                                 this.widgetBaseClass + "-disabled " +
10071                                 "ui-state-disabled" );
10072         },
10073
10074         widget: function() {
10075                 return this.element;
10076         },
10077
10078         option: function( key, value ) {
10079                 var options = key;
10080
10081                 if ( arguments.length === 0 ) {
10082                         // don't return a reference to the internal hash
10083                         return $.extend( {}, this.options );
10084                 }
10085
10086                 if  (typeof key === "string" ) {
10087                         if ( value === undefined ) {
10088                                 return this.options[ key ];
10089                         }
10090                         options = {};
10091                         options[ key ] = value;
10092                 }
10093
10094                 this._setOptions( options );
10095
10096                 return this;
10097         },
10098         _setOptions: function( options ) {
10099                 var self = this;
10100                 $.each( options, function( key, value ) {
10101                         self._setOption( key, value );
10102                 });
10103
10104                 return this;
10105         },
10106         _setOption: function( key, value ) {
10107                 this.options[ key ] = value;
10108
10109                 if ( key === "disabled" ) {
10110                         this.widget()
10111                                 [ value ? "addClass" : "removeClass"](
10112                                         this.widgetBaseClass + "-disabled" + " " +
10113                                         "ui-state-disabled" )
10114                                 .attr( "aria-disabled", value );
10115                 }
10116
10117                 return this;
10118         },
10119
10120         enable: function() {
10121                 return this._setOption( "disabled", false );
10122         },
10123         disable: function() {
10124                 return this._setOption( "disabled", true );
10125         },
10126
10127         _trigger: function( type, event, data ) {
10128                 var callback = this.options[ type ];
10129
10130                 event = $.Event( event );
10131                 event.type = ( type === this.widgetEventPrefix ?
10132                         type :
10133                         this.widgetEventPrefix + type ).toLowerCase();
10134                 data = data || {};
10135
10136                 // copy original event properties over to the new event
10137                 // this would happen if we could call $.event.fix instead of $.Event
10138                 // but we don't have a way to force an event to be fixed multiple times
10139                 if ( event.originalEvent ) {
10140                         for ( var i = $.event.props.length, prop; i; ) {
10141                                 prop = $.event.props[ --i ];
10142                                 event[ prop ] = event.originalEvent[ prop ];
10143                         }
10144                 }
10145
10146                 this.element.trigger( event, data );
10147
10148                 return !( $.isFunction(callback) &&
10149                         callback.call( this.element[0], event, data ) === false ||
10150                         event.isDefaultPrevented() );
10151         }
10152 };
10153
10154 })( jQuery );
10155 /*!
10156  * jQuery UI Mouse 1.8.12
10157  *
10158  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10159  * Dual licensed under the MIT or GPL Version 2 licenses.
10160  * http://jquery.org/license
10161  *
10162  * http://docs.jquery.com/UI/Mouse
10163  *
10164  * Depends:
10165  *      jquery.ui.widget.js
10166  */
10167 (function( $, undefined ) {
10168
10169 $.widget("ui.mouse", {
10170         options: {
10171                 cancel: ':input,option',
10172                 distance: 1,
10173                 delay: 0
10174         },
10175         _mouseInit: function() {
10176                 var self = this;
10177
10178                 this.element
10179                         .bind('mousedown.'+this.widgetName, function(event) {
10180                                 return self._mouseDown(event);
10181                         })
10182                         .bind('click.'+this.widgetName, function(event) {
10183                                 if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
10184                                     $.removeData(event.target, self.widgetName + '.preventClickEvent');
10185                                         event.stopImmediatePropagation();
10186                                         return false;
10187                                 }
10188                         });
10189
10190                 this.started = false;
10191         },
10192
10193         // TODO: make sure destroying one instance of mouse doesn't mess with
10194         // other instances of mouse
10195         _mouseDestroy: function() {
10196                 this.element.unbind('.'+this.widgetName);
10197         },
10198
10199         _mouseDown: function(event) {
10200                 // don't let more than one widget handle mouseStart
10201                 // TODO: figure out why we have to use originalEvent
10202                 event.originalEvent = event.originalEvent || {};
10203                 if (event.originalEvent.mouseHandled) { return; }
10204
10205                 // we may have missed mouseup (out of window)
10206                 (this._mouseStarted && this._mouseUp(event));
10207
10208                 this._mouseDownEvent = event;
10209
10210                 var self = this,
10211                         btnIsLeft = (event.which == 1),
10212                         elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
10213                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
10214                         return true;
10215                 }
10216
10217                 this.mouseDelayMet = !this.options.delay;
10218                 if (!this.mouseDelayMet) {
10219                         this._mouseDelayTimer = setTimeout(function() {
10220                                 self.mouseDelayMet = true;
10221                         }, this.options.delay);
10222                 }
10223
10224                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
10225                         this._mouseStarted = (this._mouseStart(event) !== false);
10226                         if (!this._mouseStarted) {
10227                                 event.preventDefault();
10228                                 return true;
10229                         }
10230                 }
10231
10232                 // Click event may never have fired (Gecko & Opera)
10233                 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
10234                         $.removeData(event.target, this.widgetName + '.preventClickEvent');
10235                 }
10236
10237                 // these delegates are required to keep context
10238                 this._mouseMoveDelegate = function(event) {
10239                         return self._mouseMove(event);
10240                 };
10241                 this._mouseUpDelegate = function(event) {
10242                         return self._mouseUp(event);
10243                 };
10244                 $(document)
10245                         .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
10246                         .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
10247
10248                 event.preventDefault();
10249                 event.originalEvent.mouseHandled = true;
10250                 return true;
10251         },
10252
10253         _mouseMove: function(event) {
10254                 // IE mouseup check - mouseup happened when mouse was out of window
10255                 if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
10256                         return this._mouseUp(event);
10257                 }
10258
10259                 if (this._mouseStarted) {
10260                         this._mouseDrag(event);
10261                         return event.preventDefault();
10262                 }
10263
10264                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
10265                         this._mouseStarted =
10266                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
10267                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
10268                 }
10269
10270                 return !this._mouseStarted;
10271         },
10272
10273         _mouseUp: function(event) {
10274                 $(document)
10275                         .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
10276                         .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
10277
10278                 if (this._mouseStarted) {
10279                         this._mouseStarted = false;
10280
10281                         if (event.target == this._mouseDownEvent.target) {
10282                             $.data(event.target, this.widgetName + '.preventClickEvent', true);
10283                         }
10284
10285                         this._mouseStop(event);
10286                 }
10287
10288                 return false;
10289         },
10290
10291         _mouseDistanceMet: function(event) {
10292                 return (Math.max(
10293                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
10294                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
10295                         ) >= this.options.distance
10296                 );
10297         },
10298
10299         _mouseDelayMet: function(event) {
10300                 return this.mouseDelayMet;
10301         },
10302
10303         // These are placeholder methods, to be overriden by extending plugin
10304         _mouseStart: function(event) {},
10305         _mouseDrag: function(event) {},
10306         _mouseStop: function(event) {},
10307         _mouseCapture: function(event) { return true; }
10308 });
10309
10310 })(jQuery);
10311 /*
10312  * jQuery UI Draggable 1.8.12
10313  *
10314  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10315  * Dual licensed under the MIT or GPL Version 2 licenses.
10316  * http://jquery.org/license
10317  *
10318  * http://docs.jquery.com/UI/Draggables
10319  *
10320  * Depends:
10321  *      jquery.ui.core.js
10322  *      jquery.ui.mouse.js
10323  *      jquery.ui.widget.js
10324  */
10325 (function( $, undefined ) {
10326
10327 $.widget("ui.draggable", $.ui.mouse, {
10328         widgetEventPrefix: "drag",
10329         options: {
10330                 addClasses: true,
10331                 appendTo: "parent",
10332                 axis: false,
10333                 connectToSortable: false,
10334                 containment: false,
10335                 cursor: "auto",
10336                 cursorAt: false,
10337                 grid: false,
10338                 handle: false,
10339                 helper: "original",
10340                 iframeFix: false,
10341                 opacity: false,
10342                 refreshPositions: false,
10343                 revert: false,
10344                 revertDuration: 500,
10345                 scope: "default",
10346                 scroll: true,
10347                 scrollSensitivity: 20,
10348                 scrollSpeed: 20,
10349                 snap: false,
10350                 snapMode: "both",
10351                 snapTolerance: 20,
10352                 stack: false,
10353                 zIndex: false
10354         },
10355         _create: function() {
10356
10357                 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
10358                         this.element[0].style.position = 'relative';
10359
10360                 (this.options.addClasses && this.element.addClass("ui-draggable"));
10361                 (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
10362
10363                 this._mouseInit();
10364
10365         },
10366
10367         destroy: function() {
10368                 if(!this.element.data('draggable')) return;
10369                 this.element
10370                         .removeData("draggable")
10371                         .unbind(".draggable")
10372                         .removeClass("ui-draggable"
10373                                 + " ui-draggable-dragging"
10374                                 + " ui-draggable-disabled");
10375                 this._mouseDestroy();
10376
10377                 return this;
10378         },
10379
10380         _mouseCapture: function(event) {
10381
10382                 var o = this.options;
10383
10384                 // among others, prevent a drag on a resizable-handle
10385                 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
10386                         return false;
10387
10388                 //Quit if we're not on a valid handle
10389                 this.handle = this._getHandle(event);
10390                 if (!this.handle)
10391                         return false;
10392
10393                 return true;
10394
10395         },
10396
10397         _mouseStart: function(event) {
10398
10399                 var o = this.options;
10400
10401                 //Create and append the visible helper
10402                 this.helper = this._createHelper(event);
10403
10404                 //Cache the helper size
10405                 this._cacheHelperProportions();
10406
10407                 //If ddmanager is used for droppables, set the global draggable
10408                 if($.ui.ddmanager)
10409                         $.ui.ddmanager.current = this;
10410
10411                 /*
10412                  * - Position generation -
10413                  * This block generates everything position related - it's the core of draggables.
10414                  */
10415
10416                 //Cache the margins of the original element
10417                 this._cacheMargins();
10418
10419                 //Store the helper's css position
10420                 this.cssPosition = this.helper.css("position");
10421                 this.scrollParent = this.helper.scrollParent();
10422
10423                 //The element's absolute position on the page minus margins
10424                 this.offset = this.positionAbs = this.element.offset();
10425                 this.offset = {
10426                         top: this.offset.top - this.margins.top,
10427                         left: this.offset.left - this.margins.left
10428                 };
10429
10430                 $.extend(this.offset, {
10431                         click: { //Where the click happened, relative to the element
10432                                 left: event.pageX - this.offset.left,
10433                                 top: event.pageY - this.offset.top
10434                         },
10435                         parent: this._getParentOffset(),
10436                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
10437                 });
10438
10439                 //Generate the original position
10440                 this.originalPosition = this.position = this._generatePosition(event);
10441                 this.originalPageX = event.pageX;
10442                 this.originalPageY = event.pageY;
10443
10444                 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
10445                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
10446
10447                 //Set a containment if given in the options
10448                 if(o.containment)
10449                         this._setContainment();
10450
10451                 //Trigger event + callbacks
10452                 if(this._trigger("start", event) === false) {
10453                         this._clear();
10454                         return false;
10455                 }
10456
10457                 //Recache the helper size
10458                 this._cacheHelperProportions();
10459
10460                 //Prepare the droppable offsets
10461                 if ($.ui.ddmanager && !o.dropBehaviour)
10462                         $.ui.ddmanager.prepareOffsets(this, event);
10463
10464                 this.helper.addClass("ui-draggable-dragging");
10465                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
10466                 return true;
10467         },
10468
10469         _mouseDrag: function(event, noPropagation) {
10470
10471                 //Compute the helpers position
10472                 this.position = this._generatePosition(event);
10473                 this.positionAbs = this._convertPositionTo("absolute");
10474
10475                 //Call plugins and callbacks and use the resulting position if something is returned
10476                 if (!noPropagation) {
10477                         var ui = this._uiHash();
10478                         if(this._trigger('drag', event, ui) === false) {
10479                                 this._mouseUp({});
10480                                 return false;
10481                         }
10482                         this.position = ui.position;
10483                 }
10484
10485                 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
10486                 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
10487                 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
10488
10489                 return false;
10490         },
10491
10492         _mouseStop: function(event) {
10493
10494                 //If we are using droppables, inform the manager about the drop
10495                 var dropped = false;
10496                 if ($.ui.ddmanager && !this.options.dropBehaviour)
10497                         dropped = $.ui.ddmanager.drop(this, event);
10498
10499                 //if a drop comes from outside (a sortable)
10500                 if(this.dropped) {
10501                         dropped = this.dropped;
10502                         this.dropped = false;
10503                 }
10504                 
10505                 //if the original element is removed, don't bother to continue if helper is set to "original"
10506                 if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
10507                         return false;
10508
10509                 if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
10510                         var self = this;
10511                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
10512                                 if(self._trigger("stop", event) !== false) {
10513                                         self._clear();
10514                                 }
10515                         });
10516                 } else {
10517                         if(this._trigger("stop", event) !== false) {
10518                                 this._clear();
10519                         }
10520                 }
10521
10522                 return false;
10523         },
10524         
10525         cancel: function() {
10526                 
10527                 if(this.helper.is(".ui-draggable-dragging")) {
10528                         this._mouseUp({});
10529                 } else {
10530                         this._clear();
10531                 }
10532                 
10533                 return this;
10534                 
10535         },
10536
10537         _getHandle: function(event) {
10538
10539                 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
10540                 $(this.options.handle, this.element)
10541                         .find("*")
10542                         .andSelf()
10543                         .each(function() {
10544                                 if(this == event.target) handle = true;
10545                         });
10546
10547                 return handle;
10548
10549         },
10550
10551         _createHelper: function(event) {
10552
10553                 var o = this.options;
10554                 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
10555
10556                 if(!helper.parents('body').length)
10557                         helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
10558
10559                 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
10560                         helper.css("position", "absolute");
10561
10562                 return helper;
10563
10564         },
10565
10566         _adjustOffsetFromHelper: function(obj) {
10567                 if (typeof obj == 'string') {
10568                         obj = obj.split(' ');
10569                 }
10570                 if ($.isArray(obj)) {
10571                         obj = {left: +obj[0], top: +obj[1] || 0};
10572                 }
10573                 if ('left' in obj) {
10574                         this.offset.click.left = obj.left + this.margins.left;
10575                 }
10576                 if ('right' in obj) {
10577                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
10578                 }
10579                 if ('top' in obj) {
10580                         this.offset.click.top = obj.top + this.margins.top;
10581                 }
10582                 if ('bottom' in obj) {
10583                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
10584                 }
10585         },
10586
10587         _getParentOffset: function() {
10588
10589                 //Get the offsetParent and cache its position
10590                 this.offsetParent = this.helper.offsetParent();
10591                 var po = this.offsetParent.offset();
10592
10593                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
10594                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
10595                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
10596                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
10597                 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
10598                         po.left += this.scrollParent.scrollLeft();
10599                         po.top += this.scrollParent.scrollTop();
10600                 }
10601
10602                 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
10603                 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
10604                         po = { top: 0, left: 0 };
10605
10606                 return {
10607                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
10608                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
10609                 };
10610
10611         },
10612
10613         _getRelativeOffset: function() {
10614
10615                 if(this.cssPosition == "relative") {
10616                         var p = this.element.position();
10617                         return {
10618                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
10619                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
10620                         };
10621                 } else {
10622                         return { top: 0, left: 0 };
10623                 }
10624
10625         },
10626
10627         _cacheMargins: function() {
10628                 this.margins = {
10629                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
10630                         top: (parseInt(this.element.css("marginTop"),10) || 0),
10631                         right: (parseInt(this.element.css("marginRight"),10) || 0),
10632                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
10633                 };
10634         },
10635
10636         _cacheHelperProportions: function() {
10637                 this.helperProportions = {
10638                         width: this.helper.outerWidth(),
10639                         height: this.helper.outerHeight()
10640                 };
10641         },
10642
10643         _setContainment: function() {
10644
10645                 var o = this.options;
10646                 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
10647                 if(o.containment == 'document' || o.containment == 'window') this.containment = [
10648                         (o.containment == 'document' ? 0 : $(window).scrollLeft()) - this.offset.relative.left - this.offset.parent.left,
10649                         (o.containment == 'document' ? 0 : $(window).scrollTop()) - this.offset.relative.top - this.offset.parent.top,
10650                         (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
10651                         (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
10652                 ];
10653
10654                 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
10655                         var ce = $(o.containment)[0]; if(!ce) return;
10656                         var co = $(o.containment).offset();
10657                         var over = ($(ce).css("overflow") != 'hidden');
10658
10659                         this.containment = [
10660                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
10661                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
10662                                 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
10663                                 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
10664                         ];
10665                 } else if(o.containment.constructor == Array) {
10666                         this.containment = o.containment;
10667                 }
10668
10669         },
10670
10671         _convertPositionTo: function(d, pos) {
10672
10673                 if(!pos) pos = this.position;
10674                 var mod = d == "absolute" ? 1 : -1;
10675                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
10676
10677                 return {
10678                         top: (
10679                                 pos.top                                                                                                                                 // The absolute mouse position
10680                                 + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
10681                                 + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
10682                                 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
10683                         ),
10684                         left: (
10685                                 pos.left                                                                                                                                // The absolute mouse position
10686                                 + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
10687                                 + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
10688                                 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
10689                         )
10690                 };
10691
10692         },
10693
10694         _generatePosition: function(event) {
10695
10696                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
10697                 var pageX = event.pageX;
10698                 var pageY = event.pageY;
10699
10700                 /*
10701                  * - Position constraining -
10702                  * Constrain the position to a mix of grid, containment.
10703                  */
10704
10705                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
10706
10707                         if(this.containment) {
10708                                 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
10709                                 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
10710                                 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
10711                                 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
10712                         }
10713
10714                         if(o.grid) {
10715                                 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
10716                                 pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
10717
10718                                 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
10719                                 pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
10720                         }
10721
10722                 }
10723
10724                 return {
10725                         top: (
10726                                 pageY                                                                                                                           // The absolute mouse position
10727                                 - this.offset.click.top                                                                                                 // Click offset (relative to the element)
10728                                 - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
10729                                 - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
10730                                 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
10731                         ),
10732                         left: (
10733                                 pageX                                                                                                                           // The absolute mouse position
10734                                 - this.offset.click.left                                                                                                // Click offset (relative to the element)
10735                                 - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
10736                                 - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
10737                                 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
10738                         )
10739                 };
10740
10741         },
10742
10743         _clear: function() {
10744                 this.helper.removeClass("ui-draggable-dragging");
10745                 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
10746                 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
10747                 this.helper = null;
10748                 this.cancelHelperRemoval = false;
10749         },
10750
10751         // From now on bulk stuff - mainly helpers
10752
10753         _trigger: function(type, event, ui) {
10754                 ui = ui || this._uiHash();
10755                 $.ui.plugin.call(this, type, [event, ui]);
10756                 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
10757                 return $.Widget.prototype._trigger.call(this, type, event, ui);
10758         },
10759
10760         plugins: {},
10761
10762         _uiHash: function(event) {
10763                 return {
10764                         helper: this.helper,
10765                         position: this.position,
10766                         originalPosition: this.originalPosition,
10767                         offset: this.positionAbs
10768                 };
10769         }
10770
10771 });
10772
10773 $.extend($.ui.draggable, {
10774         version: "1.8.12"
10775 });
10776
10777 $.ui.plugin.add("draggable", "connectToSortable", {
10778         start: function(event, ui) {
10779
10780                 var inst = $(this).data("draggable"), o = inst.options,
10781                         uiSortable = $.extend({}, ui, { item: inst.element });
10782                 inst.sortables = [];
10783                 $(o.connectToSortable).each(function() {
10784                         var sortable = $.data(this, 'sortable');
10785                         if (sortable && !sortable.options.disabled) {
10786                                 inst.sortables.push({
10787                                         instance: sortable,
10788                                         shouldRevert: sortable.options.revert
10789                                 });
10790                                 sortable.refreshPositions();    // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
10791                                 sortable._trigger("activate", event, uiSortable);
10792                         }
10793                 });
10794
10795         },
10796         stop: function(event, ui) {
10797
10798                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
10799                 var inst = $(this).data("draggable"),
10800                         uiSortable = $.extend({}, ui, { item: inst.element });
10801
10802                 $.each(inst.sortables, function() {
10803                         if(this.instance.isOver) {
10804
10805                                 this.instance.isOver = 0;
10806
10807                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
10808                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
10809
10810                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
10811                                 if(this.shouldRevert) this.instance.options.revert = true;
10812
10813                                 //Trigger the stop of the sortable
10814                                 this.instance._mouseStop(event);
10815
10816                                 this.instance.options.helper = this.instance.options._helper;
10817
10818                                 //If the helper has been the original item, restore properties in the sortable
10819                                 if(inst.options.helper == 'original')
10820                                         this.instance.currentItem.css({ top: 'auto', left: 'auto' });
10821
10822                         } else {
10823                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
10824                                 this.instance._trigger("deactivate", event, uiSortable);
10825                         }
10826
10827                 });
10828
10829         },
10830         drag: function(event, ui) {
10831
10832                 var inst = $(this).data("draggable"), self = this;
10833
10834                 var checkPos = function(o) {
10835                         var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
10836                         var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
10837                         var itemHeight = o.height, itemWidth = o.width;
10838                         var itemTop = o.top, itemLeft = o.left;
10839
10840                         return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
10841                 };
10842
10843                 $.each(inst.sortables, function(i) {
10844                         
10845                         //Copy over some variables to allow calling the sortable's native _intersectsWith
10846                         this.instance.positionAbs = inst.positionAbs;
10847                         this.instance.helperProportions = inst.helperProportions;
10848                         this.instance.offset.click = inst.offset.click;
10849                         
10850                         if(this.instance._intersectsWith(this.instance.containerCache)) {
10851
10852                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
10853                                 if(!this.instance.isOver) {
10854
10855                                         this.instance.isOver = 1;
10856                                         //Now we fake the start of dragging for the sortable instance,
10857                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
10858                                         //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
10859                                         this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
10860                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
10861                                         this.instance.options.helper = function() { return ui.helper[0]; };
10862
10863                                         event.target = this.instance.currentItem[0];
10864                                         this.instance._mouseCapture(event, true);
10865                                         this.instance._mouseStart(event, true, true);
10866
10867                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
10868                                         this.instance.offset.click.top = inst.offset.click.top;
10869                                         this.instance.offset.click.left = inst.offset.click.left;
10870                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
10871                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
10872
10873                                         inst._trigger("toSortable", event);
10874                                         inst.dropped = this.instance.element; //draggable revert needs that
10875                                         //hack so receive/update callbacks work (mostly)
10876                                         inst.currentItem = inst.element;
10877                                         this.instance.fromOutside = inst;
10878
10879                                 }
10880
10881                                 //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
10882                                 if(this.instance.currentItem) this.instance._mouseDrag(event);
10883
10884                         } else {
10885
10886                                 //If it doesn't intersect with the sortable, and it intersected before,
10887                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
10888                                 if(this.instance.isOver) {
10889
10890                                         this.instance.isOver = 0;
10891                                         this.instance.cancelHelperRemoval = true;
10892                                         
10893                                         //Prevent reverting on this forced stop
10894                                         this.instance.options.revert = false;
10895                                         
10896                                         // The out event needs to be triggered independently
10897                                         this.instance._trigger('out', event, this.instance._uiHash(this.instance));
10898                                         
10899                                         this.instance._mouseStop(event, true);
10900                                         this.instance.options.helper = this.instance.options._helper;
10901
10902                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
10903                                         this.instance.currentItem.remove();
10904                                         if(this.instance.placeholder) this.instance.placeholder.remove();
10905
10906                                         inst._trigger("fromSortable", event);
10907                                         inst.dropped = false; //draggable revert needs that
10908                                 }
10909
10910                         };
10911
10912                 });
10913
10914         }
10915 });
10916
10917 $.ui.plugin.add("draggable", "cursor", {
10918         start: function(event, ui) {
10919                 var t = $('body'), o = $(this).data('draggable').options;
10920                 if (t.css("cursor")) o._cursor = t.css("cursor");
10921                 t.css("cursor", o.cursor);
10922         },
10923         stop: function(event, ui) {
10924                 var o = $(this).data('draggable').options;
10925                 if (o._cursor) $('body').css("cursor", o._cursor);
10926         }
10927 });
10928
10929 $.ui.plugin.add("draggable", "iframeFix", {
10930         start: function(event, ui) {
10931                 var o = $(this).data('draggable').options;
10932                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
10933                         $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
10934                         .css({
10935                                 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
10936                                 position: "absolute", opacity: "0.001", zIndex: 1000
10937                         })
10938                         .css($(this).offset())
10939                         .appendTo("body");
10940                 });
10941         },
10942         stop: function(event, ui) {
10943                 $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
10944         }
10945 });
10946
10947 $.ui.plugin.add("draggable", "opacity", {
10948         start: function(event, ui) {
10949                 var t = $(ui.helper), o = $(this).data('draggable').options;
10950                 if(t.css("opacity")) o._opacity = t.css("opacity");
10951                 t.css('opacity', o.opacity);
10952         },
10953         stop: function(event, ui) {
10954                 var o = $(this).data('draggable').options;
10955                 if(o._opacity) $(ui.helper).css('opacity', o._opacity);
10956         }
10957 });
10958
10959 $.ui.plugin.add("draggable", "scroll", {
10960         start: function(event, ui) {
10961                 var i = $(this).data("draggable");
10962                 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
10963         },
10964         drag: function(event, ui) {
10965
10966                 var i = $(this).data("draggable"), o = i.options, scrolled = false;
10967
10968                 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
10969
10970                         if(!o.axis || o.axis != 'x') {
10971                                 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
10972                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
10973                                 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
10974                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
10975                         }
10976
10977                         if(!o.axis || o.axis != 'y') {
10978                                 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
10979                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
10980                                 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
10981                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
10982                         }
10983
10984                 } else {
10985
10986                         if(!o.axis || o.axis != 'x') {
10987                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
10988                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
10989                                 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
10990                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
10991                         }
10992
10993                         if(!o.axis || o.axis != 'y') {
10994                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
10995                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
10996                                 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
10997                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
10998                         }
10999
11000                 }
11001
11002                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
11003                         $.ui.ddmanager.prepareOffsets(i, event);
11004
11005         }
11006 });
11007
11008 $.ui.plugin.add("draggable", "snap", {
11009         start: function(event, ui) {
11010
11011                 var i = $(this).data("draggable"), o = i.options;
11012                 i.snapElements = [];
11013
11014                 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
11015                         var $t = $(this); var $o = $t.offset();
11016                         if(this != i.element[0]) i.snapElements.push({
11017                                 item: this,
11018                                 width: $t.outerWidth(), height: $t.outerHeight(),
11019                                 top: $o.top, left: $o.left
11020                         });
11021                 });
11022
11023         },
11024         drag: function(event, ui) {
11025
11026                 var inst = $(this).data("draggable"), o = inst.options;
11027                 var d = o.snapTolerance;
11028
11029                 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
11030                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
11031
11032                 for (var i = inst.snapElements.length - 1; i >= 0; i--){
11033
11034                         var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
11035                                 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
11036
11037                         //Yes, I know, this is insane ;)
11038                         if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
11039                                 if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
11040                                 inst.snapElements[i].snapping = false;
11041                                 continue;
11042                         }
11043
11044                         if(o.snapMode != 'inner') {
11045                                 var ts = Math.abs(t - y2) <= d;
11046                                 var bs = Math.abs(b - y1) <= d;
11047                                 var ls = Math.abs(l - x2) <= d;
11048                                 var rs = Math.abs(r - x1) <= d;
11049                                 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
11050                                 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
11051                                 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
11052                                 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
11053                         }
11054
11055                         var first = (ts || bs || ls || rs);
11056
11057                         if(o.snapMode != 'outer') {
11058                                 var ts = Math.abs(t - y1) <= d;
11059                                 var bs = Math.abs(b - y2) <= d;
11060                                 var ls = Math.abs(l - x1) <= d;
11061                                 var rs = Math.abs(r - x2) <= d;
11062                                 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
11063                                 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
11064                                 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
11065                                 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
11066                         }
11067
11068                         if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
11069                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
11070                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
11071
11072                 };
11073
11074         }
11075 });
11076
11077 $.ui.plugin.add("draggable", "stack", {
11078         start: function(event, ui) {
11079
11080                 var o = $(this).data("draggable").options;
11081
11082                 var group = $.makeArray($(o.stack)).sort(function(a,b) {
11083                         return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
11084                 });
11085                 if (!group.length) { return; }
11086                 
11087                 var min = parseInt(group[0].style.zIndex) || 0;
11088                 $(group).each(function(i) {
11089                         this.style.zIndex = min + i;
11090                 });
11091
11092                 this[0].style.zIndex = min + group.length;
11093
11094         }
11095 });
11096
11097 $.ui.plugin.add("draggable", "zIndex", {
11098         start: function(event, ui) {
11099                 var t = $(ui.helper), o = $(this).data("draggable").options;
11100                 if(t.css("zIndex")) o._zIndex = t.css("zIndex");
11101                 t.css('zIndex', o.zIndex);
11102         },
11103         stop: function(event, ui) {
11104                 var o = $(this).data("draggable").options;
11105                 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
11106         }
11107 });
11108
11109 })(jQuery);
11110 /*
11111  * jQuery UI Droppable 1.8.12
11112  *
11113  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11114  * Dual licensed under the MIT or GPL Version 2 licenses.
11115  * http://jquery.org/license
11116  *
11117  * http://docs.jquery.com/UI/Droppables
11118  *
11119  * Depends:
11120  *      jquery.ui.core.js
11121  *      jquery.ui.widget.js
11122  *      jquery.ui.mouse.js
11123  *      jquery.ui.draggable.js
11124  */
11125 (function( $, undefined ) {
11126
11127 $.widget("ui.droppable", {
11128         widgetEventPrefix: "drop",
11129         options: {
11130                 accept: '*',
11131                 activeClass: false,
11132                 addClasses: true,
11133                 greedy: false,
11134                 hoverClass: false,
11135                 scope: 'default',
11136                 tolerance: 'intersect'
11137         },
11138         _create: function() {
11139
11140                 var o = this.options, accept = o.accept;
11141                 this.isover = 0; this.isout = 1;
11142
11143                 this.accept = $.isFunction(accept) ? accept : function(d) {
11144                         return d.is(accept);
11145                 };
11146
11147                 //Store the droppable's proportions
11148                 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
11149
11150                 // Add the reference and positions to the manager
11151                 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
11152                 $.ui.ddmanager.droppables[o.scope].push(this);
11153
11154                 (o.addClasses && this.element.addClass("ui-droppable"));
11155
11156         },
11157
11158         destroy: function() {
11159                 var drop = $.ui.ddmanager.droppables[this.options.scope];
11160                 for ( var i = 0; i < drop.length; i++ )
11161                         if ( drop[i] == this )
11162                                 drop.splice(i, 1);
11163
11164                 this.element
11165                         .removeClass("ui-droppable ui-droppable-disabled")
11166                         .removeData("droppable")
11167                         .unbind(".droppable");
11168
11169                 return this;
11170         },
11171
11172         _setOption: function(key, value) {
11173
11174                 if(key == 'accept') {
11175                         this.accept = $.isFunction(value) ? value : function(d) {
11176                                 return d.is(value);
11177                         };
11178                 }
11179                 $.Widget.prototype._setOption.apply(this, arguments);
11180         },
11181
11182         _activate: function(event) {
11183                 var draggable = $.ui.ddmanager.current;
11184                 if(this.options.activeClass) this.element.addClass(this.options.activeClass);
11185                 (draggable && this._trigger('activate', event, this.ui(draggable)));
11186         },
11187
11188         _deactivate: function(event) {
11189                 var draggable = $.ui.ddmanager.current;
11190                 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
11191                 (draggable && this._trigger('deactivate', event, this.ui(draggable)));
11192         },
11193
11194         _over: function(event) {
11195
11196                 var draggable = $.ui.ddmanager.current;
11197                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
11198
11199                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
11200                         if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
11201                         this._trigger('over', event, this.ui(draggable));
11202                 }
11203
11204         },
11205
11206         _out: function(event) {
11207
11208                 var draggable = $.ui.ddmanager.current;
11209                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
11210
11211                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
11212                         if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
11213                         this._trigger('out', event, this.ui(draggable));
11214                 }
11215
11216         },
11217
11218         _drop: function(event,custom) {
11219
11220                 var draggable = custom || $.ui.ddmanager.current;
11221                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
11222
11223                 var childrenIntersection = false;
11224                 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
11225                         var inst = $.data(this, 'droppable');
11226                         if(
11227                                 inst.options.greedy
11228                                 && !inst.options.disabled
11229                                 && inst.options.scope == draggable.options.scope
11230                                 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
11231                                 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
11232                         ) { childrenIntersection = true; return false; }
11233                 });
11234                 if(childrenIntersection) return false;
11235
11236                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
11237                         if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
11238                         if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
11239                         this._trigger('drop', event, this.ui(draggable));
11240                         return this.element;
11241                 }
11242
11243                 return false;
11244
11245         },
11246
11247         ui: function(c) {
11248                 return {
11249                         draggable: (c.currentItem || c.element),
11250                         helper: c.helper,
11251                         position: c.position,
11252                         offset: c.positionAbs
11253                 };
11254         }
11255
11256 });
11257
11258 $.extend($.ui.droppable, {
11259         version: "1.8.12"
11260 });
11261
11262 $.ui.intersect = function(draggable, droppable, toleranceMode) {
11263
11264         if (!droppable.offset) return false;
11265
11266         var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
11267                 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
11268         var l = droppable.offset.left, r = l + droppable.proportions.width,
11269                 t = droppable.offset.top, b = t + droppable.proportions.height;
11270
11271         switch (toleranceMode) {
11272                 case 'fit':
11273                         return (l <= x1 && x2 <= r
11274                                 && t <= y1 && y2 <= b);
11275                         break;
11276                 case 'intersect':
11277                         return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
11278                                 && x2 - (draggable.helperProportions.width / 2) < r // Left Half
11279                                 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
11280                                 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
11281                         break;
11282                 case 'pointer':
11283                         var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
11284                                 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
11285                                 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
11286                         return isOver;
11287                         break;
11288                 case 'touch':
11289                         return (
11290                                         (y1 >= t && y1 <= b) || // Top edge touching
11291                                         (y2 >= t && y2 <= b) || // Bottom edge touching
11292                                         (y1 < t && y2 > b)              // Surrounded vertically
11293                                 ) && (
11294                                         (x1 >= l && x1 <= r) || // Left edge touching
11295                                         (x2 >= l && x2 <= r) || // Right edge touching
11296                                         (x1 < l && x2 > r)              // Surrounded horizontally
11297                                 );
11298                         break;
11299                 default:
11300                         return false;
11301                         break;
11302                 }
11303
11304 };
11305
11306 /*
11307         This manager tracks offsets of draggables and droppables
11308 */
11309 $.ui.ddmanager = {
11310         current: null,
11311         droppables: { 'default': [] },
11312         prepareOffsets: function(t, event) {
11313
11314                 var m = $.ui.ddmanager.droppables[t.options.scope] || [];
11315                 var type = event ? event.type : null; // workaround for #2317
11316                 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
11317
11318                 droppablesLoop: for (var i = 0; i < m.length; i++) {
11319
11320                         if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;   //No disabled and non-accepted
11321                         for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
11322                         m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                                                       //If the element is not visible, continue
11323
11324                         if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
11325
11326                         m[i].offset = m[i].element.offset();
11327                         m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
11328
11329                 }
11330
11331         },
11332         drop: function(draggable, event) {
11333
11334                 var dropped = false;
11335                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
11336
11337                         if(!this.options) return;
11338                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
11339                                 dropped = dropped || this._drop.call(this, event);
11340
11341                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
11342                                 this.isout = 1; this.isover = 0;
11343                                 this._deactivate.call(this, event);
11344                         }
11345
11346                 });
11347                 return dropped;
11348
11349         },
11350         drag: function(draggable, event) {
11351
11352                 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
11353                 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
11354
11355                 //Run through all droppables and check their positions based on specific tolerance options
11356                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
11357
11358                         if(this.options.disabled || this.greedyChild || !this.visible) return;
11359                         var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
11360
11361                         var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
11362                         if(!c) return;
11363
11364                         var parentInstance;
11365                         if (this.options.greedy) {
11366                                 var parent = this.element.parents(':data(droppable):eq(0)');
11367                                 if (parent.length) {
11368                                         parentInstance = $.data(parent[0], 'droppable');
11369                                         parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
11370                                 }
11371                         }
11372
11373                         // we just moved into a greedy child
11374                         if (parentInstance && c == 'isover') {
11375                                 parentInstance['isover'] = 0;
11376                                 parentInstance['isout'] = 1;
11377                                 parentInstance._out.call(parentInstance, event);
11378                         }
11379
11380                         this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
11381                         this[c == "isover" ? "_over" : "_out"].call(this, event);
11382
11383                         // we just moved out of a greedy child
11384                         if (parentInstance && c == 'isout') {
11385                                 parentInstance['isout'] = 0;
11386                                 parentInstance['isover'] = 1;
11387                                 parentInstance._over.call(parentInstance, event);
11388                         }
11389                 });
11390
11391         }
11392 };
11393
11394 })(jQuery);
11395 /*
11396  * jQuery UI Resizable 1.8.12
11397  *
11398  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11399  * Dual licensed under the MIT or GPL Version 2 licenses.
11400  * http://jquery.org/license
11401  *
11402  * http://docs.jquery.com/UI/Resizables
11403  *
11404  * Depends:
11405  *      jquery.ui.core.js
11406  *      jquery.ui.mouse.js
11407  *      jquery.ui.widget.js
11408  */
11409 (function( $, undefined ) {
11410
11411 $.widget("ui.resizable", $.ui.mouse, {
11412         widgetEventPrefix: "resize",
11413         options: {
11414                 alsoResize: false,
11415                 animate: false,
11416                 animateDuration: "slow",
11417                 animateEasing: "swing",
11418                 aspectRatio: false,
11419                 autoHide: false,
11420                 containment: false,
11421                 ghost: false,
11422                 grid: false,
11423                 handles: "e,s,se",
11424                 helper: false,
11425                 maxHeight: null,
11426                 maxWidth: null,
11427                 minHeight: 10,
11428                 minWidth: 10,
11429                 zIndex: 1000
11430         },
11431         _create: function() {
11432
11433                 var self = this, o = this.options;
11434                 this.element.addClass("ui-resizable");
11435
11436                 $.extend(this, {
11437                         _aspectRatio: !!(o.aspectRatio),
11438                         aspectRatio: o.aspectRatio,
11439                         originalElement: this.element,
11440                         _proportionallyResizeElements: [],
11441                         _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
11442                 });
11443
11444                 //Wrap the element if it cannot hold child nodes
11445                 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
11446
11447                         //Opera fix for relative positioning
11448                         if (/relative/.test(this.element.css('position')) && $.browser.opera)
11449                                 this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
11450
11451                         //Create a wrapper element and set the wrapper to the new current internal element
11452                         this.element.wrap(
11453                                 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
11454                                         position: this.element.css('position'),
11455                                         width: this.element.outerWidth(),
11456                                         height: this.element.outerHeight(),
11457                                         top: this.element.css('top'),
11458                                         left: this.element.css('left')
11459                                 })
11460                         );
11461
11462                         //Overwrite the original this.element
11463                         this.element = this.element.parent().data(
11464                                 "resizable", this.element.data('resizable')
11465                         );
11466
11467                         this.elementIsWrapper = true;
11468
11469                         //Move margins to the wrapper
11470                         this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
11471                         this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
11472
11473                         //Prevent Safari textarea resize
11474                         this.originalResizeStyle = this.originalElement.css('resize');
11475                         this.originalElement.css('resize', 'none');
11476
11477                         //Push the actual element to our proportionallyResize internal array
11478                         this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
11479
11480                         // avoid IE jump (hard set the margin)
11481                         this.originalElement.css({ margin: this.originalElement.css('margin') });
11482
11483                         // fix handlers offset
11484                         this._proportionallyResize();
11485
11486                 }
11487
11488                 this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
11489                 if(this.handles.constructor == String) {
11490
11491                         if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
11492                         var n = this.handles.split(","); this.handles = {};
11493
11494                         for(var i = 0; i < n.length; i++) {
11495
11496                                 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
11497                                 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
11498
11499                                 // increase zIndex of sw, se, ne, nw axis
11500                                 //TODO : this modifies original option
11501                                 if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
11502
11503                                 //TODO : What's going on here?
11504                                 if ('se' == handle) {
11505                                         axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
11506                                 };
11507
11508                                 //Insert into internal handles object and append to element
11509                                 this.handles[handle] = '.ui-resizable-'+handle;
11510                                 this.element.append(axis);
11511                         }
11512
11513                 }
11514
11515                 this._renderAxis = function(target) {
11516
11517                         target = target || this.element;
11518
11519                         for(var i in this.handles) {
11520
11521                                 if(this.handles[i].constructor == String)
11522                                         this.handles[i] = $(this.handles[i], this.element).show();
11523
11524                                 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
11525                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
11526
11527                                         var axis = $(this.handles[i], this.element), padWrapper = 0;
11528
11529                                         //Checking the correct pad and border
11530                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
11531
11532                                         //The padding type i have to apply...
11533                                         var padPos = [ 'padding',
11534                                                 /ne|nw|n/.test(i) ? 'Top' :
11535                                                 /se|sw|s/.test(i) ? 'Bottom' :
11536                                                 /^e$/.test(i) ? 'Right' : 'Left' ].join("");
11537
11538                                         target.css(padPos, padWrapper);
11539
11540                                         this._proportionallyResize();
11541
11542                                 }
11543
11544                                 //TODO: What's that good for? There's not anything to be executed left
11545                                 if(!$(this.handles[i]).length)
11546                                         continue;
11547
11548                         }
11549                 };
11550
11551                 //TODO: make renderAxis a prototype function
11552                 this._renderAxis(this.element);
11553
11554                 this._handles = $('.ui-resizable-handle', this.element)
11555                         .disableSelection();
11556
11557                 //Matching axis name
11558                 this._handles.mouseover(function() {
11559                         if (!self.resizing) {
11560                                 if (this.className)
11561                                         var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
11562                                 //Axis, default = se
11563                                 self.axis = axis && axis[1] ? axis[1] : 'se';
11564                         }
11565                 });
11566
11567                 //If we want to auto hide the elements
11568                 if (o.autoHide) {
11569                         this._handles.hide();
11570                         $(this.element)
11571                                 .addClass("ui-resizable-autohide")
11572                                 .hover(function() {
11573                                         $(this).removeClass("ui-resizable-autohide");
11574                                         self._handles.show();
11575                                 },
11576                                 function(){
11577                                         if (!self.resizing) {
11578                                                 $(this).addClass("ui-resizable-autohide");
11579                                                 self._handles.hide();
11580                                         }
11581                                 });
11582                 }
11583
11584                 //Initialize the mouse interaction
11585                 this._mouseInit();
11586
11587         },
11588
11589         destroy: function() {
11590
11591                 this._mouseDestroy();
11592
11593                 var _destroy = function(exp) {
11594                         $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
11595                                 .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
11596                 };
11597
11598                 //TODO: Unwrap at same DOM position
11599                 if (this.elementIsWrapper) {
11600                         _destroy(this.element);
11601                         var wrapper = this.element;
11602                         wrapper.after(
11603                                 this.originalElement.css({
11604                                         position: wrapper.css('position'),
11605                                         width: wrapper.outerWidth(),
11606                                         height: wrapper.outerHeight(),
11607                                         top: wrapper.css('top'),
11608                                         left: wrapper.css('left')
11609                                 })
11610                         ).remove();
11611                 }
11612
11613                 this.originalElement.css('resize', this.originalResizeStyle);
11614                 _destroy(this.originalElement);
11615
11616                 return this;
11617         },
11618
11619         _mouseCapture: function(event) {
11620                 var handle = false;
11621                 for (var i in this.handles) {
11622                         if ($(this.handles[i])[0] == event.target) {
11623                                 handle = true;
11624                         }
11625                 }
11626
11627                 return !this.options.disabled && handle;
11628         },
11629
11630         _mouseStart: function(event) {
11631
11632                 var o = this.options, iniPos = this.element.position(), el = this.element;
11633
11634                 this.resizing = true;
11635                 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
11636
11637                 // bugfix for http://dev.jquery.com/ticket/1749
11638                 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
11639                         el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
11640                 }
11641
11642                 //Opera fixing relative position
11643                 if ($.browser.opera && (/relative/).test(el.css('position')))
11644                         el.css({ position: 'relative', top: 'auto', left: 'auto' });
11645
11646                 this._renderProxy();
11647
11648                 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
11649
11650                 if (o.containment) {
11651                         curleft += $(o.containment).scrollLeft() || 0;
11652                         curtop += $(o.containment).scrollTop() || 0;
11653                 }
11654
11655                 //Store needed variables
11656                 this.offset = this.helper.offset();
11657                 this.position = { left: curleft, top: curtop };
11658                 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
11659                 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
11660                 this.originalPosition = { left: curleft, top: curtop };
11661                 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
11662                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
11663
11664                 //Aspect Ratio
11665                 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
11666
11667             var cursor = $('.ui-resizable-' + this.axis).css('cursor');
11668             $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
11669
11670                 el.addClass("ui-resizable-resizing");
11671                 this._propagate("start", event);
11672                 return true;
11673         },
11674
11675         _mouseDrag: function(event) {
11676
11677                 //Increase performance, avoid regex
11678                 var el = this.helper, o = this.options, props = {},
11679                         self = this, smp = this.originalMousePosition, a = this.axis;
11680
11681                 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
11682                 var trigger = this._change[a];
11683                 if (!trigger) return false;
11684
11685                 // Calculate the attrs that will be change
11686                 var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
11687
11688                 if (this._aspectRatio || event.shiftKey)
11689                         data = this._updateRatio(data, event);
11690
11691                 data = this._respectSize(data, event);
11692
11693                 // plugins callbacks need to be called first
11694                 this._propagate("resize", event);
11695
11696                 el.css({
11697                         top: this.position.top + "px", left: this.position.left + "px",
11698                         width: this.size.width + "px", height: this.size.height + "px"
11699                 });
11700
11701                 if (!this._helper && this._proportionallyResizeElements.length)
11702                         this._proportionallyResize();
11703
11704                 this._updateCache(data);
11705
11706                 // calling the user callback at the end
11707                 this._trigger('resize', event, this.ui());
11708
11709                 return false;
11710         },
11711
11712         _mouseStop: function(event) {
11713
11714                 this.resizing = false;
11715                 var o = this.options, self = this;
11716
11717                 if(this._helper) {
11718                         var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
11719                                 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
11720                                 soffsetw = ista ? 0 : self.sizeDiff.width;
11721
11722                         var s = { width: (self.helper.width()  - soffsetw), height: (self.helper.height() - soffseth) },
11723                                 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
11724                                 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
11725
11726                         if (!o.animate)
11727                                 this.element.css($.extend(s, { top: top, left: left }));
11728
11729                         self.helper.height(self.size.height);
11730                         self.helper.width(self.size.width);
11731
11732                         if (this._helper && !o.animate) this._proportionallyResize();
11733                 }
11734
11735                 $('body').css('cursor', 'auto');
11736
11737                 this.element.removeClass("ui-resizable-resizing");
11738
11739                 this._propagate("stop", event);
11740
11741                 if (this._helper) this.helper.remove();
11742                 return false;
11743
11744         },
11745
11746         _updateCache: function(data) {
11747                 var o = this.options;
11748                 this.offset = this.helper.offset();
11749                 if (isNumber(data.left)) this.position.left = data.left;
11750                 if (isNumber(data.top)) this.position.top = data.top;
11751                 if (isNumber(data.height)) this.size.height = data.height;
11752                 if (isNumber(data.width)) this.size.width = data.width;
11753         },
11754
11755         _updateRatio: function(data, event) {
11756
11757                 var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
11758
11759                 if (data.height) data.width = (csize.height * this.aspectRatio);
11760                 else if (data.width) data.height = (csize.width / this.aspectRatio);
11761
11762                 if (a == 'sw') {
11763                         data.left = cpos.left + (csize.width - data.width);
11764                         data.top = null;
11765                 }
11766                 if (a == 'nw') {
11767                         data.top = cpos.top + (csize.height - data.height);
11768                         data.left = cpos.left + (csize.width - data.width);
11769                 }
11770
11771                 return data;
11772         },
11773
11774         _respectSize: function(data, event) {
11775
11776                 var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
11777                                 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
11778                                         isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
11779
11780                 if (isminw) data.width = o.minWidth;
11781                 if (isminh) data.height = o.minHeight;
11782                 if (ismaxw) data.width = o.maxWidth;
11783                 if (ismaxh) data.height = o.maxHeight;
11784
11785                 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
11786                 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
11787
11788                 if (isminw && cw) data.left = dw - o.minWidth;
11789                 if (ismaxw && cw) data.left = dw - o.maxWidth;
11790                 if (isminh && ch)       data.top = dh - o.minHeight;
11791                 if (ismaxh && ch)       data.top = dh - o.maxHeight;
11792
11793                 // fixing jump error on top/left - bug #2330
11794                 var isNotwh = !data.width && !data.height;
11795                 if (isNotwh && !data.left && data.top) data.top = null;
11796                 else if (isNotwh && !data.top && data.left) data.left = null;
11797
11798                 return data;
11799         },
11800
11801         _proportionallyResize: function() {
11802
11803                 var o = this.options;
11804                 if (!this._proportionallyResizeElements.length) return;
11805                 var element = this.helper || this.element;
11806
11807                 for (var i=0; i < this._proportionallyResizeElements.length; i++) {
11808
11809                         var prel = this._proportionallyResizeElements[i];
11810
11811                         if (!this.borderDif) {
11812                                 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
11813                                         p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
11814
11815                                 this.borderDif = $.map(b, function(v, i) {
11816                                         var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
11817                                         return border + padding;
11818                                 });
11819                         }
11820
11821                         if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
11822                                 continue;
11823
11824                         prel.css({
11825                                 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
11826                                 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
11827                         });
11828
11829                 };
11830
11831         },
11832
11833         _renderProxy: function() {
11834
11835                 var el = this.element, o = this.options;
11836                 this.elementOffset = el.offset();
11837
11838                 if(this._helper) {
11839
11840                         this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
11841
11842                         // fix ie6 offset TODO: This seems broken
11843                         var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
11844                         pxyoffset = ( ie6 ? 2 : -1 );
11845
11846                         this.helper.addClass(this._helper).css({
11847                                 width: this.element.outerWidth() + pxyoffset,
11848                                 height: this.element.outerHeight() + pxyoffset,
11849                                 position: 'absolute',
11850                                 left: this.elementOffset.left - ie6offset +'px',
11851                                 top: this.elementOffset.top - ie6offset +'px',
11852                                 zIndex: ++o.zIndex //TODO: Don't modify option
11853                         });
11854
11855                         this.helper
11856                                 .appendTo("body")
11857                                 .disableSelection();
11858
11859                 } else {
11860                         this.helper = this.element;
11861                 }
11862
11863         },
11864
11865         _change: {
11866                 e: function(event, dx, dy) {
11867                         return { width: this.originalSize.width + dx };
11868                 },
11869                 w: function(event, dx, dy) {
11870                         var o = this.options, cs = this.originalSize, sp = this.originalPosition;
11871                         return { left: sp.left + dx, width: cs.width - dx };
11872                 },
11873                 n: function(event, dx, dy) {
11874                         var o = this.options, cs = this.originalSize, sp = this.originalPosition;
11875                         return { top: sp.top + dy, height: cs.height - dy };
11876                 },
11877                 s: function(event, dx, dy) {
11878                         return { height: this.originalSize.height + dy };
11879                 },
11880                 se: function(event, dx, dy) {
11881                         return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
11882                 },
11883                 sw: function(event, dx, dy) {
11884                         return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
11885                 },
11886                 ne: function(event, dx, dy) {
11887                         return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
11888                 },
11889                 nw: function(event, dx, dy) {
11890                         return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
11891                 }
11892         },
11893
11894         _propagate: function(n, event) {
11895                 $.ui.plugin.call(this, n, [event, this.ui()]);
11896                 (n != "resize" && this._trigger(n, event, this.ui()));
11897         },
11898
11899         plugins: {},
11900
11901         ui: function() {
11902                 return {
11903                         originalElement: this.originalElement,
11904                         element: this.element,
11905                         helper: this.helper,
11906                         position: this.position,
11907                         size: this.size,
11908                         originalSize: this.originalSize,
11909                         originalPosition: this.originalPosition
11910                 };
11911         }
11912
11913 });
11914
11915 $.extend($.ui.resizable, {
11916         version: "1.8.12"
11917 });
11918
11919 /*
11920  * Resizable Extensions
11921  */
11922
11923 $.ui.plugin.add("resizable", "alsoResize", {
11924
11925         start: function (event, ui) {
11926                 var self = $(this).data("resizable"), o = self.options;
11927
11928                 var _store = function (exp) {
11929                         $(exp).each(function() {
11930                                 var el = $(this);
11931                                 el.data("resizable-alsoresize", {
11932                                         width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
11933                                         left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
11934                                         position: el.css('position') // to reset Opera on stop()
11935                                 });
11936                         });
11937                 };
11938
11939                 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
11940                         if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
11941                         else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
11942                 }else{
11943                         _store(o.alsoResize);
11944                 }
11945         },
11946
11947         resize: function (event, ui) {
11948                 var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
11949
11950                 var delta = {
11951                         height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
11952                         top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
11953                 },
11954
11955                 _alsoResize = function (exp, c) {
11956                         $(exp).each(function() {
11957                                 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 
11958                                         css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
11959
11960                                 $.each(css, function (i, prop) {
11961                                         var sum = (start[prop]||0) + (delta[prop]||0);
11962                                         if (sum && sum >= 0)
11963                                                 style[prop] = sum || null;
11964                                 });
11965
11966                                 // Opera fixing relative position
11967                                 if ($.browser.opera && /relative/.test(el.css('position'))) {
11968                                         self._revertToRelativePosition = true;
11969                                         el.css({ position: 'absolute', top: 'auto', left: 'auto' });
11970                                 }
11971
11972                                 el.css(style);
11973                         });
11974                 };
11975
11976                 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
11977                         $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
11978                 }else{
11979                         _alsoResize(o.alsoResize);
11980                 }
11981         },
11982
11983         stop: function (event, ui) {
11984                 var self = $(this).data("resizable"), o = self.options;
11985
11986                 var _reset = function (exp) {
11987                         $(exp).each(function() {
11988                                 var el = $(this);
11989                                 // reset position for Opera - no need to verify it was changed
11990                                 el.css({ position: el.data("resizable-alsoresize").position });
11991                         });
11992                 };
11993
11994                 if (self._revertToRelativePosition) {
11995                         self._revertToRelativePosition = false;
11996                         if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
11997                                 $.each(o.alsoResize, function (exp) { _reset(exp); });
11998                         }else{
11999                                 _reset(o.alsoResize);
12000                         }
12001                 }
12002
12003                 $(this).removeData("resizable-alsoresize");
12004         }
12005 });
12006
12007 $.ui.plugin.add("resizable", "animate", {
12008
12009         stop: function(event, ui) {
12010                 var self = $(this).data("resizable"), o = self.options;
12011
12012                 var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
12013                                         soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
12014                                                 soffsetw = ista ? 0 : self.sizeDiff.width;
12015
12016                 var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
12017                                         left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
12018                                                 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
12019
12020                 self.element.animate(
12021                         $.extend(style, top && left ? { top: top, left: left } : {}), {
12022                                 duration: o.animateDuration,
12023                                 easing: o.animateEasing,
12024                                 step: function() {
12025
12026                                         var data = {
12027                                                 width: parseInt(self.element.css('width'), 10),
12028                                                 height: parseInt(self.element.css('height'), 10),
12029                                                 top: parseInt(self.element.css('top'), 10),
12030                                                 left: parseInt(self.element.css('left'), 10)
12031                                         };
12032
12033                                         if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
12034
12035                                         // propagating resize, and updating values for each animation step
12036                                         self._updateCache(data);
12037                                         self._propagate("resize", event);
12038
12039                                 }
12040                         }
12041                 );
12042         }
12043
12044 });
12045
12046 $.ui.plugin.add("resizable", "containment", {
12047
12048         start: function(event, ui) {
12049                 var self = $(this).data("resizable"), o = self.options, el = self.element;
12050                 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
12051                 if (!ce) return;
12052
12053                 self.containerElement = $(ce);
12054
12055                 if (/document/.test(oc) || oc == document) {
12056                         self.containerOffset = { left: 0, top: 0 };
12057                         self.containerPosition = { left: 0, top: 0 };
12058
12059                         self.parentData = {
12060                                 element: $(document), left: 0, top: 0,
12061                                 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
12062                         };
12063                 }
12064
12065                 // i'm a node, so compute top, left, right, bottom
12066                 else {
12067                         var element = $(ce), p = [];
12068                         $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
12069
12070                         self.containerOffset = element.offset();
12071                         self.containerPosition = element.position();
12072                         self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
12073
12074                         var co = self.containerOffset, ch = self.containerSize.height,  cw = self.containerSize.width,
12075                                                 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
12076
12077                         self.parentData = {
12078                                 element: ce, left: co.left, top: co.top, width: width, height: height
12079                         };
12080                 }
12081         },
12082
12083         resize: function(event, ui) {
12084                 var self = $(this).data("resizable"), o = self.options,
12085                                 ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
12086                                 pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
12087
12088                 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
12089
12090                 if (cp.left < (self._helper ? co.left : 0)) {
12091                         self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
12092                         if (pRatio) self.size.height = self.size.width / o.aspectRatio;
12093                         self.position.left = o.helper ? co.left : 0;
12094                 }
12095
12096                 if (cp.top < (self._helper ? co.top : 0)) {
12097                         self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
12098                         if (pRatio) self.size.width = self.size.height * o.aspectRatio;
12099                         self.position.top = self._helper ? co.top : 0;
12100                 }
12101
12102                 self.offset.left = self.parentData.left+self.position.left;
12103                 self.offset.top = self.parentData.top+self.position.top;
12104
12105                 var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
12106                                         hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
12107
12108                 var isParent = self.containerElement.get(0) == self.element.parent().get(0),
12109                     isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
12110
12111                 if(isParent && isOffsetRelative) woset -= self.parentData.left;
12112
12113                 if (woset + self.size.width >= self.parentData.width) {
12114                         self.size.width = self.parentData.width - woset;
12115                         if (pRatio) self.size.height = self.size.width / self.aspectRatio;
12116                 }
12117
12118                 if (hoset + self.size.height >= self.parentData.height) {
12119                         self.size.height = self.parentData.height - hoset;
12120                         if (pRatio) self.size.width = self.size.height * self.aspectRatio;
12121                 }
12122         },
12123
12124         stop: function(event, ui){
12125                 var self = $(this).data("resizable"), o = self.options, cp = self.position,
12126                                 co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
12127
12128                 var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
12129
12130                 if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
12131                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
12132
12133                 if (self._helper && !o.animate && (/static/).test(ce.css('position')))
12134                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
12135
12136         }
12137 });
12138
12139 $.ui.plugin.add("resizable", "ghost", {
12140
12141         start: function(event, ui) {
12142
12143                 var self = $(this).data("resizable"), o = self.options, cs = self.size;
12144
12145                 self.ghost = self.originalElement.clone();
12146                 self.ghost
12147                         .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
12148                         .addClass('ui-resizable-ghost')
12149                         .addClass(typeof o.ghost == 'string' ? o.ghost : '');
12150
12151                 self.ghost.appendTo(self.helper);
12152
12153         },
12154
12155         resize: function(event, ui){
12156                 var self = $(this).data("resizable"), o = self.options;
12157                 if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
12158         },
12159
12160         stop: function(event, ui){
12161                 var self = $(this).data("resizable"), o = self.options;
12162                 if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
12163         }
12164
12165 });
12166
12167 $.ui.plugin.add("resizable", "grid", {
12168
12169         resize: function(event, ui) {
12170                 var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
12171                 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
12172                 var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
12173
12174                 if (/^(se|s|e)$/.test(a)) {
12175                         self.size.width = os.width + ox;
12176                         self.size.height = os.height + oy;
12177                 }
12178                 else if (/^(ne)$/.test(a)) {
12179                         self.size.width = os.width + ox;
12180                         self.size.height = os.height + oy;
12181                         self.position.top = op.top - oy;
12182                 }
12183                 else if (/^(sw)$/.test(a)) {
12184                         self.size.width = os.width + ox;
12185                         self.size.height = os.height + oy;
12186                         self.position.left = op.left - ox;
12187                 }
12188                 else {
12189                         self.size.width = os.width + ox;
12190                         self.size.height = os.height + oy;
12191                         self.position.top = op.top - oy;
12192                         self.position.left = op.left - ox;
12193                 }
12194         }
12195
12196 });
12197
12198 var num = function(v) {
12199         return parseInt(v, 10) || 0;
12200 };
12201
12202 var isNumber = function(value) {
12203         return !isNaN(parseInt(value, 10));
12204 };
12205
12206 })(jQuery);
12207 /*
12208  * jQuery UI Selectable 1.8.12
12209  *
12210  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
12211  * Dual licensed under the MIT or GPL Version 2 licenses.
12212  * http://jquery.org/license
12213  *
12214  * http://docs.jquery.com/UI/Selectables
12215  *
12216  * Depends:
12217  *      jquery.ui.core.js
12218  *      jquery.ui.mouse.js
12219  *      jquery.ui.widget.js
12220  */
12221 (function( $, undefined ) {
12222
12223 $.widget("ui.selectable", $.ui.mouse, {
12224         options: {
12225                 appendTo: 'body',
12226                 autoRefresh: true,
12227                 distance: 0,
12228                 filter: '*',
12229                 tolerance: 'touch'
12230         },
12231         _create: function() {
12232                 var self = this;
12233
12234                 this.element.addClass("ui-selectable");
12235
12236                 this.dragged = false;
12237
12238                 // cache selectee children based on filter
12239                 var selectees;
12240                 this.refresh = function() {
12241                         selectees = $(self.options.filter, self.element[0]);
12242                         selectees.each(function() {
12243                                 var $this = $(this);
12244                                 var pos = $this.offset();
12245                                 $.data(this, "selectable-item", {
12246                                         element: this,
12247                                         $element: $this,
12248                                         left: pos.left,
12249                                         top: pos.top,
12250                                         right: pos.left + $this.outerWidth(),
12251                                         bottom: pos.top + $this.outerHeight(),
12252                                         startselected: false,
12253                                         selected: $this.hasClass('ui-selected'),
12254                                         selecting: $this.hasClass('ui-selecting'),
12255                                         unselecting: $this.hasClass('ui-unselecting')
12256                                 });
12257                         });
12258                 };
12259                 this.refresh();
12260
12261                 this.selectees = selectees.addClass("ui-selectee");
12262
12263                 this._mouseInit();
12264
12265                 this.helper = $("<div class='ui-selectable-helper'></div>");
12266         },
12267
12268         destroy: function() {
12269                 this.selectees
12270                         .removeClass("ui-selectee")
12271                         .removeData("selectable-item");
12272                 this.element
12273                         .removeClass("ui-selectable ui-selectable-disabled")
12274                         .removeData("selectable")
12275                         .unbind(".selectable");
12276                 this._mouseDestroy();
12277
12278                 return this;
12279         },
12280
12281         _mouseStart: function(event) {
12282                 var self = this;
12283
12284                 this.opos = [event.pageX, event.pageY];
12285
12286                 if (this.options.disabled)
12287                         return;
12288
12289                 var options = this.options;
12290
12291                 this.selectees = $(options.filter, this.element[0]);
12292
12293                 this._trigger("start", event);
12294
12295                 $(options.appendTo).append(this.helper);
12296                 // position helper (lasso)
12297                 this.helper.css({
12298                         "left": event.clientX,
12299                         "top": event.clientY,
12300                         "width": 0,
12301                         "height": 0
12302                 });
12303
12304                 if (options.autoRefresh) {
12305                         this.refresh();
12306                 }
12307
12308                 this.selectees.filter('.ui-selected').each(function() {
12309                         var selectee = $.data(this, "selectable-item");
12310                         selectee.startselected = true;
12311                         if (!event.metaKey) {
12312                                 selectee.$element.removeClass('ui-selected');
12313                                 selectee.selected = false;
12314                                 selectee.$element.addClass('ui-unselecting');
12315                                 selectee.unselecting = true;
12316                                 // selectable UNSELECTING callback
12317                                 self._trigger("unselecting", event, {
12318                                         unselecting: selectee.element
12319                                 });
12320                         }
12321                 });
12322
12323                 $(event.target).parents().andSelf().each(function() {
12324                         var selectee = $.data(this, "selectable-item");
12325                         if (selectee) {
12326                                 var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
12327                                 selectee.$element
12328                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
12329                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
12330                                 selectee.unselecting = !doSelect;
12331                                 selectee.selecting = doSelect;
12332                                 selectee.selected = doSelect;
12333                                 // selectable (UN)SELECTING callback
12334                                 if (doSelect) {
12335                                         self._trigger("selecting", event, {
12336                                                 selecting: selectee.element
12337                                         });
12338                                 } else {
12339                                         self._trigger("unselecting", event, {
12340                                                 unselecting: selectee.element
12341                                         });
12342                                 }
12343                                 return false;
12344                         }
12345                 });
12346
12347         },
12348
12349         _mouseDrag: function(event) {
12350                 var self = this;
12351                 this.dragged = true;
12352
12353                 if (this.options.disabled)
12354                         return;
12355
12356                 var options = this.options;
12357
12358                 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
12359                 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
12360                 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
12361                 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
12362
12363                 this.selectees.each(function() {
12364                         var selectee = $.data(this, "selectable-item");
12365                         //prevent helper from being selected if appendTo: selectable
12366                         if (!selectee || selectee.element == self.element[0])
12367                                 return;
12368                         var hit = false;
12369                         if (options.tolerance == 'touch') {
12370                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
12371                         } else if (options.tolerance == 'fit') {
12372                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
12373                         }
12374
12375                         if (hit) {
12376                                 // SELECT
12377                                 if (selectee.selected) {
12378                                         selectee.$element.removeClass('ui-selected');
12379                                         selectee.selected = false;
12380                                 }
12381                                 if (selectee.unselecting) {
12382                                         selectee.$element.removeClass('ui-unselecting');
12383                                         selectee.unselecting = false;
12384                                 }
12385                                 if (!selectee.selecting) {
12386                                         selectee.$element.addClass('ui-selecting');
12387                                         selectee.selecting = true;
12388                                         // selectable SELECTING callback
12389                                         self._trigger("selecting", event, {
12390                                                 selecting: selectee.element
12391                                         });
12392                                 }
12393                         } else {
12394                                 // UNSELECT
12395                                 if (selectee.selecting) {
12396                                         if (event.metaKey && selectee.startselected) {
12397                                                 selectee.$element.removeClass('ui-selecting');
12398                                                 selectee.selecting = false;
12399                                                 selectee.$element.addClass('ui-selected');
12400                                                 selectee.selected = true;
12401                                         } else {
12402                                                 selectee.$element.removeClass('ui-selecting');
12403                                                 selectee.selecting = false;
12404                                                 if (selectee.startselected) {
12405                                                         selectee.$element.addClass('ui-unselecting');
12406                                                         selectee.unselecting = true;
12407                                                 }
12408                                                 // selectable UNSELECTING callback
12409                                                 self._trigger("unselecting", event, {
12410                                                         unselecting: selectee.element
12411                                                 });
12412                                         }
12413                                 }
12414                                 if (selectee.selected) {
12415                                         if (!event.metaKey && !selectee.startselected) {
12416                                                 selectee.$element.removeClass('ui-selected');
12417                                                 selectee.selected = false;
12418
12419                                                 selectee.$element.addClass('ui-unselecting');
12420                                                 selectee.unselecting = true;
12421                                                 // selectable UNSELECTING callback
12422                                                 self._trigger("unselecting", event, {
12423                                                         unselecting: selectee.element
12424                                                 });
12425                                         }
12426                                 }
12427                         }
12428                 });
12429
12430                 return false;
12431         },
12432
12433         _mouseStop: function(event) {
12434                 var self = this;
12435
12436                 this.dragged = false;
12437
12438                 var options = this.options;
12439
12440                 $('.ui-unselecting', this.element[0]).each(function() {
12441                         var selectee = $.data(this, "selectable-item");
12442                         selectee.$element.removeClass('ui-unselecting');
12443                         selectee.unselecting = false;
12444                         selectee.startselected = false;
12445                         self._trigger("unselected", event, {
12446                                 unselected: selectee.element
12447                         });
12448                 });
12449                 $('.ui-selecting', this.element[0]).each(function() {
12450                         var selectee = $.data(this, "selectable-item");
12451                         selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
12452                         selectee.selecting = false;
12453                         selectee.selected = true;
12454                         selectee.startselected = true;
12455                         self._trigger("selected", event, {
12456                                 selected: selectee.element
12457                         });
12458                 });
12459                 this._trigger("stop", event);
12460
12461                 this.helper.remove();
12462
12463                 return false;
12464         }
12465
12466 });
12467
12468 $.extend($.ui.selectable, {
12469         version: "1.8.12"
12470 });
12471
12472 })(jQuery);
12473 /*
12474  * jQuery UI Sortable 1.8.12
12475  *
12476  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
12477  * Dual licensed under the MIT or GPL Version 2 licenses.
12478  * http://jquery.org/license
12479  *
12480  * http://docs.jquery.com/UI/Sortables
12481  *
12482  * Depends:
12483  *      jquery.ui.core.js
12484  *      jquery.ui.mouse.js
12485  *      jquery.ui.widget.js
12486  */
12487 (function( $, undefined ) {
12488
12489 $.widget("ui.sortable", $.ui.mouse, {
12490         widgetEventPrefix: "sort",
12491         options: {
12492                 appendTo: "parent",
12493                 axis: false,
12494                 connectWith: false,
12495                 containment: false,
12496                 cursor: 'auto',
12497                 cursorAt: false,
12498                 dropOnEmpty: true,
12499                 forcePlaceholderSize: false,
12500                 forceHelperSize: false,
12501                 grid: false,
12502                 handle: false,
12503                 helper: "original",
12504                 items: '> *',
12505                 opacity: false,
12506                 placeholder: false,
12507                 revert: false,
12508                 scroll: true,
12509                 scrollSensitivity: 20,
12510                 scrollSpeed: 20,
12511                 scope: "default",
12512                 tolerance: "intersect",
12513                 zIndex: 1000
12514         },
12515         _create: function() {
12516
12517                 var o = this.options;
12518                 this.containerCache = {};
12519                 this.element.addClass("ui-sortable");
12520
12521                 //Get the items
12522                 this.refresh();
12523
12524                 //Let's determine if the items are being displayed horizontally
12525                 this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
12526
12527                 //Let's determine the parent's offset
12528                 this.offset = this.element.offset();
12529
12530                 //Initialize mouse events for interaction
12531                 this._mouseInit();
12532
12533         },
12534
12535         destroy: function() {
12536                 this.element
12537                         .removeClass("ui-sortable ui-sortable-disabled")
12538                         .removeData("sortable")
12539                         .unbind(".sortable");
12540                 this._mouseDestroy();
12541
12542                 for ( var i = this.items.length - 1; i >= 0; i-- )
12543                         this.items[i].item.removeData("sortable-item");
12544
12545                 return this;
12546         },
12547
12548         _setOption: function(key, value){
12549                 if ( key === "disabled" ) {
12550                         this.options[ key ] = value;
12551         
12552                         this.widget()
12553                                 [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
12554                 } else {
12555                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
12556                         $.Widget.prototype._setOption.apply(this, arguments);
12557                 }
12558         },
12559
12560         _mouseCapture: function(event, overrideHandle) {
12561
12562                 if (this.reverting) {
12563                         return false;
12564                 }
12565
12566                 if(this.options.disabled || this.options.type == 'static') return false;
12567
12568                 //We have to refresh the items data once first
12569                 this._refreshItems(event);
12570
12571                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
12572                 var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
12573                         if($.data(this, 'sortable-item') == self) {
12574                                 currentItem = $(this);
12575                                 return false;
12576                         }
12577                 });
12578                 if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
12579
12580                 if(!currentItem) return false;
12581                 if(this.options.handle && !overrideHandle) {
12582                         var validHandle = false;
12583
12584                         $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
12585                         if(!validHandle) return false;
12586                 }
12587
12588                 this.currentItem = currentItem;
12589                 this._removeCurrentsFromItems();
12590                 return true;
12591
12592         },
12593
12594         _mouseStart: function(event, overrideHandle, noActivation) {
12595
12596                 var o = this.options, self = this;
12597                 this.currentContainer = this;
12598
12599                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
12600                 this.refreshPositions();
12601
12602                 //Create and append the visible helper
12603                 this.helper = this._createHelper(event);
12604
12605                 //Cache the helper size
12606                 this._cacheHelperProportions();
12607
12608                 /*
12609                  * - Position generation -
12610                  * This block generates everything position related - it's the core of draggables.
12611                  */
12612
12613                 //Cache the margins of the original element
12614                 this._cacheMargins();
12615
12616                 //Get the next scrolling parent
12617                 this.scrollParent = this.helper.scrollParent();
12618
12619                 //The element's absolute position on the page minus margins
12620                 this.offset = this.currentItem.offset();
12621                 this.offset = {
12622                         top: this.offset.top - this.margins.top,
12623                         left: this.offset.left - this.margins.left
12624                 };
12625
12626                 // Only after we got the offset, we can change the helper's position to absolute
12627                 // TODO: Still need to figure out a way to make relative sorting possible
12628                 this.helper.css("position", "absolute");
12629                 this.cssPosition = this.helper.css("position");
12630
12631                 $.extend(this.offset, {
12632                         click: { //Where the click happened, relative to the element
12633                                 left: event.pageX - this.offset.left,
12634                                 top: event.pageY - this.offset.top
12635                         },
12636                         parent: this._getParentOffset(),
12637                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
12638                 });
12639
12640                 //Generate the original position
12641                 this.originalPosition = this._generatePosition(event);
12642                 this.originalPageX = event.pageX;
12643                 this.originalPageY = event.pageY;
12644
12645                 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
12646                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
12647
12648                 //Cache the former DOM position
12649                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
12650
12651                 //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
12652                 if(this.helper[0] != this.currentItem[0]) {
12653                         this.currentItem.hide();
12654                 }
12655
12656                 //Create the placeholder
12657                 this._createPlaceholder();
12658
12659                 //Set a containment if given in the options
12660                 if(o.containment)
12661                         this._setContainment();
12662
12663                 if(o.cursor) { // cursor option
12664                         if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
12665                         $('body').css("cursor", o.cursor);
12666                 }
12667
12668                 if(o.opacity) { // opacity option
12669                         if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
12670                         this.helper.css("opacity", o.opacity);
12671                 }
12672
12673                 if(o.zIndex) { // zIndex option
12674                         if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
12675                         this.helper.css("zIndex", o.zIndex);
12676                 }
12677
12678                 //Prepare scrolling
12679                 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
12680                         this.overflowOffset = this.scrollParent.offset();
12681
12682                 //Call callbacks
12683                 this._trigger("start", event, this._uiHash());
12684
12685                 //Recache the helper size
12686                 if(!this._preserveHelperProportions)
12687                         this._cacheHelperProportions();
12688
12689
12690                 //Post 'activate' events to possible containers
12691                 if(!noActivation) {
12692                          for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
12693                 }
12694
12695                 //Prepare possible droppables
12696                 if($.ui.ddmanager)
12697                         $.ui.ddmanager.current = this;
12698
12699                 if ($.ui.ddmanager && !o.dropBehaviour)
12700                         $.ui.ddmanager.prepareOffsets(this, event);
12701
12702                 this.dragging = true;
12703
12704                 this.helper.addClass("ui-sortable-helper");
12705                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
12706                 return true;
12707
12708         },
12709
12710         _mouseDrag: function(event) {
12711
12712                 //Compute the helpers position
12713                 this.position = this._generatePosition(event);
12714                 this.positionAbs = this._convertPositionTo("absolute");
12715
12716                 if (!this.lastPositionAbs) {
12717                         this.lastPositionAbs = this.positionAbs;
12718                 }
12719
12720                 //Do scrolling
12721                 if(this.options.scroll) {
12722                         var o = this.options, scrolled = false;
12723                         if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
12724
12725                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
12726                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
12727                                 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
12728                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
12729
12730                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
12731                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
12732                                 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
12733                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
12734
12735                         } else {
12736
12737                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
12738                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
12739                                 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
12740                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
12741
12742                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
12743                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
12744                                 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
12745                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
12746
12747                         }
12748
12749                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
12750                                 $.ui.ddmanager.prepareOffsets(this, event);
12751                 }
12752
12753                 //Regenerate the absolute position used for position checks
12754                 this.positionAbs = this._convertPositionTo("absolute");
12755
12756                 //Set the helper position
12757                 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
12758                 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
12759
12760                 //Rearrange
12761                 for (var i = this.items.length - 1; i >= 0; i--) {
12762
12763                         //Cache variables and intersection, continue if no intersection
12764                         var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
12765                         if (!intersection) continue;
12766
12767                         if(itemElement != this.currentItem[0] //cannot intersect with itself
12768                                 &&      this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
12769                                 &&      !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
12770                                 && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
12771                                 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
12772                         ) {
12773
12774                                 this.direction = intersection == 1 ? "down" : "up";
12775
12776                                 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
12777                                         this._rearrange(event, item);
12778                                 } else {
12779                                         break;
12780                                 }
12781
12782                                 this._trigger("change", event, this._uiHash());
12783                                 break;
12784                         }
12785                 }
12786
12787                 //Post events to containers
12788                 this._contactContainers(event);
12789
12790                 //Interconnect with droppables
12791                 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
12792
12793                 //Call callbacks
12794                 this._trigger('sort', event, this._uiHash());
12795
12796                 this.lastPositionAbs = this.positionAbs;
12797                 return false;
12798
12799         },
12800
12801         _mouseStop: function(event, noPropagation) {
12802
12803                 if(!event) return;
12804
12805                 //If we are using droppables, inform the manager about the drop
12806                 if ($.ui.ddmanager && !this.options.dropBehaviour)
12807                         $.ui.ddmanager.drop(this, event);
12808
12809                 if(this.options.revert) {
12810                         var self = this;
12811                         var cur = self.placeholder.offset();
12812
12813                         self.reverting = true;
12814
12815                         $(this.helper).animate({
12816                                 left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
12817                                 top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
12818                         }, parseInt(this.options.revert, 10) || 500, function() {
12819                                 self._clear(event);
12820                         });
12821                 } else {
12822                         this._clear(event, noPropagation);
12823                 }
12824
12825                 return false;
12826
12827         },
12828
12829         cancel: function() {
12830
12831                 var self = this;
12832
12833                 if(this.dragging) {
12834
12835                         this._mouseUp({ target: null });
12836
12837                         if(this.options.helper == "original")
12838                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
12839                         else
12840                                 this.currentItem.show();
12841
12842                         //Post deactivating events to containers
12843                         for (var i = this.containers.length - 1; i >= 0; i--){
12844                                 this.containers[i]._trigger("deactivate", null, self._uiHash(this));
12845                                 if(this.containers[i].containerCache.over) {
12846                                         this.containers[i]._trigger("out", null, self._uiHash(this));
12847                                         this.containers[i].containerCache.over = 0;
12848                                 }
12849                         }
12850
12851                 }
12852
12853                 if (this.placeholder) {
12854                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
12855                         if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
12856                         if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
12857
12858                         $.extend(this, {
12859                                 helper: null,
12860                                 dragging: false,
12861                                 reverting: false,
12862                                 _noFinalSort: null
12863                         });
12864
12865                         if(this.domPosition.prev) {
12866                                 $(this.domPosition.prev).after(this.currentItem);
12867                         } else {
12868                                 $(this.domPosition.parent).prepend(this.currentItem);
12869                         }
12870                 }
12871
12872                 return this;
12873
12874         },
12875
12876         serialize: function(o) {
12877
12878                 var items = this._getItemsAsjQuery(o && o.connected);
12879                 var str = []; o = o || {};
12880
12881                 $(items).each(function() {
12882                         var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
12883                         if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
12884                 });
12885
12886                 if(!str.length && o.key) {
12887                         str.push(o.key + '=');
12888                 }
12889
12890                 return str.join('&');
12891
12892         },
12893
12894         toArray: function(o) {
12895
12896                 var items = this._getItemsAsjQuery(o && o.connected);
12897                 var ret = []; o = o || {};
12898
12899                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
12900                 return ret;
12901
12902         },
12903
12904         /* Be careful with the following core functions */
12905         _intersectsWith: function(item) {
12906
12907                 var x1 = this.positionAbs.left,
12908                         x2 = x1 + this.helperProportions.width,
12909                         y1 = this.positionAbs.top,
12910                         y2 = y1 + this.helperProportions.height;
12911
12912                 var l = item.left,
12913                         r = l + item.width,
12914                         t = item.top,
12915                         b = t + item.height;
12916
12917                 var dyClick = this.offset.click.top,
12918                         dxClick = this.offset.click.left;
12919
12920                 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
12921
12922                 if(        this.options.tolerance == "pointer"
12923                         || this.options.forcePointerForContainers
12924                         || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
12925                 ) {
12926                         return isOverElement;
12927                 } else {
12928
12929                         return (l < x1 + (this.helperProportions.width / 2) // Right Half
12930                                 && x2 - (this.helperProportions.width / 2) < r // Left Half
12931                                 && t < y1 + (this.helperProportions.height / 2) // Bottom Half
12932                                 && y2 - (this.helperProportions.height / 2) < b ); // Top Half
12933
12934                 }
12935         },
12936
12937         _intersectsWithPointer: function(item) {
12938
12939                 var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
12940                         isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
12941                         isOverElement = isOverElementHeight && isOverElementWidth,
12942                         verticalDirection = this._getDragVerticalDirection(),
12943                         horizontalDirection = this._getDragHorizontalDirection();
12944
12945                 if (!isOverElement)
12946                         return false;
12947
12948                 return this.floating ?
12949                         ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
12950                         : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
12951
12952         },
12953
12954         _intersectsWithSides: function(item) {
12955
12956                 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
12957                         isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
12958                         verticalDirection = this._getDragVerticalDirection(),
12959                         horizontalDirection = this._getDragHorizontalDirection();
12960
12961                 if (this.floating && horizontalDirection) {
12962                         return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
12963                 } else {
12964                         return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
12965                 }
12966
12967         },
12968
12969         _getDragVerticalDirection: function() {
12970                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
12971                 return delta != 0 && (delta > 0 ? "down" : "up");
12972         },
12973
12974         _getDragHorizontalDirection: function() {
12975                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
12976                 return delta != 0 && (delta > 0 ? "right" : "left");
12977         },
12978
12979         refresh: function(event) {
12980                 this._refreshItems(event);
12981                 this.refreshPositions();
12982                 return this;
12983         },
12984
12985         _connectWith: function() {
12986                 var options = this.options;
12987                 return options.connectWith.constructor == String
12988                         ? [options.connectWith]
12989                         : options.connectWith;
12990         },
12991         
12992         _getItemsAsjQuery: function(connected) {
12993
12994                 var self = this;
12995                 var items = [];
12996                 var queries = [];
12997                 var connectWith = this._connectWith();
12998
12999                 if(connectWith && connected) {
13000                         for (var i = connectWith.length - 1; i >= 0; i--){
13001                                 var cur = $(connectWith[i]);
13002                                 for (var j = cur.length - 1; j >= 0; j--){
13003                                         var inst = $.data(cur[j], 'sortable');
13004                                         if(inst && inst != this && !inst.options.disabled) {
13005                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
13006                                         }
13007                                 };
13008                         };
13009                 }
13010
13011                 queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
13012
13013                 for (var i = queries.length - 1; i >= 0; i--){
13014                         queries[i][0].each(function() {
13015                                 items.push(this);
13016                         });
13017                 };
13018
13019                 return $(items);
13020
13021         },
13022
13023         _removeCurrentsFromItems: function() {
13024
13025                 var list = this.currentItem.find(":data(sortable-item)");
13026
13027                 for (var i=0; i < this.items.length; i++) {
13028
13029                         for (var j=0; j < list.length; j++) {
13030                                 if(list[j] == this.items[i].item[0])
13031                                         this.items.splice(i,1);
13032                         };
13033
13034                 };
13035
13036         },
13037
13038         _refreshItems: function(event) {
13039
13040                 this.items = [];
13041                 this.containers = [this];
13042                 var items = this.items;
13043                 var self = this;
13044                 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
13045                 var connectWith = this._connectWith();
13046
13047                 if(connectWith) {
13048                         for (var i = connectWith.length - 1; i >= 0; i--){
13049                                 var cur = $(connectWith[i]);
13050                                 for (var j = cur.length - 1; j >= 0; j--){
13051                                         var inst = $.data(cur[j], 'sortable');
13052                                         if(inst && inst != this && !inst.options.disabled) {
13053                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
13054                                                 this.containers.push(inst);
13055                                         }
13056                                 };
13057                         };
13058                 }
13059
13060                 for (var i = queries.length - 1; i >= 0; i--) {
13061                         var targetData = queries[i][1];
13062                         var _queries = queries[i][0];
13063
13064                         for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
13065                                 var item = $(_queries[j]);
13066
13067                                 item.data('sortable-item', targetData); // Data for target checking (mouse manager)
13068
13069                                 items.push({
13070                                         item: item,
13071                                         instance: targetData,
13072                                         width: 0, height: 0,
13073                                         left: 0, top: 0
13074                                 });
13075                         };
13076                 };
13077
13078         },
13079
13080         refreshPositions: function(fast) {
13081
13082                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
13083                 if(this.offsetParent && this.helper) {
13084                         this.offset.parent = this._getParentOffset();
13085                 }
13086
13087                 for (var i = this.items.length - 1; i >= 0; i--){
13088                         var item = this.items[i];
13089
13090                         //We ignore calculating positions of all connected containers when we're not over them
13091                         if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
13092                                 continue;
13093
13094                         var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
13095
13096                         if (!fast) {
13097                                 item.width = t.outerWidth();
13098                                 item.height = t.outerHeight();
13099                         }
13100
13101                         var p = t.offset();
13102                         item.left = p.left;
13103                         item.top = p.top;
13104                 };
13105
13106                 if(this.options.custom && this.options.custom.refreshContainers) {
13107                         this.options.custom.refreshContainers.call(this);
13108                 } else {
13109                         for (var i = this.containers.length - 1; i >= 0; i--){
13110                                 var p = this.containers[i].element.offset();
13111                                 this.containers[i].containerCache.left = p.left;
13112                                 this.containers[i].containerCache.top = p.top;
13113                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
13114                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
13115                         };
13116                 }
13117
13118                 return this;
13119         },
13120
13121         _createPlaceholder: function(that) {
13122
13123                 var self = that || this, o = self.options;
13124
13125                 if(!o.placeholder || o.placeholder.constructor == String) {
13126                         var className = o.placeholder;
13127                         o.placeholder = {
13128                                 element: function() {
13129
13130                                         var el = $(document.createElement(self.currentItem[0].nodeName))
13131                                                 .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
13132                                                 .removeClass("ui-sortable-helper")[0];
13133
13134                                         if(!className)
13135                                                 el.style.visibility = "hidden";
13136
13137                                         return el;
13138                                 },
13139                                 update: function(container, p) {
13140
13141                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
13142                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
13143                                         if(className && !o.forcePlaceholderSize) return;
13144
13145                                         //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
13146                                         if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
13147                                         if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
13148                                 }
13149                         };
13150                 }
13151
13152                 //Create the placeholder
13153                 self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
13154
13155                 //Append it after the actual current item
13156                 self.currentItem.after(self.placeholder);
13157
13158                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
13159                 o.placeholder.update(self, self.placeholder);
13160
13161         },
13162
13163         _contactContainers: function(event) {
13164                 
13165                 // get innermost container that intersects with item 
13166                 var innermostContainer = null, innermostIndex = null;           
13167                 
13168                 
13169                 for (var i = this.containers.length - 1; i >= 0; i--){
13170
13171                         // never consider a container that's located within the item itself 
13172                         if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
13173                                 continue;
13174
13175                         if(this._intersectsWith(this.containers[i].containerCache)) {
13176
13177                                 // if we've already found a container and it's more "inner" than this, then continue 
13178                                 if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
13179                                         continue;
13180
13181                                 innermostContainer = this.containers[i]; 
13182                                 innermostIndex = i;
13183                                         
13184                         } else {
13185                                 // container doesn't intersect. trigger "out" event if necessary 
13186                                 if(this.containers[i].containerCache.over) {
13187                                         this.containers[i]._trigger("out", event, this._uiHash(this));
13188                                         this.containers[i].containerCache.over = 0;
13189                                 }
13190                         }
13191
13192                 }
13193                 
13194                 // if no intersecting containers found, return 
13195                 if(!innermostContainer) return; 
13196
13197                 // move the item into the container if it's not there already
13198                 if(this.containers.length === 1) {
13199                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
13200                         this.containers[innermostIndex].containerCache.over = 1;
13201                 } else if(this.currentContainer != this.containers[innermostIndex]) { 
13202
13203                         //When entering a new container, we will find the item with the least distance and append our item near it 
13204                         var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; 
13205                         for (var j = this.items.length - 1; j >= 0; j--) { 
13206                                 if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 
13207                                 var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; 
13208                                 if(Math.abs(cur - base) < dist) { 
13209                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 
13210                                 } 
13211                         } 
13212
13213                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 
13214                                 return; 
13215
13216                         this.currentContainer = this.containers[innermostIndex]; 
13217                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 
13218                         this._trigger("change", event, this._uiHash()); 
13219                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 
13220
13221                         //Update the placeholder 
13222                         this.options.placeholder.update(this.currentContainer, this.placeholder); 
13223                 
13224                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 
13225                         this.containers[innermostIndex].containerCache.over = 1;
13226                 } 
13227         
13228                 
13229         },
13230
13231         _createHelper: function(event) {
13232
13233                 var o = this.options;
13234                 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
13235
13236                 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
13237                         $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
13238
13239                 if(helper[0] == this.currentItem[0])
13240                         this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
13241
13242                 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
13243                 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
13244
13245                 return helper;
13246
13247         },
13248
13249         _adjustOffsetFromHelper: function(obj) {
13250                 if (typeof obj == 'string') {
13251                         obj = obj.split(' ');
13252                 }
13253                 if ($.isArray(obj)) {
13254                         obj = {left: +obj[0], top: +obj[1] || 0};
13255                 }
13256                 if ('left' in obj) {
13257                         this.offset.click.left = obj.left + this.margins.left;
13258                 }
13259                 if ('right' in obj) {
13260                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
13261                 }
13262                 if ('top' in obj) {
13263                         this.offset.click.top = obj.top + this.margins.top;
13264                 }
13265                 if ('bottom' in obj) {
13266                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
13267                 }
13268         },
13269
13270         _getParentOffset: function() {
13271
13272
13273                 //Get the offsetParent and cache its position
13274                 this.offsetParent = this.helper.offsetParent();
13275                 var po = this.offsetParent.offset();
13276
13277                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
13278                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
13279                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
13280                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
13281                 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
13282                         po.left += this.scrollParent.scrollLeft();
13283                         po.top += this.scrollParent.scrollTop();
13284                 }
13285
13286                 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
13287                 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
13288                         po = { top: 0, left: 0 };
13289
13290                 return {
13291                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
13292                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
13293                 };
13294
13295         },
13296
13297         _getRelativeOffset: function() {
13298
13299                 if(this.cssPosition == "relative") {
13300                         var p = this.currentItem.position();
13301                         return {
13302                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
13303                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
13304                         };
13305                 } else {
13306                         return { top: 0, left: 0 };
13307                 }
13308
13309         },
13310
13311         _cacheMargins: function() {
13312                 this.margins = {
13313                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
13314                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
13315                 };
13316         },
13317
13318         _cacheHelperProportions: function() {
13319                 this.helperProportions = {
13320                         width: this.helper.outerWidth(),
13321                         height: this.helper.outerHeight()
13322                 };
13323         },
13324
13325         _setContainment: function() {
13326
13327                 var o = this.options;
13328                 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
13329                 if(o.containment == 'document' || o.containment == 'window') this.containment = [
13330                         0 - this.offset.relative.left - this.offset.parent.left,
13331                         0 - this.offset.relative.top - this.offset.parent.top,
13332                         $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
13333                         ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
13334                 ];
13335
13336                 if(!(/^(document|window|parent)$/).test(o.containment)) {
13337                         var ce = $(o.containment)[0];
13338                         var co = $(o.containment).offset();
13339                         var over = ($(ce).css("overflow") != 'hidden');
13340
13341                         this.containment = [
13342                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
13343                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
13344                                 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
13345                                 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
13346                         ];
13347                 }
13348
13349         },
13350
13351         _convertPositionTo: function(d, pos) {
13352
13353                 if(!pos) pos = this.position;
13354                 var mod = d == "absolute" ? 1 : -1;
13355                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
13356
13357                 return {
13358                         top: (
13359                                 pos.top                                                                                                                                 // The absolute mouse position
13360                                 + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
13361                                 + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
13362                                 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
13363                         ),
13364                         left: (
13365                                 pos.left                                                                                                                                // The absolute mouse position
13366                                 + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
13367                                 + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
13368                                 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
13369                         )
13370                 };
13371
13372         },
13373
13374         _generatePosition: function(event) {
13375
13376                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
13377
13378                 // This is another very weird special case that only happens for relative elements:
13379                 // 1. If the css position is relative
13380                 // 2. and the scroll parent is the document or similar to the offset parent
13381                 // we have to refresh the relative offset during the scroll so there are no jumps
13382                 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
13383                         this.offset.relative = this._getRelativeOffset();
13384                 }
13385
13386                 var pageX = event.pageX;
13387                 var pageY = event.pageY;
13388
13389                 /*
13390                  * - Position constraining -
13391                  * Constrain the position to a mix of grid, containment.
13392                  */
13393
13394                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
13395
13396                         if(this.containment) {
13397                                 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
13398                                 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
13399                                 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
13400                                 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
13401                         }
13402
13403                         if(o.grid) {
13404                                 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
13405                                 pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
13406
13407                                 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
13408                                 pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
13409                         }
13410
13411                 }
13412
13413                 return {
13414                         top: (
13415                                 pageY                                                                                                                           // The absolute mouse position
13416                                 - this.offset.click.top                                                                                                 // Click offset (relative to the element)
13417                                 - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
13418                                 - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
13419                                 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
13420                         ),
13421                         left: (
13422                                 pageX                                                                                                                           // The absolute mouse position
13423                                 - this.offset.click.left                                                                                                // Click offset (relative to the element)
13424                                 - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
13425                                 - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
13426                                 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
13427                         )
13428                 };
13429
13430         },
13431
13432         _rearrange: function(event, i, a, hardRefresh) {
13433
13434                 a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
13435
13436                 //Various things done here to improve the performance:
13437                 // 1. we create a setTimeout, that calls refreshPositions
13438                 // 2. on the instance, we have a counter variable, that get's higher after every append
13439                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
13440                 // 4. this lets only the last addition to the timeout stack through
13441                 this.counter = this.counter ? ++this.counter : 1;
13442                 var self = this, counter = this.counter;
13443
13444                 window.setTimeout(function() {
13445                         if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
13446                 },0);
13447
13448         },
13449
13450         _clear: function(event, noPropagation) {
13451
13452                 this.reverting = false;
13453                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
13454                 // everything else normalized again
13455                 var delayedTriggers = [], self = this;
13456
13457                 // We first have to update the dom position of the actual currentItem
13458                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
13459                 if(!this._noFinalSort && this.currentItem[0].parentNode) this.placeholder.before(this.currentItem);
13460                 this._noFinalSort = null;
13461
13462                 if(this.helper[0] == this.currentItem[0]) {
13463                         for(var i in this._storedCSS) {
13464                                 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
13465                         }
13466                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
13467                 } else {
13468                         this.currentItem.show();
13469                 }
13470
13471                 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
13472                 if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
13473                 if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
13474                         if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
13475                         for (var i = this.containers.length - 1; i >= 0; i--){
13476                                 if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
13477                                         delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
13478                                         delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
13479                                 }
13480                         };
13481                 };
13482
13483                 //Post events to containers
13484                 for (var i = this.containers.length - 1; i >= 0; i--){
13485                         if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
13486                         if(this.containers[i].containerCache.over) {
13487                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
13488                                 this.containers[i].containerCache.over = 0;
13489                         }
13490                 }
13491
13492                 //Do what was originally in plugins
13493                 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
13494                 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
13495                 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
13496
13497                 this.dragging = false;
13498                 if(this.cancelHelperRemoval) {
13499                         if(!noPropagation) {
13500                                 this._trigger("beforeStop", event, this._uiHash());
13501                                 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
13502                                 this._trigger("stop", event, this._uiHash());
13503                         }
13504                         return false;
13505                 }
13506
13507                 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
13508
13509                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
13510                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
13511
13512                 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
13513
13514                 if(!noPropagation) {
13515                         for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
13516                         this._trigger("stop", event, this._uiHash());
13517                 }
13518
13519                 this.fromOutside = false;
13520                 return true;
13521
13522         },
13523
13524         _trigger: function() {
13525                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
13526                         this.cancel();
13527                 }
13528         },
13529
13530         _uiHash: function(inst) {
13531                 var self = inst || this;
13532                 return {
13533                         helper: self.helper,
13534                         placeholder: self.placeholder || $([]),
13535                         position: self.position,
13536                         originalPosition: self.originalPosition,
13537                         offset: self.positionAbs,
13538                         item: self.currentItem,
13539                         sender: inst ? inst.element : null
13540                 };
13541         }
13542
13543 });
13544
13545 $.extend($.ui.sortable, {
13546         version: "1.8.12"
13547 });
13548
13549 })(jQuery);
13550 /*
13551  * jQuery UI Effects 1.8.12
13552  *
13553  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
13554  * Dual licensed under the MIT or GPL Version 2 licenses.
13555  * http://jquery.org/license
13556  *
13557  * http://docs.jquery.com/UI/Effects/
13558  */
13559 ;jQuery.effects || (function($, undefined) {
13560
13561 $.effects = {};
13562
13563
13564
13565 /******************************************************************************/
13566 /****************************** COLOR ANIMATIONS ******************************/
13567 /******************************************************************************/
13568
13569 // override the animation for color styles
13570 $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
13571         'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
13572 function(i, attr) {
13573         $.fx.step[attr] = function(fx) {
13574                 if (!fx.colorInit) {
13575                         fx.start = getColor(fx.elem, attr);
13576                         fx.end = getRGB(fx.end);
13577                         fx.colorInit = true;
13578                 }
13579
13580                 fx.elem.style[attr] = 'rgb(' +
13581                         Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
13582                         Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
13583                         Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
13584         };
13585 });
13586
13587 // Color Conversion functions from highlightFade
13588 // By Blair Mitchelmore
13589 // http://jquery.offput.ca/highlightFade/
13590
13591 // Parse strings looking for color tuples [255,255,255]
13592 function getRGB(color) {
13593                 var result;
13594
13595                 // Check if we're already dealing with an array of colors
13596                 if ( color && color.constructor == Array && color.length == 3 )
13597                                 return color;
13598
13599                 // Look for rgb(num,num,num)
13600                 if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
13601                                 return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
13602
13603                 // Look for rgb(num%,num%,num%)
13604                 if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
13605                                 return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
13606
13607                 // Look for #a0b1c2
13608                 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
13609                                 return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
13610
13611                 // Look for #fff
13612                 if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
13613                                 return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
13614
13615                 // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
13616                 if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
13617                                 return colors['transparent'];
13618
13619                 // Otherwise, we're most likely dealing with a named color
13620                 return colors[$.trim(color).toLowerCase()];
13621 }
13622
13623 function getColor(elem, attr) {
13624                 var color;
13625
13626                 do {
13627                                 color = $.curCSS(elem, attr);
13628
13629                                 // Keep going until we find an element that has color, or we hit the body
13630                                 if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
13631                                                 break;
13632
13633                                 attr = "backgroundColor";
13634                 } while ( elem = elem.parentNode );
13635
13636                 return getRGB(color);
13637 };
13638
13639 // Some named colors to work with
13640 // From Interface by Stefan Petre
13641 // http://interface.eyecon.ro/
13642
13643 var colors = {
13644         aqua:[0,255,255],
13645         azure:[240,255,255],
13646         beige:[245,245,220],
13647         black:[0,0,0],
13648         blue:[0,0,255],
13649         brown:[165,42,42],
13650         cyan:[0,255,255],
13651         darkblue:[0,0,139],
13652         darkcyan:[0,139,139],
13653         darkgrey:[169,169,169],
13654         darkgreen:[0,100,0],
13655         darkkhaki:[189,183,107],
13656         darkmagenta:[139,0,139],
13657         darkolivegreen:[85,107,47],
13658         darkorange:[255,140,0],
13659         darkorchid:[153,50,204],
13660         darkred:[139,0,0],
13661         darksalmon:[233,150,122],
13662         darkviolet:[148,0,211],
13663         fuchsia:[255,0,255],
13664         gold:[255,215,0],
13665         green:[0,128,0],
13666         indigo:[75,0,130],
13667         khaki:[240,230,140],
13668         lightblue:[173,216,230],
13669         lightcyan:[224,255,255],
13670         lightgreen:[144,238,144],
13671         lightgrey:[211,211,211],
13672         lightpink:[255,182,193],
13673         lightyellow:[255,255,224],
13674         lime:[0,255,0],
13675         magenta:[255,0,255],
13676         maroon:[128,0,0],
13677         navy:[0,0,128],
13678         olive:[128,128,0],
13679         orange:[255,165,0],
13680         pink:[255,192,203],
13681         purple:[128,0,128],
13682         violet:[128,0,128],
13683         red:[255,0,0],
13684         silver:[192,192,192],
13685         white:[255,255,255],
13686         yellow:[255,255,0],
13687         transparent: [255,255,255]
13688 };
13689
13690
13691
13692 /******************************************************************************/
13693 /****************************** CLASS ANIMATIONS ******************************/
13694 /******************************************************************************/
13695
13696 var classAnimationActions = ['add', 'remove', 'toggle'],
13697         shorthandStyles = {
13698                 border: 1,
13699                 borderBottom: 1,
13700                 borderColor: 1,
13701                 borderLeft: 1,
13702                 borderRight: 1,
13703                 borderTop: 1,
13704                 borderWidth: 1,
13705                 margin: 1,
13706                 padding: 1
13707         };
13708
13709 function getElementStyles() {
13710         var style = document.defaultView
13711                         ? document.defaultView.getComputedStyle(this, null)
13712                         : this.currentStyle,
13713                 newStyle = {},
13714                 key,
13715                 camelCase;
13716
13717         // webkit enumerates style porperties
13718         if (style && style.length && style[0] && style[style[0]]) {
13719                 var len = style.length;
13720                 while (len--) {
13721                         key = style[len];
13722                         if (typeof style[key] == 'string') {
13723                                 camelCase = key.replace(/\-(\w)/g, function(all, letter){
13724                                         return letter.toUpperCase();
13725                                 });
13726                                 newStyle[camelCase] = style[key];
13727                         }
13728                 }
13729         } else {
13730                 for (key in style) {
13731                         if (typeof style[key] === 'string') {
13732                                 newStyle[key] = style[key];
13733                         }
13734                 }
13735         }
13736         
13737         return newStyle;
13738 }
13739
13740 function filterStyles(styles) {
13741         var name, value;
13742         for (name in styles) {
13743                 value = styles[name];
13744                 if (
13745                         // ignore null and undefined values
13746                         value == null ||
13747                         // ignore functions (when does this occur?)
13748                         $.isFunction(value) ||
13749                         // shorthand styles that need to be expanded
13750                         name in shorthandStyles ||
13751                         // ignore scrollbars (break in IE)
13752                         (/scrollbar/).test(name) ||
13753
13754                         // only colors or values that can be converted to numbers
13755                         (!(/color/i).test(name) && isNaN(parseFloat(value)))
13756                 ) {
13757                         delete styles[name];
13758                 }
13759         }
13760         
13761         return styles;
13762 }
13763
13764 function styleDifference(oldStyle, newStyle) {
13765         var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
13766                 name;
13767
13768         for (name in newStyle) {
13769                 if (oldStyle[name] != newStyle[name]) {
13770                         diff[name] = newStyle[name];
13771                 }
13772         }
13773
13774         return diff;
13775 }
13776
13777 $.effects.animateClass = function(value, duration, easing, callback) {
13778         if ($.isFunction(easing)) {
13779                 callback = easing;
13780                 easing = null;
13781         }
13782
13783         return this.queue('fx', function() {
13784                 var that = $(this),
13785                         originalStyleAttr = that.attr('style') || ' ',
13786                         originalStyle = filterStyles(getElementStyles.call(this)),
13787                         newStyle,
13788                         className = that.attr('className');
13789
13790                 $.each(classAnimationActions, function(i, action) {
13791                         if (value[action]) {
13792                                 that[action + 'Class'](value[action]);
13793                         }
13794                 });
13795                 newStyle = filterStyles(getElementStyles.call(this));
13796                 that.attr('className', className);
13797
13798                 that.animate(styleDifference(originalStyle, newStyle), duration, easing, function() {
13799                         $.each(classAnimationActions, function(i, action) {
13800                                 if (value[action]) { that[action + 'Class'](value[action]); }
13801                         });
13802                         // work around bug in IE by clearing the cssText before setting it
13803                         if (typeof that.attr('style') == 'object') {
13804                                 that.attr('style').cssText = '';
13805                                 that.attr('style').cssText = originalStyleAttr;
13806                         } else {
13807                                 that.attr('style', originalStyleAttr);
13808                         }
13809                         if (callback) { callback.apply(this, arguments); }
13810                 });
13811
13812                 // $.animate adds a function to the end of the queue
13813                 // but we want it at the front
13814                 var queue = $.queue(this),
13815                         anim = queue.splice(queue.length - 1, 1)[0];
13816                 queue.splice(1, 0, anim);
13817                 $.dequeue(this);
13818         });
13819 };
13820
13821 $.fn.extend({
13822         _addClass: $.fn.addClass,
13823         addClass: function(classNames, speed, easing, callback) {
13824                 return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
13825         },
13826
13827         _removeClass: $.fn.removeClass,
13828         removeClass: function(classNames,speed,easing,callback) {
13829                 return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
13830         },
13831
13832         _toggleClass: $.fn.toggleClass,
13833         toggleClass: function(classNames, force, speed, easing, callback) {
13834                 if ( typeof force == "boolean" || force === undefined ) {
13835                         if ( !speed ) {
13836                                 // without speed parameter;
13837                                 return this._toggleClass(classNames, force);
13838                         } else {
13839                                 return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
13840                         }
13841                 } else {
13842                         // without switch parameter;
13843                         return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
13844                 }
13845         },
13846
13847         switchClass: function(remove,add,speed,easing,callback) {
13848                 return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
13849         }
13850 });
13851
13852
13853
13854 /******************************************************************************/
13855 /*********************************** EFFECTS **********************************/
13856 /******************************************************************************/
13857
13858 $.extend($.effects, {
13859         version: "1.8.12",
13860
13861         // Saves a set of properties in a data storage
13862         save: function(element, set) {
13863                 for(var i=0; i < set.length; i++) {
13864                         if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
13865                 }
13866         },
13867
13868         // Restores a set of previously saved properties from a data storage
13869         restore: function(element, set) {
13870                 for(var i=0; i < set.length; i++) {
13871                         if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
13872                 }
13873         },
13874
13875         setMode: function(el, mode) {
13876                 if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
13877                 return mode;
13878         },
13879
13880         getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
13881                 // this should be a little more flexible in the future to handle a string & hash
13882                 var y, x;
13883                 switch (origin[0]) {
13884                         case 'top': y = 0; break;
13885                         case 'middle': y = 0.5; break;
13886                         case 'bottom': y = 1; break;
13887                         default: y = origin[0] / original.height;
13888                 };
13889                 switch (origin[1]) {
13890                         case 'left': x = 0; break;
13891                         case 'center': x = 0.5; break;
13892                         case 'right': x = 1; break;
13893                         default: x = origin[1] / original.width;
13894                 };
13895                 return {x: x, y: y};
13896         },
13897
13898         // Wraps the element around a wrapper that copies position properties
13899         createWrapper: function(element) {
13900
13901                 // if the element is already wrapped, return it
13902                 if (element.parent().is('.ui-effects-wrapper')) {
13903                         return element.parent();
13904                 }
13905
13906                 // wrap the element
13907                 var props = {
13908                                 width: element.outerWidth(true),
13909                                 height: element.outerHeight(true),
13910                                 'float': element.css('float')
13911                         },
13912                         wrapper = $('<div></div>')
13913                                 .addClass('ui-effects-wrapper')
13914                                 .css({
13915                                         fontSize: '100%',
13916                                         background: 'transparent',
13917                                         border: 'none',
13918                                         margin: 0,
13919                                         padding: 0
13920                                 });
13921
13922                 element.wrap(wrapper);
13923                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
13924
13925                 // transfer positioning properties to the wrapper
13926                 if (element.css('position') == 'static') {
13927                         wrapper.css({ position: 'relative' });
13928                         element.css({ position: 'relative' });
13929                 } else {
13930                         $.extend(props, {
13931                                 position: element.css('position'),
13932                                 zIndex: element.css('z-index')
13933                         });
13934                         $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
13935                                 props[pos] = element.css(pos);
13936                                 if (isNaN(parseInt(props[pos], 10))) {
13937                                         props[pos] = 'auto';
13938                                 }
13939                         });
13940                         element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
13941                 }
13942
13943                 return wrapper.css(props).show();
13944         },
13945
13946         removeWrapper: function(element) {
13947                 if (element.parent().is('.ui-effects-wrapper'))
13948                         return element.parent().replaceWith(element);
13949                 return element;
13950         },
13951
13952         setTransition: function(element, list, factor, value) {
13953                 value = value || {};
13954                 $.each(list, function(i, x){
13955                         unit = element.cssUnit(x);
13956                         if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
13957                 });
13958                 return value;
13959         }
13960 });
13961
13962
13963 function _normalizeArguments(effect, options, speed, callback) {
13964         // shift params for method overloading
13965         if (typeof effect == 'object') {
13966                 callback = options;
13967                 speed = null;
13968                 options = effect;
13969                 effect = options.effect;
13970         }
13971         if ($.isFunction(options)) {
13972                 callback = options;
13973                 speed = null;
13974                 options = {};
13975         }
13976         if (typeof options == 'number' || $.fx.speeds[options]) {
13977                 callback = speed;
13978                 speed = options;
13979                 options = {};
13980         }
13981         if ($.isFunction(speed)) {
13982                 callback = speed;
13983                 speed = null;
13984         }
13985
13986         options = options || {};
13987
13988         speed = speed || options.duration;
13989         speed = $.fx.off ? 0 : typeof speed == 'number'
13990                 ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
13991
13992         callback = callback || options.complete;
13993
13994         return [effect, options, speed, callback];
13995 }
13996
13997 function standardSpeed( speed ) {
13998         // valid standard speeds
13999         if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
14000                 return true;
14001         }
14002         
14003         // invalid strings - treat as "normal" speed
14004         if ( typeof speed === "string" && !$.effects[ speed ] ) {
14005                 return true;
14006         }
14007         
14008         return false;
14009 }
14010
14011 $.fn.extend({
14012         effect: function(effect, options, speed, callback) {
14013                 var args = _normalizeArguments.apply(this, arguments),
14014                         // TODO: make effects take actual parameters instead of a hash
14015                         args2 = {
14016                                 options: args[1],
14017                                 duration: args[2],
14018                                 callback: args[3]
14019                         },
14020                         mode = args2.options.mode,
14021                         effectMethod = $.effects[effect];
14022                 
14023                 if ( $.fx.off || !effectMethod ) {
14024                         // delegate to the original method (e.g., .show()) if possible
14025                         if ( mode ) {
14026                                 return this[ mode ]( args2.duration, args2.callback );
14027                         } else {
14028                                 return this.each(function() {
14029                                         if ( args2.callback ) {
14030                                                 args2.callback.call( this );
14031                                         }
14032                                 });
14033                         }
14034                 }
14035                 
14036                 return effectMethod.call(this, args2);
14037         },
14038
14039         _show: $.fn.show,
14040         show: function(speed) {
14041                 if ( standardSpeed( speed ) ) {
14042                         return this._show.apply(this, arguments);
14043                 } else {
14044                         var args = _normalizeArguments.apply(this, arguments);
14045                         args[1].mode = 'show';
14046                         return this.effect.apply(this, args);
14047                 }
14048         },
14049
14050         _hide: $.fn.hide,
14051         hide: function(speed) {
14052                 if ( standardSpeed( speed ) ) {
14053                         return this._hide.apply(this, arguments);
14054                 } else {
14055                         var args = _normalizeArguments.apply(this, arguments);
14056                         args[1].mode = 'hide';
14057                         return this.effect.apply(this, args);
14058                 }
14059         },
14060
14061         // jQuery core overloads toggle and creates _toggle
14062         __toggle: $.fn.toggle,
14063         toggle: function(speed) {
14064                 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
14065                         return this.__toggle.apply(this, arguments);
14066                 } else {
14067                         var args = _normalizeArguments.apply(this, arguments);
14068                         args[1].mode = 'toggle';
14069                         return this.effect.apply(this, args);
14070                 }
14071         },
14072
14073         // helper functions
14074         cssUnit: function(key) {
14075                 var style = this.css(key), val = [];
14076                 $.each( ['em','px','%','pt'], function(i, unit){
14077                         if(style.indexOf(unit) > 0)
14078                                 val = [parseFloat(style), unit];
14079                 });
14080                 return val;
14081         }
14082 });
14083
14084
14085
14086 /******************************************************************************/
14087 /*********************************** EASING ***********************************/
14088 /******************************************************************************/
14089
14090 /*
14091  * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
14092  *
14093  * Uses the built in easing capabilities added In jQuery 1.1
14094  * to offer multiple easing options
14095  *
14096  * TERMS OF USE - jQuery Easing
14097  *
14098  * Open source under the BSD License.
14099  *
14100  * Copyright 2008 George McGinley Smith
14101  * All rights reserved.
14102  *
14103  * Redistribution and use in source and binary forms, with or without modification,
14104  * are permitted provided that the following conditions are met:
14105  *
14106  * Redistributions of source code must retain the above copyright notice, this list of
14107  * conditions and the following disclaimer.
14108  * Redistributions in binary form must reproduce the above copyright notice, this list
14109  * of conditions and the following disclaimer in the documentation and/or other materials
14110  * provided with the distribution.
14111  *
14112  * Neither the name of the author nor the names of contributors may be used to endorse
14113  * or promote products derived from this software without specific prior written permission.
14114  *
14115  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
14116  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14117  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
14118  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14119  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
14120  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
14121  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
14122  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
14123  * OF THE POSSIBILITY OF SUCH DAMAGE.
14124  *
14125 */
14126
14127 // t: current time, b: begInnIng value, c: change In value, d: duration
14128 $.easing.jswing = $.easing.swing;
14129
14130 $.extend($.easing,
14131 {
14132         def: 'easeOutQuad',
14133         swing: function (x, t, b, c, d) {
14134                 //alert($.easing.default);
14135                 return $.easing[$.easing.def](x, t, b, c, d);
14136         },
14137         easeInQuad: function (x, t, b, c, d) {
14138                 return c*(t/=d)*t + b;
14139         },
14140         easeOutQuad: function (x, t, b, c, d) {
14141                 return -c *(t/=d)*(t-2) + b;
14142         },
14143         easeInOutQuad: function (x, t, b, c, d) {
14144                 if ((t/=d/2) < 1) return c/2*t*t + b;
14145                 return -c/2 * ((--t)*(t-2) - 1) + b;
14146         },
14147         easeInCubic: function (x, t, b, c, d) {
14148                 return c*(t/=d)*t*t + b;
14149         },
14150         easeOutCubic: function (x, t, b, c, d) {
14151                 return c*((t=t/d-1)*t*t + 1) + b;
14152         },
14153         easeInOutCubic: function (x, t, b, c, d) {
14154                 if ((t/=d/2) < 1) return c/2*t*t*t + b;
14155                 return c/2*((t-=2)*t*t + 2) + b;
14156         },
14157         easeInQuart: function (x, t, b, c, d) {
14158                 return c*(t/=d)*t*t*t + b;
14159         },
14160         easeOutQuart: function (x, t, b, c, d) {
14161                 return -c * ((t=t/d-1)*t*t*t - 1) + b;
14162         },
14163         easeInOutQuart: function (x, t, b, c, d) {
14164                 if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
14165                 return -c/2 * ((t-=2)*t*t*t - 2) + b;
14166         },
14167         easeInQuint: function (x, t, b, c, d) {
14168                 return c*(t/=d)*t*t*t*t + b;
14169         },
14170         easeOutQuint: function (x, t, b, c, d) {
14171                 return c*((t=t/d-1)*t*t*t*t + 1) + b;
14172         },
14173         easeInOutQuint: function (x, t, b, c, d) {
14174                 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
14175                 return c/2*((t-=2)*t*t*t*t + 2) + b;
14176         },
14177         easeInSine: function (x, t, b, c, d) {
14178                 return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
14179         },
14180         easeOutSine: function (x, t, b, c, d) {
14181                 return c * Math.sin(t/d * (Math.PI/2)) + b;
14182         },
14183         easeInOutSine: function (x, t, b, c, d) {
14184                 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
14185         },
14186         easeInExpo: function (x, t, b, c, d) {
14187                 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
14188         },
14189         easeOutExpo: function (x, t, b, c, d) {
14190                 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
14191         },
14192         easeInOutExpo: function (x, t, b, c, d) {
14193                 if (t==0) return b;
14194                 if (t==d) return b+c;
14195                 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
14196                 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
14197         },
14198         easeInCirc: function (x, t, b, c, d) {
14199                 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
14200         },
14201         easeOutCirc: function (x, t, b, c, d) {
14202                 return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
14203         },
14204         easeInOutCirc: function (x, t, b, c, d) {
14205                 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
14206                 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
14207         },
14208         easeInElastic: function (x, t, b, c, d) {
14209                 var s=1.70158;var p=0;var a=c;
14210                 if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
14211                 if (a < Math.abs(c)) { a=c; var s=p/4; }
14212                 else var s = p/(2*Math.PI) * Math.asin (c/a);
14213                 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
14214         },
14215         easeOutElastic: function (x, t, b, c, d) {
14216                 var s=1.70158;var p=0;var a=c;
14217                 if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
14218                 if (a < Math.abs(c)) { a=c; var s=p/4; }
14219                 else var s = p/(2*Math.PI) * Math.asin (c/a);
14220                 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
14221         },
14222         easeInOutElastic: function (x, t, b, c, d) {
14223                 var s=1.70158;var p=0;var a=c;
14224                 if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
14225                 if (a < Math.abs(c)) { a=c; var s=p/4; }
14226                 else var s = p/(2*Math.PI) * Math.asin (c/a);
14227                 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
14228                 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
14229         },
14230         easeInBack: function (x, t, b, c, d, s) {
14231                 if (s == undefined) s = 1.70158;
14232                 return c*(t/=d)*t*((s+1)*t - s) + b;
14233         },
14234         easeOutBack: function (x, t, b, c, d, s) {
14235                 if (s == undefined) s = 1.70158;
14236                 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
14237         },
14238         easeInOutBack: function (x, t, b, c, d, s) {
14239                 if (s == undefined) s = 1.70158;
14240                 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
14241                 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
14242         },
14243         easeInBounce: function (x, t, b, c, d) {
14244                 return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
14245         },
14246         easeOutBounce: function (x, t, b, c, d) {
14247                 if ((t/=d) < (1/2.75)) {
14248                         return c*(7.5625*t*t) + b;
14249                 } else if (t < (2/2.75)) {
14250                         return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
14251                 } else if (t < (2.5/2.75)) {
14252                         return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
14253                 } else {
14254                         return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
14255                 }
14256         },
14257         easeInOutBounce: function (x, t, b, c, d) {
14258                 if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
14259                 return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
14260         }
14261 });
14262
14263 /*
14264  *
14265  * TERMS OF USE - EASING EQUATIONS
14266  *
14267  * Open source under the BSD License.
14268  *
14269  * Copyright 2001 Robert Penner
14270  * All rights reserved.
14271  *
14272  * Redistribution and use in source and binary forms, with or without modification,
14273  * are permitted provided that the following conditions are met:
14274  *
14275  * Redistributions of source code must retain the above copyright notice, this list of
14276  * conditions and the following disclaimer.
14277  * Redistributions in binary form must reproduce the above copyright notice, this list
14278  * of conditions and the following disclaimer in the documentation and/or other materials
14279  * provided with the distribution.
14280  *
14281  * Neither the name of the author nor the names of contributors may be used to endorse
14282  * or promote products derived from this software without specific prior written permission.
14283  *
14284  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
14285  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14286  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
14287  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14288  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
14289  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
14290  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
14291  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
14292  * OF THE POSSIBILITY OF SUCH DAMAGE.
14293  *
14294  */
14295
14296 })(jQuery);
14297 /*
14298  * jQuery UI Effects Blind 1.8.12
14299  *
14300  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14301  * Dual licensed under the MIT or GPL Version 2 licenses.
14302  * http://jquery.org/license
14303  *
14304  * http://docs.jquery.com/UI/Effects/Blind
14305  *
14306  * Depends:
14307  *      jquery.effects.core.js
14308  */
14309 (function( $, undefined ) {
14310
14311 $.effects.blind = function(o) {
14312
14313         return this.queue(function() {
14314
14315                 // Create element
14316                 var el = $(this), props = ['position','top','bottom','left','right'];
14317
14318                 // Set options
14319                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
14320                 var direction = o.options.direction || 'vertical'; // Default direction
14321
14322                 // Adjust
14323                 $.effects.save(el, props); el.show(); // Save & Show
14324                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
14325                 var ref = (direction == 'vertical') ? 'height' : 'width';
14326                 var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
14327                 if(mode == 'show') wrapper.css(ref, 0); // Shift
14328
14329                 // Animation
14330                 var animation = {};
14331                 animation[ref] = mode == 'show' ? distance : 0;
14332
14333                 // Animate
14334                 wrapper.animate(animation, o.duration, o.options.easing, function() {
14335                         if(mode == 'hide') el.hide(); // Hide
14336                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14337                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
14338                         el.dequeue();
14339                 });
14340
14341         });
14342
14343 };
14344
14345 })(jQuery);
14346 /*
14347  * jQuery UI Effects Bounce 1.8.12
14348  *
14349  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14350  * Dual licensed under the MIT or GPL Version 2 licenses.
14351  * http://jquery.org/license
14352  *
14353  * http://docs.jquery.com/UI/Effects/Bounce
14354  *
14355  * Depends:
14356  *      jquery.effects.core.js
14357  */
14358 (function( $, undefined ) {
14359
14360 $.effects.bounce = function(o) {
14361
14362         return this.queue(function() {
14363
14364                 // Create element
14365                 var el = $(this), props = ['position','top','bottom','left','right'];
14366
14367                 // Set options
14368                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
14369                 var direction = o.options.direction || 'up'; // Default direction
14370                 var distance = o.options.distance || 20; // Default distance
14371                 var times = o.options.times || 5; // Default # of times
14372                 var speed = o.duration || 250; // Default speed per bounce
14373                 if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
14374
14375                 // Adjust
14376                 $.effects.save(el, props); el.show(); // Save & Show
14377                 $.effects.createWrapper(el); // Create Wrapper
14378                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
14379                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
14380                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
14381                 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
14382                 if (mode == 'hide') distance = distance / (times * 2);
14383                 if (mode != 'hide') times--;
14384
14385                 // Animate
14386                 if (mode == 'show') { // Show Bounce
14387                         var animation = {opacity: 1};
14388                         animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
14389                         el.animate(animation, speed / 2, o.options.easing);
14390                         distance = distance / 2;
14391                         times--;
14392                 };
14393                 for (var i = 0; i < times; i++) { // Bounces
14394                         var animation1 = {}, animation2 = {};
14395                         animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
14396                         animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
14397                         el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
14398                         distance = (mode == 'hide') ? distance * 2 : distance / 2;
14399                 };
14400                 if (mode == 'hide') { // Last Bounce
14401                         var animation = {opacity: 0};
14402                         animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
14403                         el.animate(animation, speed / 2, o.options.easing, function(){
14404                                 el.hide(); // Hide
14405                                 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14406                                 if(o.callback) o.callback.apply(this, arguments); // Callback
14407                         });
14408                 } else {
14409                         var animation1 = {}, animation2 = {};
14410                         animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
14411                         animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
14412                         el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
14413                                 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14414                                 if(o.callback) o.callback.apply(this, arguments); // Callback
14415                         });
14416                 };
14417                 el.queue('fx', function() { el.dequeue(); });
14418                 el.dequeue();
14419         });
14420
14421 };
14422
14423 })(jQuery);
14424 /*
14425  * jQuery UI Effects Clip 1.8.12
14426  *
14427  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14428  * Dual licensed under the MIT or GPL Version 2 licenses.
14429  * http://jquery.org/license
14430  *
14431  * http://docs.jquery.com/UI/Effects/Clip
14432  *
14433  * Depends:
14434  *      jquery.effects.core.js
14435  */
14436 (function( $, undefined ) {
14437
14438 $.effects.clip = function(o) {
14439
14440         return this.queue(function() {
14441
14442                 // Create element
14443                 var el = $(this), props = ['position','top','bottom','left','right','height','width'];
14444
14445                 // Set options
14446                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
14447                 var direction = o.options.direction || 'vertical'; // Default direction
14448
14449                 // Adjust
14450                 $.effects.save(el, props); el.show(); // Save & Show
14451                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
14452                 var animate = el[0].tagName == 'IMG' ? wrapper : el;
14453                 var ref = {
14454                         size: (direction == 'vertical') ? 'height' : 'width',
14455                         position: (direction == 'vertical') ? 'top' : 'left'
14456                 };
14457                 var distance = (direction == 'vertical') ? animate.height() : animate.width();
14458                 if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
14459
14460                 // Animation
14461                 var animation = {};
14462                 animation[ref.size] = mode == 'show' ? distance : 0;
14463                 animation[ref.position] = mode == 'show' ? 0 : distance / 2;
14464
14465                 // Animate
14466                 animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
14467                         if(mode == 'hide') el.hide(); // Hide
14468                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14469                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
14470                         el.dequeue();
14471                 }});
14472
14473         });
14474
14475 };
14476
14477 })(jQuery);
14478 /*
14479  * jQuery UI Effects Drop 1.8.12
14480  *
14481  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14482  * Dual licensed under the MIT or GPL Version 2 licenses.
14483  * http://jquery.org/license
14484  *
14485  * http://docs.jquery.com/UI/Effects/Drop
14486  *
14487  * Depends:
14488  *      jquery.effects.core.js
14489  */
14490 (function( $, undefined ) {
14491
14492 $.effects.drop = function(o) {
14493
14494         return this.queue(function() {
14495
14496                 // Create element
14497                 var el = $(this), props = ['position','top','bottom','left','right','opacity'];
14498
14499                 // Set options
14500                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
14501                 var direction = o.options.direction || 'left'; // Default Direction
14502
14503                 // Adjust
14504                 $.effects.save(el, props); el.show(); // Save & Show
14505                 $.effects.createWrapper(el); // Create Wrapper
14506                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
14507                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
14508                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
14509                 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
14510
14511                 // Animation
14512                 var animation = {opacity: mode == 'show' ? 1 : 0};
14513                 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
14514
14515                 // Animate
14516                 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
14517                         if(mode == 'hide') el.hide(); // Hide
14518                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14519                         if(o.callback) o.callback.apply(this, arguments); // Callback
14520                         el.dequeue();
14521                 }});
14522
14523         });
14524
14525 };
14526
14527 })(jQuery);
14528 /*
14529  * jQuery UI Effects Explode 1.8.12
14530  *
14531  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14532  * Dual licensed under the MIT or GPL Version 2 licenses.
14533  * http://jquery.org/license
14534  *
14535  * http://docs.jquery.com/UI/Effects/Explode
14536  *
14537  * Depends:
14538  *      jquery.effects.core.js
14539  */
14540 (function( $, undefined ) {
14541
14542 $.effects.explode = function(o) {
14543
14544         return this.queue(function() {
14545
14546         var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
14547         var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
14548
14549         o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
14550         var el = $(this).show().css('visibility', 'hidden');
14551         var offset = el.offset();
14552
14553         //Substract the margins - not fixing the problem yet.
14554         offset.top -= parseInt(el.css("marginTop"),10) || 0;
14555         offset.left -= parseInt(el.css("marginLeft"),10) || 0;
14556
14557         var width = el.outerWidth(true);
14558         var height = el.outerHeight(true);
14559
14560         for(var i=0;i<rows;i++) { // =
14561                 for(var j=0;j<cells;j++) { // ||
14562                         el
14563                                 .clone()
14564                                 .appendTo('body')
14565                                 .wrap('<div></div>')
14566                                 .css({
14567                                         position: 'absolute',
14568                                         visibility: 'visible',
14569                                         left: -j*(width/cells),
14570                                         top: -i*(height/rows)
14571                                 })
14572                                 .parent()
14573                                 .addClass('ui-effects-explode')
14574                                 .css({
14575                                         position: 'absolute',
14576                                         overflow: 'hidden',
14577                                         width: width/cells,
14578                                         height: height/rows,
14579                                         left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
14580                                         top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
14581                                         opacity: o.options.mode == 'show' ? 0 : 1
14582                                 }).animate({
14583                                         left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
14584                                         top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
14585                                         opacity: o.options.mode == 'show' ? 1 : 0
14586                                 }, o.duration || 500);
14587                 }
14588         }
14589
14590         // Set a timeout, to call the callback approx. when the other animations have finished
14591         setTimeout(function() {
14592
14593                 o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
14594                                 if(o.callback) o.callback.apply(el[0]); // Callback
14595                                 el.dequeue();
14596
14597                                 $('div.ui-effects-explode').remove();
14598
14599         }, o.duration || 500);
14600
14601
14602         });
14603
14604 };
14605
14606 })(jQuery);
14607 /*
14608  * jQuery UI Effects Fade 1.8.12
14609  *
14610  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14611  * Dual licensed under the MIT or GPL Version 2 licenses.
14612  * http://jquery.org/license
14613  *
14614  * http://docs.jquery.com/UI/Effects/Fade
14615  *
14616  * Depends:
14617  *      jquery.effects.core.js
14618  */
14619 (function( $, undefined ) {
14620
14621 $.effects.fade = function(o) {
14622         return this.queue(function() {
14623                 var elem = $(this),
14624                         mode = $.effects.setMode(elem, o.options.mode || 'hide');
14625
14626                 elem.animate({ opacity: mode }, {
14627                         queue: false,
14628                         duration: o.duration,
14629                         easing: o.options.easing,
14630                         complete: function() {
14631                                 (o.callback && o.callback.apply(this, arguments));
14632                                 elem.dequeue();
14633                         }
14634                 });
14635         });
14636 };
14637
14638 })(jQuery);
14639 /*
14640  * jQuery UI Effects Fold 1.8.12
14641  *
14642  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14643  * Dual licensed under the MIT or GPL Version 2 licenses.
14644  * http://jquery.org/license
14645  *
14646  * http://docs.jquery.com/UI/Effects/Fold
14647  *
14648  * Depends:
14649  *      jquery.effects.core.js
14650  */
14651 (function( $, undefined ) {
14652
14653 $.effects.fold = function(o) {
14654
14655         return this.queue(function() {
14656
14657                 // Create element
14658                 var el = $(this), props = ['position','top','bottom','left','right'];
14659
14660                 // Set options
14661                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
14662                 var size = o.options.size || 15; // Default fold size
14663                 var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
14664                 var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
14665
14666                 // Adjust
14667                 $.effects.save(el, props); el.show(); // Save & Show
14668                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
14669                 var widthFirst = ((mode == 'show') != horizFirst);
14670                 var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
14671                 var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
14672                 var percent = /([0-9]+)%/.exec(size);
14673                 if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
14674                 if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
14675
14676                 // Animation
14677                 var animation1 = {}, animation2 = {};
14678                 animation1[ref[0]] = mode == 'show' ? distance[0] : size;
14679                 animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
14680
14681                 // Animate
14682                 wrapper.animate(animation1, duration, o.options.easing)
14683                 .animate(animation2, duration, o.options.easing, function() {
14684                         if(mode == 'hide') el.hide(); // Hide
14685                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14686                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
14687                         el.dequeue();
14688                 });
14689
14690         });
14691
14692 };
14693
14694 })(jQuery);
14695 /*
14696  * jQuery UI Effects Highlight 1.8.12
14697  *
14698  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14699  * Dual licensed under the MIT or GPL Version 2 licenses.
14700  * http://jquery.org/license
14701  *
14702  * http://docs.jquery.com/UI/Effects/Highlight
14703  *
14704  * Depends:
14705  *      jquery.effects.core.js
14706  */
14707 (function( $, undefined ) {
14708
14709 $.effects.highlight = function(o) {
14710         return this.queue(function() {
14711                 var elem = $(this),
14712                         props = ['backgroundImage', 'backgroundColor', 'opacity'],
14713                         mode = $.effects.setMode(elem, o.options.mode || 'show'),
14714                         animation = {
14715                                 backgroundColor: elem.css('backgroundColor')
14716                         };
14717
14718                 if (mode == 'hide') {
14719                         animation.opacity = 0;
14720                 }
14721
14722                 $.effects.save(elem, props);
14723                 elem
14724                         .show()
14725                         .css({
14726                                 backgroundImage: 'none',
14727                                 backgroundColor: o.options.color || '#ffff99'
14728                         })
14729                         .animate(animation, {
14730                                 queue: false,
14731                                 duration: o.duration,
14732                                 easing: o.options.easing,
14733                                 complete: function() {
14734                                         (mode == 'hide' && elem.hide());
14735                                         $.effects.restore(elem, props);
14736                                         (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
14737                                         (o.callback && o.callback.apply(this, arguments));
14738                                         elem.dequeue();
14739                                 }
14740                         });
14741         });
14742 };
14743
14744 })(jQuery);
14745 /*
14746  * jQuery UI Effects Pulsate 1.8.12
14747  *
14748  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14749  * Dual licensed under the MIT or GPL Version 2 licenses.
14750  * http://jquery.org/license
14751  *
14752  * http://docs.jquery.com/UI/Effects/Pulsate
14753  *
14754  * Depends:
14755  *      jquery.effects.core.js
14756  */
14757 (function( $, undefined ) {
14758
14759 $.effects.pulsate = function(o) {
14760         return this.queue(function() {
14761                 var elem = $(this),
14762                         mode = $.effects.setMode(elem, o.options.mode || 'show');
14763                         times = ((o.options.times || 5) * 2) - 1;
14764                         duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
14765                         isVisible = elem.is(':visible'),
14766                         animateTo = 0;
14767
14768                 if (!isVisible) {
14769                         elem.css('opacity', 0).show();
14770                         animateTo = 1;
14771                 }
14772
14773                 if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
14774                         times--;
14775                 }
14776
14777                 for (var i = 0; i < times; i++) {
14778                         elem.animate({ opacity: animateTo }, duration, o.options.easing);
14779                         animateTo = (animateTo + 1) % 2;
14780                 }
14781
14782                 elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
14783                         if (animateTo == 0) {
14784                                 elem.hide();
14785                         }
14786                         (o.callback && o.callback.apply(this, arguments));
14787                 });
14788
14789                 elem
14790                         .queue('fx', function() { elem.dequeue(); })
14791                         .dequeue();
14792         });
14793 };
14794
14795 })(jQuery);
14796 /*
14797  * jQuery UI Effects Scale 1.8.12
14798  *
14799  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14800  * Dual licensed under the MIT or GPL Version 2 licenses.
14801  * http://jquery.org/license
14802  *
14803  * http://docs.jquery.com/UI/Effects/Scale
14804  *
14805  * Depends:
14806  *      jquery.effects.core.js
14807  */
14808 (function( $, undefined ) {
14809
14810 $.effects.puff = function(o) {
14811         return this.queue(function() {
14812                 var elem = $(this),
14813                         mode = $.effects.setMode(elem, o.options.mode || 'hide'),
14814                         percent = parseInt(o.options.percent, 10) || 150,
14815                         factor = percent / 100,
14816                         original = { height: elem.height(), width: elem.width() };
14817
14818                 $.extend(o.options, {
14819                         fade: true,
14820                         mode: mode,
14821                         percent: mode == 'hide' ? percent : 100,
14822                         from: mode == 'hide'
14823                                 ? original
14824                                 : {
14825                                         height: original.height * factor,
14826                                         width: original.width * factor
14827                                 }
14828                 });
14829
14830                 elem.effect('scale', o.options, o.duration, o.callback);
14831                 elem.dequeue();
14832         });
14833 };
14834
14835 $.effects.scale = function(o) {
14836
14837         return this.queue(function() {
14838
14839                 // Create element
14840                 var el = $(this);
14841
14842                 // Set options
14843                 var options = $.extend(true, {}, o.options);
14844                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
14845                 var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
14846                 var direction = o.options.direction || 'both'; // Set default axis
14847                 var origin = o.options.origin; // The origin of the scaling
14848                 if (mode != 'effect') { // Set default origin and restore for show/hide
14849                         options.origin = origin || ['middle','center'];
14850                         options.restore = true;
14851                 }
14852                 var original = {height: el.height(), width: el.width()}; // Save original
14853                 el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
14854
14855                 // Adjust
14856                 var factor = { // Set scaling factor
14857                         y: direction != 'horizontal' ? (percent / 100) : 1,
14858                         x: direction != 'vertical' ? (percent / 100) : 1
14859                 };
14860                 el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
14861
14862                 if (o.options.fade) { // Fade option to support puff
14863                         if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
14864                         if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
14865                 };
14866
14867                 // Animation
14868                 options.from = el.from; options.to = el.to; options.mode = mode;
14869
14870                 // Animate
14871                 el.effect('size', options, o.duration, o.callback);
14872                 el.dequeue();
14873         });
14874
14875 };
14876
14877 $.effects.size = function(o) {
14878
14879         return this.queue(function() {
14880
14881                 // Create element
14882                 var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
14883                 var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
14884                 var props2 = ['width','height','overflow']; // Copy for children
14885                 var cProps = ['fontSize'];
14886                 var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
14887                 var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
14888
14889                 // Set options
14890                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
14891                 var restore = o.options.restore || false; // Default restore
14892                 var scale = o.options.scale || 'both'; // Default scale mode
14893                 var origin = o.options.origin; // The origin of the sizing
14894                 var original = {height: el.height(), width: el.width()}; // Save original
14895                 el.from = o.options.from || original; // Default from state
14896                 el.to = o.options.to || original; // Default to state
14897                 // Adjust
14898                 if (origin) { // Calculate baseline shifts
14899                         var baseline = $.effects.getBaseline(origin, original);
14900                         el.from.top = (original.height - el.from.height) * baseline.y;
14901                         el.from.left = (original.width - el.from.width) * baseline.x;
14902                         el.to.top = (original.height - el.to.height) * baseline.y;
14903                         el.to.left = (original.width - el.to.width) * baseline.x;
14904                 };
14905                 var factor = { // Set scaling factor
14906                         from: {y: el.from.height / original.height, x: el.from.width / original.width},
14907                         to: {y: el.to.height / original.height, x: el.to.width / original.width}
14908                 };
14909                 if (scale == 'box' || scale == 'both') { // Scale the css box
14910                         if (factor.from.y != factor.to.y) { // Vertical props scaling
14911                                 props = props.concat(vProps);
14912                                 el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
14913                                 el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
14914                         };
14915                         if (factor.from.x != factor.to.x) { // Horizontal props scaling
14916                                 props = props.concat(hProps);
14917                                 el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
14918                                 el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
14919                         };
14920                 };
14921                 if (scale == 'content' || scale == 'both') { // Scale the content
14922                         if (factor.from.y != factor.to.y) { // Vertical props scaling
14923                                 props = props.concat(cProps);
14924                                 el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
14925                                 el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
14926                         };
14927                 };
14928                 $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
14929                 $.effects.createWrapper(el); // Create Wrapper
14930                 el.css('overflow','hidden').css(el.from); // Shift
14931
14932                 // Animate
14933                 if (scale == 'content' || scale == 'both') { // Scale the children
14934                         vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
14935                         hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
14936                         props2 = props.concat(vProps).concat(hProps); // Concat
14937                         el.find("*[width]").each(function(){
14938                                 child = $(this);
14939                                 if (restore) $.effects.save(child, props2);
14940                                 var c_original = {height: child.height(), width: child.width()}; // Save original
14941                                 child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
14942                                 child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
14943                                 if (factor.from.y != factor.to.y) { // Vertical props scaling
14944                                         child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
14945                                         child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
14946                                 };
14947                                 if (factor.from.x != factor.to.x) { // Horizontal props scaling
14948                                         child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
14949                                         child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
14950                                 };
14951                                 child.css(child.from); // Shift children
14952                                 child.animate(child.to, o.duration, o.options.easing, function(){
14953                                         if (restore) $.effects.restore(child, props2); // Restore children
14954                                 }); // Animate children
14955                         });
14956                 };
14957
14958                 // Animate
14959                 el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
14960                         if (el.to.opacity === 0) {
14961                                 el.css('opacity', el.from.opacity);
14962                         }
14963                         if(mode == 'hide') el.hide(); // Hide
14964                         $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
14965                         if(o.callback) o.callback.apply(this, arguments); // Callback
14966                         el.dequeue();
14967                 }});
14968
14969         });
14970
14971 };
14972
14973 })(jQuery);
14974 /*
14975  * jQuery UI Effects Shake 1.8.12
14976  *
14977  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14978  * Dual licensed under the MIT or GPL Version 2 licenses.
14979  * http://jquery.org/license
14980  *
14981  * http://docs.jquery.com/UI/Effects/Shake
14982  *
14983  * Depends:
14984  *      jquery.effects.core.js
14985  */
14986 (function( $, undefined ) {
14987
14988 $.effects.shake = function(o) {
14989
14990         return this.queue(function() {
14991
14992                 // Create element
14993                 var el = $(this), props = ['position','top','bottom','left','right'];
14994
14995                 // Set options
14996                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
14997                 var direction = o.options.direction || 'left'; // Default direction
14998                 var distance = o.options.distance || 20; // Default distance
14999                 var times = o.options.times || 3; // Default # of times
15000                 var speed = o.duration || o.options.duration || 140; // Default speed per shake
15001
15002                 // Adjust
15003                 $.effects.save(el, props); el.show(); // Save & Show
15004                 $.effects.createWrapper(el); // Create Wrapper
15005                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
15006                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
15007
15008                 // Animation
15009                 var animation = {}, animation1 = {}, animation2 = {};
15010                 animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
15011                 animation1[ref] = (motion == 'pos' ? '+=' : '-=')  + distance * 2;
15012                 animation2[ref] = (motion == 'pos' ? '-=' : '+=')  + distance * 2;
15013
15014                 // Animate
15015                 el.animate(animation, speed, o.options.easing);
15016                 for (var i = 1; i < times; i++) { // Shakes
15017                         el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
15018                 };
15019                 el.animate(animation1, speed, o.options.easing).
15020                 animate(animation, speed / 2, o.options.easing, function(){ // Last shake
15021                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
15022                         if(o.callback) o.callback.apply(this, arguments); // Callback
15023                 });
15024                 el.queue('fx', function() { el.dequeue(); });
15025                 el.dequeue();
15026         });
15027
15028 };
15029
15030 })(jQuery);
15031 /*
15032  * jQuery UI Effects Slide 1.8.12
15033  *
15034  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
15035  * Dual licensed under the MIT or GPL Version 2 licenses.
15036  * http://jquery.org/license
15037  *
15038  * http://docs.jquery.com/UI/Effects/Slide
15039  *
15040  * Depends:
15041  *      jquery.effects.core.js
15042  */
15043 (function( $, undefined ) {
15044
15045 $.effects.slide = function(o) {
15046
15047         return this.queue(function() {
15048
15049                 // Create element
15050                 var el = $(this), props = ['position','top','bottom','left','right'];
15051
15052                 // Set options
15053                 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
15054                 var direction = o.options.direction || 'left'; // Default Direction
15055
15056                 // Adjust
15057                 $.effects.save(el, props); el.show(); // Save & Show
15058                 $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
15059                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
15060                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
15061                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
15062                 if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
15063
15064                 // Animation
15065                 var animation = {};
15066                 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
15067
15068                 // Animate
15069                 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
15070                         if(mode == 'hide') el.hide(); // Hide
15071                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
15072                         if(o.callback) o.callback.apply(this, arguments); // Callback
15073                         el.dequeue();
15074                 }});
15075
15076         });
15077
15078 };
15079
15080 })(jQuery);
15081 /*
15082  * jQuery UI Effects Transfer 1.8.12
15083  *
15084  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
15085  * Dual licensed under the MIT or GPL Version 2 licenses.
15086  * http://jquery.org/license
15087  *
15088  * http://docs.jquery.com/UI/Effects/Transfer
15089  *
15090  * Depends:
15091  *      jquery.effects.core.js
15092  */
15093 (function( $, undefined ) {
15094
15095 $.effects.transfer = function(o) {
15096         return this.queue(function() {
15097                 var elem = $(this),
15098                         target = $(o.options.to),
15099                         endPosition = target.offset(),
15100                         animation = {
15101                                 top: endPosition.top,
15102                                 left: endPosition.left,
15103                                 height: target.innerHeight(),
15104                                 width: target.innerWidth()
15105                         },
15106                         startPosition = elem.offset(),
15107                         transfer = $('<div class="ui-effects-transfer"></div>')
15108                                 .appendTo(document.body)
15109                                 .addClass(o.options.className)
15110                                 .css({
15111                                         top: startPosition.top,
15112                                         left: startPosition.left,
15113                                         height: elem.innerHeight(),
15114                                         width: elem.innerWidth(),
15115                                         position: 'absolute'
15116                                 })
15117                                 .animate(animation, o.duration, o.options.easing, function() {
15118                                         transfer.remove();
15119                                         (o.callback && o.callback.apply(elem[0], arguments));
15120                                         elem.dequeue();
15121                                 });
15122         });
15123 };
15124
15125 })(jQuery);
15126 /*
15127  * jQuery UI Accordion 1.8.12
15128  *
15129  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
15130  * Dual licensed under the MIT or GPL Version 2 licenses.
15131  * http://jquery.org/license
15132  *
15133  * http://docs.jquery.com/UI/Accordion
15134  *
15135  * Depends:
15136  *      jquery.ui.core.js
15137  *      jquery.ui.widget.js
15138  */
15139 (function( $, undefined ) {
15140
15141 $.widget( "ui.accordion", {
15142         options: {
15143                 active: 0,
15144                 animated: "slide",
15145                 autoHeight: true,
15146                 clearStyle: false,
15147                 collapsible: false,
15148                 event: "click",
15149                 fillSpace: false,
15150                 header: "> li > :first-child,> :not(li):even",
15151                 icons: {
15152                         header: "ui-icon-triangle-1-e",
15153                         headerSelected: "ui-icon-triangle-1-s"
15154                 },
15155                 navigation: false,
15156                 navigationFilter: function() {
15157                         return this.href.toLowerCase() === location.href.toLowerCase();
15158                 }
15159         },
15160
15161         _create: function() {
15162                 var self = this,
15163                         options = self.options;
15164
15165                 self.running = 0;
15166
15167                 self.element
15168                         .addClass( "ui-accordion ui-widget ui-helper-reset" )
15169                         // in lack of child-selectors in CSS
15170                         // we need to mark top-LIs in a UL-accordion for some IE-fix
15171                         .children( "li" )
15172                                 .addClass( "ui-accordion-li-fix" );
15173
15174                 self.headers = self.element.find( options.header )
15175                         .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
15176                         .bind( "mouseenter.accordion", function() {
15177                                 if ( options.disabled ) {
15178                                         return;
15179                                 }
15180                                 $( this ).addClass( "ui-state-hover" );
15181                         })
15182                         .bind( "mouseleave.accordion", function() {
15183                                 if ( options.disabled ) {
15184                                         return;
15185                                 }
15186                                 $( this ).removeClass( "ui-state-hover" );
15187                         })
15188                         .bind( "focus.accordion", function() {
15189                                 if ( options.disabled ) {
15190                                         return;
15191                                 }
15192                                 $( this ).addClass( "ui-state-focus" );
15193                         })
15194                         .bind( "blur.accordion", function() {
15195                                 if ( options.disabled ) {
15196                                         return;
15197                                 }
15198                                 $( this ).removeClass( "ui-state-focus" );
15199                         });
15200
15201                 self.headers.next()
15202                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
15203
15204                 if ( options.navigation ) {
15205                         var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
15206                         if ( current.length ) {
15207                                 var header = current.closest( ".ui-accordion-header" );
15208                                 if ( header.length ) {
15209                                         // anchor within header
15210                                         self.active = header;
15211                                 } else {
15212                                         // anchor within content
15213                                         self.active = current.closest( ".ui-accordion-content" ).prev();
15214                                 }
15215                         }
15216                 }
15217
15218                 self.active = self._findActive( self.active || options.active )
15219                         .addClass( "ui-state-default ui-state-active" )
15220                         .toggleClass( "ui-corner-all" )
15221                         .toggleClass( "ui-corner-top" );
15222                 self.active.next().addClass( "ui-accordion-content-active" );
15223
15224                 self._createIcons();
15225                 self.resize();
15226                 
15227                 // ARIA
15228                 self.element.attr( "role", "tablist" );
15229
15230                 self.headers
15231                         .attr( "role", "tab" )
15232                         .bind( "keydown.accordion", function( event ) {
15233                                 return self._keydown( event );
15234                         })
15235                         .next()
15236                                 .attr( "role", "tabpanel" );
15237
15238                 self.headers
15239                         .not( self.active || "" )
15240                         .attr({
15241                                 "aria-expanded": "false",
15242                                 "aria-selected": "false",
15243                                 tabIndex: -1
15244                         })
15245                         .next()
15246                                 .hide();
15247
15248                 // make sure at least one header is in the tab order
15249                 if ( !self.active.length ) {
15250                         self.headers.eq( 0 ).attr( "tabIndex", 0 );
15251                 } else {
15252                         self.active
15253                                 .attr({
15254                                         "aria-expanded": "true",
15255                                         "aria-selected": "true",
15256                                         tabIndex: 0
15257                                 });
15258                 }
15259
15260                 // only need links in tab order for Safari
15261                 if ( !$.browser.safari ) {
15262                         self.headers.find( "a" ).attr( "tabIndex", -1 );
15263                 }
15264
15265                 if ( options.event ) {
15266                         self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
15267                                 self._clickHandler.call( self, event, this );
15268                                 event.preventDefault();
15269                         });
15270                 }
15271         },
15272
15273         _createIcons: function() {
15274                 var options = this.options;
15275                 if ( options.icons ) {
15276                         $( "<span></span>" )
15277                                 .addClass( "ui-icon " + options.icons.header )
15278                                 .prependTo( this.headers );
15279                         this.active.children( ".ui-icon" )
15280                                 .toggleClass(options.icons.header)
15281                                 .toggleClass(options.icons.headerSelected);
15282                         this.element.addClass( "ui-accordion-icons" );
15283                 }
15284         },
15285
15286         _destroyIcons: function() {
15287                 this.headers.children( ".ui-icon" ).remove();
15288                 this.element.removeClass( "ui-accordion-icons" );
15289         },
15290
15291         destroy: function() {
15292                 var options = this.options;
15293
15294                 this.element
15295                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
15296                         .removeAttr( "role" );
15297
15298                 this.headers
15299                         .unbind( ".accordion" )
15300                         .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
15301                         .removeAttr( "role" )
15302                         .removeAttr( "aria-expanded" )
15303                         .removeAttr( "aria-selected" )
15304                         .removeAttr( "tabIndex" );
15305
15306                 this.headers.find( "a" ).removeAttr( "tabIndex" );
15307                 this._destroyIcons();
15308                 var contents = this.headers.next()
15309                         .css( "display", "" )
15310                         .removeAttr( "role" )
15311                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
15312                 if ( options.autoHeight || options.fillHeight ) {
15313                         contents.css( "height", "" );
15314                 }
15315
15316                 return $.Widget.prototype.destroy.call( this );
15317         },
15318
15319         _setOption: function( key, value ) {
15320                 $.Widget.prototype._setOption.apply( this, arguments );
15321                         
15322                 if ( key == "active" ) {
15323                         this.activate( value );
15324                 }
15325                 if ( key == "icons" ) {
15326                         this._destroyIcons();
15327                         if ( value ) {
15328                                 this._createIcons();
15329                         }
15330                 }
15331                 // #5332 - opacity doesn't cascade to positioned elements in IE
15332                 // so we need to add the disabled class to the headers and panels
15333                 if ( key == "disabled" ) {
15334                         this.headers.add(this.headers.next())
15335                                 [ value ? "addClass" : "removeClass" ](
15336                                         "ui-accordion-disabled ui-state-disabled" );
15337                 }
15338         },
15339
15340         _keydown: function( event ) {
15341                 if ( this.options.disabled || event.altKey || event.ctrlKey ) {
15342                         return;
15343                 }
15344
15345                 var keyCode = $.ui.keyCode,
15346                         length = this.headers.length,
15347                         currentIndex = this.headers.index( event.target ),
15348                         toFocus = false;
15349
15350                 switch ( event.keyCode ) {
15351                         case keyCode.RIGHT:
15352                         case keyCode.DOWN:
15353                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
15354                                 break;
15355                         case keyCode.LEFT:
15356                         case keyCode.UP:
15357                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
15358                                 break;
15359                         case keyCode.SPACE:
15360                         case keyCode.ENTER:
15361                                 this._clickHandler( { target: event.target }, event.target );
15362                                 event.preventDefault();
15363                 }
15364
15365                 if ( toFocus ) {
15366                         $( event.target ).attr( "tabIndex", -1 );
15367                         $( toFocus ).attr( "tabIndex", 0 );
15368                         toFocus.focus();
15369                         return false;
15370                 }
15371
15372                 return true;
15373         },
15374
15375         resize: function() {
15376                 var options = this.options,
15377                         maxHeight;
15378
15379                 if ( options.fillSpace ) {
15380                         if ( $.browser.msie ) {
15381                                 var defOverflow = this.element.parent().css( "overflow" );
15382                                 this.element.parent().css( "overflow", "hidden");
15383                         }
15384                         maxHeight = this.element.parent().height();
15385                         if ($.browser.msie) {
15386                                 this.element.parent().css( "overflow", defOverflow );
15387                         }
15388
15389                         this.headers.each(function() {
15390                                 maxHeight -= $( this ).outerHeight( true );
15391                         });
15392
15393                         this.headers.next()
15394                                 .each(function() {
15395                                         $( this ).height( Math.max( 0, maxHeight -
15396                                                 $( this ).innerHeight() + $( this ).height() ) );
15397                                 })
15398                                 .css( "overflow", "auto" );
15399                 } else if ( options.autoHeight ) {
15400                         maxHeight = 0;
15401                         this.headers.next()
15402                                 .each(function() {
15403                                         maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15404                                 })
15405                                 .height( maxHeight );
15406                 }
15407
15408                 return this;
15409         },
15410
15411         activate: function( index ) {
15412                 // TODO this gets called on init, changing the option without an explicit call for that
15413                 this.options.active = index;
15414                 // call clickHandler with custom event
15415                 var active = this._findActive( index )[ 0 ];
15416                 this._clickHandler( { target: active }, active );
15417
15418                 return this;
15419         },
15420
15421         _findActive: function( selector ) {
15422                 return selector
15423                         ? typeof selector === "number"
15424                                 ? this.headers.filter( ":eq(" + selector + ")" )
15425                                 : this.headers.not( this.headers.not( selector ) )
15426                         : selector === false
15427                                 ? $( [] )
15428                                 : this.headers.filter( ":eq(0)" );
15429         },
15430
15431         // TODO isn't event.target enough? why the separate target argument?
15432         _clickHandler: function( event, target ) {
15433                 var options = this.options;
15434                 if ( options.disabled ) {
15435                         return;
15436                 }
15437
15438                 // called only when using activate(false) to close all parts programmatically
15439                 if ( !event.target ) {
15440                         if ( !options.collapsible ) {
15441                                 return;
15442                         }
15443                         this.active
15444                                 .removeClass( "ui-state-active ui-corner-top" )
15445                                 .addClass( "ui-state-default ui-corner-all" )
15446                                 .children( ".ui-icon" )
15447                                         .removeClass( options.icons.headerSelected )
15448                                         .addClass( options.icons.header );
15449                         this.active.next().addClass( "ui-accordion-content-active" );
15450                         var toHide = this.active.next(),
15451                                 data = {
15452                                         options: options,
15453                                         newHeader: $( [] ),
15454                                         oldHeader: options.active,
15455                                         newContent: $( [] ),
15456                                         oldContent: toHide
15457                                 },
15458                                 toShow = ( this.active = $( [] ) );
15459                         this._toggle( toShow, toHide, data );
15460                         return;
15461                 }
15462
15463                 // get the click target
15464                 var clicked = $( event.currentTarget || target ),
15465                         clickedIsActive = clicked[0] === this.active[0];
15466
15467                 // TODO the option is changed, is that correct?
15468                 // TODO if it is correct, shouldn't that happen after determining that the click is valid?
15469                 options.active = options.collapsible && clickedIsActive ?
15470                         false :
15471                         this.headers.index( clicked );
15472
15473                 // if animations are still active, or the active header is the target, ignore click
15474                 if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
15475                         return;
15476                 }
15477
15478                 // find elements to show and hide
15479                 var active = this.active,
15480                         toShow = clicked.next(),
15481                         toHide = this.active.next(),
15482                         data = {
15483                                 options: options,
15484                                 newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
15485                                 oldHeader: this.active,
15486                                 newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
15487                                 oldContent: toHide
15488                         },
15489                         down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
15490
15491                 // when the call to ._toggle() comes after the class changes
15492                 // it causes a very odd bug in IE 8 (see #6720)
15493                 this.active = clickedIsActive ? $([]) : clicked;
15494                 this._toggle( toShow, toHide, data, clickedIsActive, down );
15495
15496                 // switch classes
15497                 active
15498                         .removeClass( "ui-state-active ui-corner-top" )
15499                         .addClass( "ui-state-default ui-corner-all" )
15500                         .children( ".ui-icon" )
15501                                 .removeClass( options.icons.headerSelected )
15502                                 .addClass( options.icons.header );
15503                 if ( !clickedIsActive ) {
15504                         clicked
15505                                 .removeClass( "ui-state-default ui-corner-all" )
15506                                 .addClass( "ui-state-active ui-corner-top" )
15507                                 .children( ".ui-icon" )
15508                                         .removeClass( options.icons.header )
15509                                         .addClass( options.icons.headerSelected );
15510                         clicked
15511                                 .next()
15512                                 .addClass( "ui-accordion-content-active" );
15513                 }
15514
15515                 return;
15516         },
15517
15518         _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
15519                 var self = this,
15520                         options = self.options;
15521
15522                 self.toShow = toShow;
15523                 self.toHide = toHide;
15524                 self.data = data;
15525
15526                 var complete = function() {
15527                         if ( !self ) {
15528                                 return;
15529                         }
15530                         return self._completed.apply( self, arguments );
15531                 };
15532
15533                 // trigger changestart event
15534                 self._trigger( "changestart", null, self.data );
15535
15536                 // count elements to animate
15537                 self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
15538
15539                 if ( options.animated ) {
15540                         var animOptions = {};
15541
15542                         if ( options.collapsible && clickedIsActive ) {
15543                                 animOptions = {
15544                                         toShow: $( [] ),
15545                                         toHide: toHide,
15546                                         complete: complete,
15547                                         down: down,
15548                                         autoHeight: options.autoHeight || options.fillSpace
15549                                 };
15550                         } else {
15551                                 animOptions = {
15552                                         toShow: toShow,
15553                                         toHide: toHide,
15554                                         complete: complete,
15555                                         down: down,
15556                                         autoHeight: options.autoHeight || options.fillSpace
15557                                 };
15558                         }
15559
15560                         if ( !options.proxied ) {
15561                                 options.proxied = options.animated;
15562                         }
15563
15564                         if ( !options.proxiedDuration ) {
15565                                 options.proxiedDuration = options.duration;
15566                         }
15567
15568                         options.animated = $.isFunction( options.proxied ) ?
15569                                 options.proxied( animOptions ) :
15570                                 options.proxied;
15571
15572                         options.duration = $.isFunction( options.proxiedDuration ) ?
15573                                 options.proxiedDuration( animOptions ) :
15574                                 options.proxiedDuration;
15575
15576                         var animations = $.ui.accordion.animations,
15577                                 duration = options.duration,
15578                                 easing = options.animated;
15579
15580                         if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
15581                                 easing = "slide";
15582                         }
15583                         if ( !animations[ easing ] ) {
15584                                 animations[ easing ] = function( options ) {
15585                                         this.slide( options, {
15586                                                 easing: easing,
15587                                                 duration: duration || 700
15588                                         });
15589                                 };
15590                         }
15591
15592                         animations[ easing ]( animOptions );
15593                 } else {
15594                         if ( options.collapsible && clickedIsActive ) {
15595                                 toShow.toggle();
15596                         } else {
15597                                 toHide.hide();
15598                                 toShow.show();
15599                         }
15600
15601                         complete( true );
15602                 }
15603
15604                 // TODO assert that the blur and focus triggers are really necessary, remove otherwise
15605                 toHide.prev()
15606                         .attr({
15607                                 "aria-expanded": "false",
15608                                 "aria-selected": "false",
15609                                 tabIndex: -1
15610                         })
15611                         .blur();
15612                 toShow.prev()
15613                         .attr({
15614                                 "aria-expanded": "true",
15615                                 "aria-selected": "true",
15616                                 tabIndex: 0
15617                         })
15618                         .focus();
15619         },
15620
15621         _completed: function( cancel ) {
15622                 this.running = cancel ? 0 : --this.running;
15623                 if ( this.running ) {
15624                         return;
15625                 }
15626
15627                 if ( this.options.clearStyle ) {
15628                         this.toShow.add( this.toHide ).css({
15629                                 height: "",
15630                                 overflow: ""
15631                         });
15632                 }
15633
15634                 // other classes are removed before the animation; this one needs to stay until completed
15635                 this.toHide.removeClass( "ui-accordion-content-active" );
15636                 // Work around for rendering bug in IE (#5421)
15637                 if ( this.toHide.length ) {
15638                         this.toHide.parent()[0].className = this.toHide.parent()[0].className;
15639                 }
15640
15641                 this._trigger( "change", null, this.data );
15642         }
15643 });
15644
15645 $.extend( $.ui.accordion, {
15646         version: "1.8.12",
15647         animations: {
15648                 slide: function( options, additions ) {
15649                         options = $.extend({
15650                                 easing: "swing",
15651                                 duration: 300
15652                         }, options, additions );
15653                         if ( !options.toHide.size() ) {
15654                                 options.toShow.animate({
15655                                         height: "show",
15656                                         paddingTop: "show",
15657                                         paddingBottom: "show"
15658                                 }, options );
15659                                 return;
15660                         }
15661                         if ( !options.toShow.size() ) {
15662                                 options.toHide.animate({
15663                                         height: "hide",
15664                                         paddingTop: "hide",
15665                                         paddingBottom: "hide"
15666                                 }, options );
15667                                 return;
15668                         }
15669                         var overflow = options.toShow.css( "overflow" ),
15670                                 percentDone = 0,
15671                                 showProps = {},
15672                                 hideProps = {},
15673                                 fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
15674                                 originalWidth;
15675                         // fix width before calculating height of hidden element
15676                         var s = options.toShow;
15677                         originalWidth = s[0].style.width;
15678                         s.width( parseInt( s.parent().width(), 10 )
15679                                 - parseInt( s.css( "paddingLeft" ), 10 )
15680                                 - parseInt( s.css( "paddingRight" ), 10 )
15681                                 - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 )
15682                                 - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) );
15683
15684                         $.each( fxAttrs, function( i, prop ) {
15685                                 hideProps[ prop ] = "hide";
15686
15687                                 var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
15688                                 showProps[ prop ] = {
15689                                         value: parts[ 1 ],
15690                                         unit: parts[ 2 ] || "px"
15691                                 };
15692                         });
15693                         options.toShow.css({ height: 0, overflow: "hidden" }).show();
15694                         options.toHide
15695                                 .filter( ":hidden" )
15696                                         .each( options.complete )
15697                                 .end()
15698                                 .filter( ":visible" )
15699                                 .animate( hideProps, {
15700                                 step: function( now, settings ) {
15701                                         // only calculate the percent when animating height
15702                                         // IE gets very inconsistent results when animating elements
15703                                         // with small values, which is common for padding
15704                                         if ( settings.prop == "height" ) {
15705                                                 percentDone = ( settings.end - settings.start === 0 ) ? 0 :
15706                                                         ( settings.now - settings.start ) / ( settings.end - settings.start );
15707                                         }
15708
15709                                         options.toShow[ 0 ].style[ settings.prop ] =
15710                                                 ( percentDone * showProps[ settings.prop ].value )
15711                                                 + showProps[ settings.prop ].unit;
15712                                 },
15713                                 duration: options.duration,
15714                                 easing: options.easing,
15715                                 complete: function() {
15716                                         if ( !options.autoHeight ) {
15717                                                 options.toShow.css( "height", "" );
15718                                         }
15719                                         options.toShow.css({
15720                                                 width: originalWidth,
15721                                                 overflow: overflow
15722                                         });
15723                                         options.complete();
15724                                 }
15725                         });
15726                 },
15727                 bounceslide: function( options ) {
15728                         this.slide( options, {
15729                                 easing: options.down ? "easeOutBounce" : "swing",
15730                                 duration: options.down ? 1000 : 200
15731                         });
15732                 }
15733         }
15734 });
15735
15736 })( jQuery );
15737 /*
15738  * jQuery UI Autocomplete 1.8.12
15739  *
15740  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
15741  * Dual licensed under the MIT or GPL Version 2 licenses.
15742  * http://jquery.org/license
15743  *
15744  * http://docs.jquery.com/UI/Autocomplete
15745  *
15746  * Depends:
15747  *      jquery.ui.core.js
15748  *      jquery.ui.widget.js
15749  *      jquery.ui.position.js
15750  */
15751 (function( $, undefined ) {
15752
15753 // used to prevent race conditions with remote data sources
15754 var requestIndex = 0;
15755
15756 $.widget( "ui.autocomplete", {
15757         options: {
15758                 appendTo: "body",
15759                 autoFocus: false,
15760                 delay: 300,
15761                 minLength: 1,
15762                 position: {
15763                         my: "left top",
15764                         at: "left bottom",
15765                         collision: "none"
15766                 },
15767                 source: null
15768         },
15769
15770         pending: 0,
15771
15772         _create: function() {
15773                 var self = this,
15774                         doc = this.element[ 0 ].ownerDocument,
15775                         suppressKeyPress;
15776
15777                 this.element
15778                         .addClass( "ui-autocomplete-input" )
15779                         .attr( "autocomplete", "off" )
15780                         // TODO verify these actually work as intended
15781                         .attr({
15782                                 role: "textbox",
15783                                 "aria-autocomplete": "list",
15784                                 "aria-haspopup": "true"
15785                         })
15786                         .bind( "keydown.autocomplete", function( event ) {
15787                                 if ( self.options.disabled || self.element.attr( "readonly" ) ) {
15788                                         return;
15789                                 }
15790
15791                                 suppressKeyPress = false;
15792                                 var keyCode = $.ui.keyCode;
15793                                 switch( event.keyCode ) {
15794                                 case keyCode.PAGE_UP:
15795                                         self._move( "previousPage", event );
15796                                         break;
15797                                 case keyCode.PAGE_DOWN:
15798                                         self._move( "nextPage", event );
15799                                         break;
15800                                 case keyCode.UP:
15801                                         self._move( "previous", event );
15802                                         // prevent moving cursor to beginning of text field in some browsers
15803                                         event.preventDefault();
15804                                         break;
15805                                 case keyCode.DOWN:
15806                                         self._move( "next", event );
15807                                         // prevent moving cursor to end of text field in some browsers
15808                                         event.preventDefault();
15809                                         break;
15810                                 case keyCode.ENTER:
15811                                 case keyCode.NUMPAD_ENTER:
15812                                         // when menu is open and has focus
15813                                         if ( self.menu.active ) {
15814                                                 // #6055 - Opera still allows the keypress to occur
15815                                                 // which causes forms to submit
15816                                                 suppressKeyPress = true;
15817                                                 event.preventDefault();
15818                                         }
15819                                         //passthrough - ENTER and TAB both select the current element
15820                                 case keyCode.TAB:
15821                                         if ( !self.menu.active ) {
15822                                                 return;
15823                                         }
15824                                         self.menu.select( event );
15825                                         break;
15826                                 case keyCode.ESCAPE:
15827                                         self.element.val( self.term );
15828                                         self.close( event );
15829                                         break;
15830                                 default:
15831                                         // keypress is triggered before the input value is changed
15832                                         clearTimeout( self.searching );
15833                                         self.searching = setTimeout(function() {
15834                                                 // only search if the value has changed
15835                                                 if ( self.term != self.element.val() ) {
15836                                                         self.selectedItem = null;
15837                                                         self.search( null, event );
15838                                                 }
15839                                         }, self.options.delay );
15840                                         break;
15841                                 }
15842                         })
15843                         .bind( "keypress.autocomplete", function( event ) {
15844                                 if ( suppressKeyPress ) {
15845                                         suppressKeyPress = false;
15846                                         event.preventDefault();
15847                                 }
15848                         })
15849                         .bind( "focus.autocomplete", function() {
15850                                 if ( self.options.disabled ) {
15851                                         return;
15852                                 }
15853
15854                                 self.selectedItem = null;
15855                                 self.previous = self.element.val();
15856                         })
15857                         .bind( "blur.autocomplete", function( event ) {
15858                                 if ( self.options.disabled ) {
15859                                         return;
15860                                 }
15861
15862                                 clearTimeout( self.searching );
15863                                 // clicks on the menu (or a button to trigger a search) will cause a blur event
15864                                 self.closing = setTimeout(function() {
15865                                         self.close( event );
15866                                         self._change( event );
15867                                 }, 150 );
15868                         });
15869                 this._initSource();
15870                 this.response = function() {
15871                         return self._response.apply( self, arguments );
15872                 };
15873                 this.menu = $( "<ul></ul>" )
15874                         .addClass( "ui-autocomplete" )
15875                         .appendTo( $( this.options.appendTo || "body", doc )[0] )
15876                         // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
15877                         .mousedown(function( event ) {
15878                                 // clicking on the scrollbar causes focus to shift to the body
15879                                 // but we can't detect a mouseup or a click immediately afterward
15880                                 // so we have to track the next mousedown and close the menu if
15881                                 // the user clicks somewhere outside of the autocomplete
15882                                 var menuElement = self.menu.element[ 0 ];
15883                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
15884                                         setTimeout(function() {
15885                                                 $( document ).one( 'mousedown', function( event ) {
15886                                                         if ( event.target !== self.element[ 0 ] &&
15887                                                                 event.target !== menuElement &&
15888                                                                 !$.ui.contains( menuElement, event.target ) ) {
15889                                                                 self.close();
15890                                                         }
15891                                                 });
15892                                         }, 1 );
15893                                 }
15894
15895                                 // use another timeout to make sure the blur-event-handler on the input was already triggered
15896                                 setTimeout(function() {
15897                                         clearTimeout( self.closing );
15898                                 }, 13);
15899                         })
15900                         .menu({
15901                                 focus: function( event, ui ) {
15902                                         var item = ui.item.data( "item.autocomplete" );
15903                                         if ( false !== self._trigger( "focus", event, { item: item } ) ) {
15904                                                 // use value to match what will end up in the input, if it was a key event
15905                                                 if ( /^key/.test(event.originalEvent.type) ) {
15906                                                         self.element.val( item.value );
15907                                                 }
15908                                         }
15909                                 },
15910                                 selected: function( event, ui ) {
15911                                         var item = ui.item.data( "item.autocomplete" ),
15912                                                 previous = self.previous;
15913
15914                                         // only trigger when focus was lost (click on menu)
15915                                         if ( self.element[0] !== doc.activeElement ) {
15916                                                 self.element.focus();
15917                                                 self.previous = previous;
15918                                                 // #6109 - IE triggers two focus events and the second
15919                                                 // is asynchronous, so we need to reset the previous
15920                                                 // term synchronously and asynchronously :-(
15921                                                 setTimeout(function() {
15922                                                         self.previous = previous;
15923                                                         self.selectedItem = item;
15924                                                 }, 1);
15925                                         }
15926
15927                                         if ( false !== self._trigger( "select", event, { item: item } ) ) {
15928                                                 self.element.val( item.value );
15929                                         }
15930                                         // reset the term after the select event
15931                                         // this allows custom select handling to work properly
15932                                         self.term = self.element.val();
15933
15934                                         self.close( event );
15935                                         self.selectedItem = item;
15936                                 },
15937                                 blur: function( event, ui ) {
15938                                         // don't set the value of the text field if it's already correct
15939                                         // this prevents moving the cursor unnecessarily
15940                                         if ( self.menu.element.is(":visible") &&
15941                                                 ( self.element.val() !== self.term ) ) {
15942                                                 self.element.val( self.term );
15943                                         }
15944                                 }
15945                         })
15946                         .zIndex( this.element.zIndex() + 1 )
15947                         // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
15948                         .css({ top: 0, left: 0 })
15949                         .hide()
15950                         .data( "menu" );
15951                 if ( $.fn.bgiframe ) {
15952                          this.menu.element.bgiframe();
15953                 }
15954         },
15955
15956         destroy: function() {
15957                 this.element
15958                         .removeClass( "ui-autocomplete-input" )
15959                         .removeAttr( "autocomplete" )
15960                         .removeAttr( "role" )
15961                         .removeAttr( "aria-autocomplete" )
15962                         .removeAttr( "aria-haspopup" );
15963                 this.menu.element.remove();
15964                 $.Widget.prototype.destroy.call( this );
15965         },
15966
15967         _setOption: function( key, value ) {
15968                 $.Widget.prototype._setOption.apply( this, arguments );
15969                 if ( key === "source" ) {
15970                         this._initSource();
15971                 }
15972                 if ( key === "appendTo" ) {
15973                         this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
15974                 }
15975                 if ( key === "disabled" && value && this.xhr ) {
15976                         this.xhr.abort();
15977                 }
15978         },
15979
15980         _initSource: function() {
15981                 var self = this,
15982                         array,
15983                         url;
15984                 if ( $.isArray(this.options.source) ) {
15985                         array = this.options.source;
15986                         this.source = function( request, response ) {
15987                                 response( $.ui.autocomplete.filter(array, request.term) );
15988                         };
15989                 } else if ( typeof this.options.source === "string" ) {
15990                         url = this.options.source;
15991                         this.source = function( request, response ) {
15992                                 if ( self.xhr ) {
15993                                         self.xhr.abort();
15994                                 }
15995                                 self.xhr = $.ajax({
15996                                         url: url,
15997                                         data: request,
15998                                         dataType: "json",
15999                                         autocompleteRequest: ++requestIndex,
16000                                         success: function( data, status ) {
16001                                                 if ( this.autocompleteRequest === requestIndex ) {
16002                                                         response( data );
16003                                                 }
16004                                         },
16005                                         error: function() {
16006                                                 if ( this.autocompleteRequest === requestIndex ) {
16007                                                         response( [] );
16008                                                 }
16009                                         }
16010                                 });
16011                         };
16012                 } else {
16013                         this.source = this.options.source;
16014                 }
16015         },
16016
16017         search: function( value, event ) {
16018                 value = value != null ? value : this.element.val();
16019
16020                 // always save the actual value, not the one passed as an argument
16021                 this.term = this.element.val();
16022
16023                 if ( value.length < this.options.minLength ) {
16024                         return this.close( event );
16025                 }
16026
16027                 clearTimeout( this.closing );
16028                 if ( this._trigger( "search", event ) === false ) {
16029                         return;
16030                 }
16031
16032                 return this._search( value );
16033         },
16034
16035         _search: function( value ) {
16036                 this.pending++;
16037                 this.element.addClass( "ui-autocomplete-loading" );
16038
16039                 this.source( { term: value }, this.response );
16040         },
16041
16042         _response: function( content ) {
16043                 if ( !this.options.disabled && content && content.length ) {
16044                         content = this._normalize( content );
16045                         this._suggest( content );
16046                         this._trigger( "open" );
16047                 } else {
16048                         this.close();
16049                 }
16050                 this.pending--;
16051                 if ( !this.pending ) {
16052                         this.element.removeClass( "ui-autocomplete-loading" );
16053                 }
16054         },
16055
16056         close: function( event ) {
16057                 clearTimeout( this.closing );
16058                 if ( this.menu.element.is(":visible") ) {
16059                         this.menu.element.hide();
16060                         this.menu.deactivate();
16061                         this._trigger( "close", event );
16062                 }
16063         },
16064         
16065         _change: function( event ) {
16066                 if ( this.previous !== this.element.val() ) {
16067                         this._trigger( "change", event, { item: this.selectedItem } );
16068                 }
16069         },
16070
16071         _normalize: function( items ) {
16072                 // assume all items have the right format when the first item is complete
16073                 if ( items.length && items[0].label && items[0].value ) {
16074                         return items;
16075                 }
16076                 return $.map( items, function(item) {
16077                         if ( typeof item === "string" ) {
16078                                 return {
16079                                         label: item,
16080                                         value: item
16081                                 };
16082                         }
16083                         return $.extend({
16084                                 label: item.label || item.value,
16085                                 value: item.value || item.label
16086                         }, item );
16087                 });
16088         },
16089
16090         _suggest: function( items ) {
16091                 var ul = this.menu.element
16092                         .empty()
16093                         .zIndex( this.element.zIndex() + 1 );
16094                 this._renderMenu( ul, items );
16095                 // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
16096                 this.menu.deactivate();
16097                 this.menu.refresh();
16098
16099                 // size and position menu
16100                 ul.show();
16101                 this._resizeMenu();
16102                 ul.position( $.extend({
16103                         of: this.element
16104                 }, this.options.position ));
16105
16106                 if ( this.options.autoFocus ) {
16107                         this.menu.next( new $.Event("mouseover") );
16108                 }
16109         },
16110
16111         _resizeMenu: function() {
16112                 var ul = this.menu.element;
16113                 ul.outerWidth( Math.max(
16114                         ul.width( "" ).outerWidth(),
16115                         this.element.outerWidth()
16116                 ) );
16117         },
16118
16119         _renderMenu: function( ul, items ) {
16120                 var self = this;
16121                 $.each( items, function( index, item ) {
16122                         self._renderItem( ul, item );
16123                 });
16124         },
16125
16126         _renderItem: function( ul, item) {
16127                 return $( "<li></li>" )
16128                         .data( "item.autocomplete", item )
16129                         .append( $( "<a></a>" ).text( item.label ) )
16130                         .appendTo( ul );
16131         },
16132
16133         _move: function( direction, event ) {
16134                 if ( !this.menu.element.is(":visible") ) {
16135                         this.search( null, event );
16136                         return;
16137                 }
16138                 if ( this.menu.first() && /^previous/.test(direction) ||
16139                                 this.menu.last() && /^next/.test(direction) ) {
16140                         this.element.val( this.term );
16141                         this.menu.deactivate();
16142                         return;
16143                 }
16144                 this.menu[ direction ]( event );
16145         },
16146
16147         widget: function() {
16148                 return this.menu.element;
16149         }
16150 });
16151
16152 $.extend( $.ui.autocomplete, {
16153         escapeRegex: function( value ) {
16154                 return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
16155         },
16156         filter: function(array, term) {
16157                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
16158                 return $.grep( array, function(value) {
16159                         return matcher.test( value.label || value.value || value );
16160                 });
16161         }
16162 });
16163
16164 }( jQuery ));
16165
16166 /*
16167  * jQuery UI Menu (not officially released)
16168  * 
16169  * This widget isn't yet finished and the API is subject to change. We plan to finish
16170  * it for the next release. You're welcome to give it a try anyway and give us feedback,
16171  * as long as you're okay with migrating your code later on. We can help with that, too.
16172  *
16173  * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
16174  * Dual licensed under the MIT or GPL Version 2 licenses.
16175  * http://jquery.org/license
16176  *
16177  * http://docs.jquery.com/UI/Menu
16178  *
16179  * Depends:
16180  *      jquery.ui.core.js
16181  *  jquery.ui.widget.js
16182  */
16183 (function($) {
16184
16185 $.widget("ui.menu", {
16186         _create: function() {
16187                 var self = this;
16188                 this.element
16189                         .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
16190                         .attr({
16191                                 role: "listbox",
16192                                 "aria-activedescendant": "ui-active-menuitem"
16193                         })
16194                         .click(function( event ) {
16195                                 if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
16196                                         return;
16197                                 }
16198                                 // temporary
16199                                 event.preventDefault();
16200                                 self.select( event );
16201                         });
16202                 this.refresh();
16203         },
16204         
16205         refresh: function() {
16206                 var self = this;
16207
16208                 // don't refresh list items that are already adapted
16209                 var items = this.element.children("li:not(.ui-menu-item):has(a)")
16210                         .addClass("ui-menu-item")
16211                         .attr("role", "menuitem");
16212                 
16213                 items.children("a")
16214                         .addClass("ui-corner-all")
16215                         .attr("tabindex", -1)
16216                         // mouseenter doesn't work with event delegation
16217                         .mouseenter(function( event ) {
16218                                 self.activate( event, $(this).parent() );
16219                         })
16220                         .mouseleave(function() {
16221                                 self.deactivate();
16222                         });
16223         },
16224
16225         activate: function( event, item ) {
16226                 this.deactivate();
16227                 if (this.hasScroll()) {
16228                         var offset = item.offset().top - this.element.offset().top,
16229                                 scroll = this.element.attr("scrollTop"),
16230                                 elementHeight = this.element.height();
16231                         if (offset < 0) {
16232                                 this.element.attr("scrollTop", scroll + offset);
16233                         } else if (offset >= elementHeight) {
16234                                 this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
16235                         }
16236                 }
16237                 this.active = item.eq(0)
16238                         .children("a")
16239                                 .addClass("ui-state-hover")
16240                                 .attr("id", "ui-active-menuitem")
16241                         .end();
16242                 this._trigger("focus", event, { item: item });
16243         },
16244
16245         deactivate: function() {
16246                 if (!this.active) { return; }
16247
16248                 this.active.children("a")
16249                         .removeClass("ui-state-hover")
16250                         .removeAttr("id");
16251                 this._trigger("blur");
16252                 this.active = null;
16253         },
16254
16255         next: function(event) {
16256                 this.move("next", ".ui-menu-item:first", event);
16257         },
16258
16259         previous: function(event) {
16260                 this.move("prev", ".ui-menu-item:last", event);
16261         },
16262
16263         first: function() {
16264                 return this.active && !this.active.prevAll(".ui-menu-item").length;
16265         },
16266
16267         last: function() {
16268                 return this.active && !this.active.nextAll(".ui-menu-item").length;
16269         },
16270
16271         move: function(direction, edge, event) {
16272                 if (!this.active) {
16273                         this.activate(event, this.element.children(edge));
16274                         return;
16275                 }
16276                 var next = this.active[direction + "All"](".ui-menu-item").eq(0);
16277                 if (next.length) {
16278                         this.activate(event, next);
16279                 } else {
16280                         this.activate(event, this.element.children(edge));
16281                 }
16282         },
16283
16284         // TODO merge with previousPage
16285         nextPage: function(event) {
16286                 if (this.hasScroll()) {
16287                         // TODO merge with no-scroll-else
16288                         if (!this.active || this.last()) {
16289                                 this.activate(event, this.element.children(".ui-menu-item:first"));
16290                                 return;
16291                         }
16292                         var base = this.active.offset().top,
16293                                 height = this.element.height(),
16294                                 result = this.element.children(".ui-menu-item").filter(function() {
16295                                         var close = $(this).offset().top - base - height + $(this).height();
16296                                         // TODO improve approximation
16297                                         return close < 10 && close > -10;
16298                                 });
16299
16300                         // TODO try to catch this earlier when scrollTop indicates the last page anyway
16301                         if (!result.length) {
16302                                 result = this.element.children(".ui-menu-item:last");
16303                         }
16304                         this.activate(event, result);
16305                 } else {
16306                         this.activate(event, this.element.children(".ui-menu-item")
16307                                 .filter(!this.active || this.last() ? ":first" : ":last"));
16308                 }
16309         },
16310
16311         // TODO merge with nextPage
16312         previousPage: function(event) {
16313                 if (this.hasScroll()) {
16314                         // TODO merge with no-scroll-else
16315                         if (!this.active || this.first()) {
16316                                 this.activate(event, this.element.children(".ui-menu-item:last"));
16317                                 return;
16318                         }
16319
16320                         var base = this.active.offset().top,
16321                                 height = this.element.height();
16322                                 result = this.element.children(".ui-menu-item").filter(function() {
16323                                         var close = $(this).offset().top - base + height - $(this).height();
16324                                         // TODO improve approximation
16325                                         return close < 10 && close > -10;
16326                                 });
16327
16328                         // TODO try to catch this earlier when scrollTop indicates the last page anyway
16329                         if (!result.length) {
16330                                 result = this.element.children(".ui-menu-item:first");
16331                         }
16332                         this.activate(event, result);
16333                 } else {
16334                         this.activate(event, this.element.children(".ui-menu-item")
16335                                 .filter(!this.active || this.first() ? ":last" : ":first"));
16336                 }
16337         },
16338
16339         hasScroll: function() {
16340                 return this.element.height() < this.element.attr("scrollHeight");
16341         },
16342
16343         select: function( event ) {
16344                 this._trigger("selected", event, { item: this.active });
16345         }
16346 });
16347
16348 }(jQuery));
16349 /*
16350  * jQuery UI Button 1.8.12
16351  *
16352  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
16353  * Dual licensed under the MIT or GPL Version 2 licenses.
16354  * http://jquery.org/license
16355  *
16356  * http://docs.jquery.com/UI/Button
16357  *
16358  * Depends:
16359  *      jquery.ui.core.js
16360  *      jquery.ui.widget.js
16361  */
16362 (function( $, undefined ) {
16363
16364 var lastActive,
16365         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
16366         stateClasses = "ui-state-hover ui-state-active ",
16367         typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
16368         formResetHandler = function( event ) {
16369                 $( ":ui-button", event.target.form ).each(function() {
16370                         var inst = $( this ).data( "button" );
16371                         setTimeout(function() {
16372                                 inst.refresh();
16373                         }, 1 );
16374                 });
16375         },
16376         radioGroup = function( radio ) {
16377                 var name = radio.name,
16378                         form = radio.form,
16379                         radios = $( [] );
16380                 if ( name ) {
16381                         if ( form ) {
16382                                 radios = $( form ).find( "[name='" + name + "']" );
16383                         } else {
16384                                 radios = $( "[name='" + name + "']", radio.ownerDocument )
16385                                         .filter(function() {
16386                                                 return !this.form;
16387                                         });
16388                         }
16389                 }
16390                 return radios;
16391         };
16392
16393 $.widget( "ui.button", {
16394         options: {
16395                 disabled: null,
16396                 text: true,
16397                 label: null,
16398                 icons: {
16399                         primary: null,
16400                         secondary: null
16401                 }
16402         },
16403         _create: function() {
16404                 this.element.closest( "form" )
16405                         .unbind( "reset.button" )
16406                         .bind( "reset.button", formResetHandler );
16407
16408                 if ( typeof this.options.disabled !== "boolean" ) {
16409                         this.options.disabled = this.element.attr( "disabled" );
16410                 }
16411
16412                 this._determineButtonType();
16413                 this.hasTitle = !!this.buttonElement.attr( "title" );
16414
16415                 var self = this,
16416                         options = this.options,
16417                         toggleButton = this.type === "checkbox" || this.type === "radio",
16418                         hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
16419                         focusClass = "ui-state-focus";
16420
16421                 if ( options.label === null ) {
16422                         options.label = this.buttonElement.html();
16423                 }
16424
16425                 if ( this.element.is( ":disabled" ) ) {
16426                         options.disabled = true;
16427                 }
16428
16429                 this.buttonElement
16430                         .addClass( baseClasses )
16431                         .attr( "role", "button" )
16432                         .bind( "mouseenter.button", function() {
16433                                 if ( options.disabled ) {
16434                                         return;
16435                                 }
16436                                 $( this ).addClass( "ui-state-hover" );
16437                                 if ( this === lastActive ) {
16438                                         $( this ).addClass( "ui-state-active" );
16439                                 }
16440                         })
16441                         .bind( "mouseleave.button", function() {
16442                                 if ( options.disabled ) {
16443                                         return;
16444                                 }
16445                                 $( this ).removeClass( hoverClass );
16446                         })
16447                         .bind( "focus.button", function() {
16448                                 // no need to check disabled, focus won't be triggered anyway
16449                                 $( this ).addClass( focusClass );
16450                         })
16451                         .bind( "blur.button", function() {
16452                                 $( this ).removeClass( focusClass );
16453                         });
16454
16455                 if ( toggleButton ) {
16456                         this.element.bind( "change.button", function() {
16457                                 self.refresh();
16458                         });
16459                 }
16460
16461                 if ( this.type === "checkbox" ) {
16462                         this.buttonElement.bind( "click.button", function() {
16463                                 if ( options.disabled ) {
16464                                         return false;
16465                                 }
16466                                 $( this ).toggleClass( "ui-state-active" );
16467                                 self.buttonElement.attr( "aria-pressed", self.element[0].checked );
16468                         });
16469                 } else if ( this.type === "radio" ) {
16470                         this.buttonElement.bind( "click.button", function() {
16471                                 if ( options.disabled ) {
16472                                         return false;
16473                                 }
16474                                 $( this ).addClass( "ui-state-active" );
16475                                 self.buttonElement.attr( "aria-pressed", true );
16476
16477                                 var radio = self.element[ 0 ];
16478                                 radioGroup( radio )
16479                                         .not( radio )
16480                                         .map(function() {
16481                                                 return $( this ).button( "widget" )[ 0 ];
16482                                         })
16483                                         .removeClass( "ui-state-active" )
16484                                         .attr( "aria-pressed", false );
16485                         });
16486                 } else {
16487                         this.buttonElement
16488                                 .bind( "mousedown.button", function() {
16489                                         if ( options.disabled ) {
16490                                                 return false;
16491                                         }
16492                                         $( this ).addClass( "ui-state-active" );
16493                                         lastActive = this;
16494                                         $( document ).one( "mouseup", function() {
16495                                                 lastActive = null;
16496                                         });
16497                                 })
16498                                 .bind( "mouseup.button", function() {
16499                                         if ( options.disabled ) {
16500                                                 return false;
16501                                         }
16502                                         $( this ).removeClass( "ui-state-active" );
16503                                 })
16504                                 .bind( "keydown.button", function(event) {
16505                                         if ( options.disabled ) {
16506                                                 return false;
16507                                         }
16508                                         if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
16509                                                 $( this ).addClass( "ui-state-active" );
16510                                         }
16511                                 })
16512                                 .bind( "keyup.button", function() {
16513                                         $( this ).removeClass( "ui-state-active" );
16514                                 });
16515
16516                         if ( this.buttonElement.is("a") ) {
16517                                 this.buttonElement.keyup(function(event) {
16518                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
16519                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
16520                                                 $( this ).click();
16521                                         }
16522                                 });
16523                         }
16524                 }
16525
16526                 // TODO: pull out $.Widget's handling for the disabled option into
16527                 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
16528                 // be overridden by individual plugins
16529                 this._setOption( "disabled", options.disabled );
16530         },
16531
16532         _determineButtonType: function() {
16533
16534                 if ( this.element.is(":checkbox") ) {
16535                         this.type = "checkbox";
16536                 } else if ( this.element.is(":radio") ) {
16537                         this.type = "radio";
16538                 } else if ( this.element.is("input") ) {
16539                         this.type = "input";
16540                 } else {
16541                         this.type = "button";
16542                 }
16543
16544                 if ( this.type === "checkbox" || this.type === "radio" ) {
16545                         // we don't search against the document in case the element
16546                         // is disconnected from the DOM
16547                         var ancestor = this.element.parents().filter(":last"),
16548                                 labelSelector = "label[for=" + this.element.attr("id") + "]";
16549                         this.buttonElement = ancestor.find( labelSelector );
16550                         if ( !this.buttonElement.length ) {
16551                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
16552                                 this.buttonElement = ancestor.filter( labelSelector );
16553                                 if ( !this.buttonElement.length ) {
16554                                         this.buttonElement = ancestor.find( labelSelector );
16555                                 }
16556                         }
16557                         this.element.addClass( "ui-helper-hidden-accessible" );
16558
16559                         var checked = this.element.is( ":checked" );
16560                         if ( checked ) {
16561                                 this.buttonElement.addClass( "ui-state-active" );
16562                         }
16563                         this.buttonElement.attr( "aria-pressed", checked );
16564                 } else {
16565                         this.buttonElement = this.element;
16566                 }
16567         },
16568
16569         widget: function() {
16570                 return this.buttonElement;
16571         },
16572
16573         destroy: function() {
16574                 this.element
16575                         .removeClass( "ui-helper-hidden-accessible" );
16576                 this.buttonElement
16577                         .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
16578                         .removeAttr( "role" )
16579                         .removeAttr( "aria-pressed" )
16580                         .html( this.buttonElement.find(".ui-button-text").html() );
16581
16582                 if ( !this.hasTitle ) {
16583                         this.buttonElement.removeAttr( "title" );
16584                 }
16585
16586                 $.Widget.prototype.destroy.call( this );
16587         },
16588
16589         _setOption: function( key, value ) {
16590                 $.Widget.prototype._setOption.apply( this, arguments );
16591                 if ( key === "disabled" ) {
16592                         if ( value ) {
16593                                 this.element.attr( "disabled", true );
16594                         } else {
16595                                 this.element.removeAttr( "disabled" );
16596                         }
16597                 }
16598                 this._resetButton();
16599         },
16600
16601         refresh: function() {
16602                 var isDisabled = this.element.is( ":disabled" );
16603                 if ( isDisabled !== this.options.disabled ) {
16604                         this._setOption( "disabled", isDisabled );
16605                 }
16606                 if ( this.type === "radio" ) {
16607                         radioGroup( this.element[0] ).each(function() {
16608                                 if ( $( this ).is( ":checked" ) ) {
16609                                         $( this ).button( "widget" )
16610                                                 .addClass( "ui-state-active" )
16611                                                 .attr( "aria-pressed", true );
16612                                 } else {
16613                                         $( this ).button( "widget" )
16614                                                 .removeClass( "ui-state-active" )
16615                                                 .attr( "aria-pressed", false );
16616                                 }
16617                         });
16618                 } else if ( this.type === "checkbox" ) {
16619                         if ( this.element.is( ":checked" ) ) {
16620                                 this.buttonElement
16621                                         .addClass( "ui-state-active" )
16622                                         .attr( "aria-pressed", true );
16623                         } else {
16624                                 this.buttonElement
16625                                         .removeClass( "ui-state-active" )
16626                                         .attr( "aria-pressed", false );
16627                         }
16628                 }
16629         },
16630
16631         _resetButton: function() {
16632                 if ( this.type === "input" ) {
16633                         if ( this.options.label ) {
16634                                 this.element.val( this.options.label );
16635                         }
16636                         return;
16637                 }
16638                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
16639                         buttonText = $( "<span></span>" )
16640                                 .addClass( "ui-button-text" )
16641                                 .html( this.options.label )
16642                                 .appendTo( buttonElement.empty() )
16643                                 .text(),
16644                         icons = this.options.icons,
16645                         multipleIcons = icons.primary && icons.secondary,
16646                         buttonClasses = [];  
16647
16648                 if ( icons.primary || icons.secondary ) {
16649                         if ( this.options.text ) {
16650                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
16651                         }
16652
16653                         if ( icons.primary ) {
16654                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
16655                         }
16656
16657                         if ( icons.secondary ) {
16658                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
16659                         }
16660
16661                         if ( !this.options.text ) {
16662                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
16663
16664                                 if ( !this.hasTitle ) {
16665                                         buttonElement.attr( "title", buttonText );
16666                                 }
16667                         }
16668                 } else {
16669                         buttonClasses.push( "ui-button-text-only" );
16670                 }
16671                 buttonElement.addClass( buttonClasses.join( " " ) );
16672         }
16673 });
16674
16675 $.widget( "ui.buttonset", {
16676         options: {
16677                 items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
16678         },
16679
16680         _create: function() {
16681                 this.element.addClass( "ui-buttonset" );
16682         },
16683         
16684         _init: function() {
16685                 this.refresh();
16686         },
16687
16688         _setOption: function( key, value ) {
16689                 if ( key === "disabled" ) {
16690                         this.buttons.button( "option", key, value );
16691                 }
16692
16693                 $.Widget.prototype._setOption.apply( this, arguments );
16694         },
16695         
16696         refresh: function() {
16697                 this.buttons = this.element.find( this.options.items )
16698                         .filter( ":ui-button" )
16699                                 .button( "refresh" )
16700                         .end()
16701                         .not( ":ui-button" )
16702                                 .button()
16703                         .end()
16704                         .map(function() {
16705                                 return $( this ).button( "widget" )[ 0 ];
16706                         })
16707                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
16708                                 .filter( ":first" )
16709                                         .addClass( "ui-corner-left" )
16710                                 .end()
16711                                 .filter( ":last" )
16712                                         .addClass( "ui-corner-right" )
16713                                 .end()
16714                         .end();
16715         },
16716
16717         destroy: function() {
16718                 this.element.removeClass( "ui-buttonset" );
16719                 this.buttons
16720                         .map(function() {
16721                                 return $( this ).button( "widget" )[ 0 ];
16722                         })
16723                                 .removeClass( "ui-corner-left ui-corner-right" )
16724                         .end()
16725                         .button( "destroy" );
16726
16727                 $.Widget.prototype.destroy.call( this );
16728         }
16729 });
16730
16731 }( jQuery ) );
16732 /*
16733  * jQuery UI Datepicker 1.8.12
16734  *
16735  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
16736  * Dual licensed under the MIT or GPL Version 2 licenses.
16737  * http://jquery.org/license
16738  *
16739  * http://docs.jquery.com/UI/Datepicker
16740  *
16741  * Depends:
16742  *      jquery.ui.core.js
16743  */
16744 (function( $, undefined ) {
16745
16746 $.extend($.ui, { datepicker: { version: "1.8.12" } });
16747
16748 var PROP_NAME = 'datepicker';
16749 var dpuuid = new Date().getTime();
16750
16751 /* Date picker manager.
16752    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
16753    Settings for (groups of) date pickers are maintained in an instance object,
16754    allowing multiple different settings on the same page. */
16755
16756 function Datepicker() {
16757         this.debug = false; // Change this to true to start debugging
16758         this._curInst = null; // The current instance in use
16759         this._keyEvent = false; // If the last event was a key event
16760         this._disabledInputs = []; // List of date picker inputs that have been disabled
16761         this._datepickerShowing = false; // True if the popup picker is showing , false if not
16762         this._inDialog = false; // True if showing within a "dialog", false if not
16763         this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
16764         this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
16765         this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
16766         this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
16767         this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
16768         this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
16769         this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
16770         this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
16771         this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
16772         this.regional = []; // Available regional settings, indexed by language code
16773         this.regional[''] = { // Default regional settings
16774                 closeText: 'Done', // Display text for close link
16775                 prevText: 'Prev', // Display text for previous month link
16776                 nextText: 'Next', // Display text for next month link
16777                 currentText: 'Today', // Display text for current month link
16778                 monthNames: ['January','February','March','April','May','June',
16779                         'July','August','September','October','November','December'], // Names of months for drop-down and formatting
16780                 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
16781                 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
16782                 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
16783                 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
16784                 weekHeader: 'Wk', // Column header for week of the year
16785                 dateFormat: 'mm/dd/yy', // See format options on parseDate
16786                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
16787                 isRTL: false, // True if right-to-left language, false if left-to-right
16788                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
16789                 yearSuffix: '' // Additional text to append to the year in the month headers
16790         };
16791         this._defaults = { // Global defaults for all the date picker instances
16792                 showOn: 'focus', // 'focus' for popup on focus,
16793                         // 'button' for trigger button, or 'both' for either
16794                 showAnim: 'fadeIn', // Name of jQuery animation for popup
16795                 showOptions: {}, // Options for enhanced animations
16796                 defaultDate: null, // Used when field is blank: actual date,
16797                         // +/-number for offset from today, null for today
16798                 appendText: '', // Display text following the input box, e.g. showing the format
16799                 buttonText: '...', // Text for trigger button
16800                 buttonImage: '', // URL for trigger button image
16801                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
16802                 hideIfNoPrevNext: false, // True to hide next/previous month links
16803                         // if not applicable, false to just disable them
16804                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
16805                 gotoCurrent: false, // True if today link goes back to current selection instead
16806                 changeMonth: false, // True if month can be selected directly, false if only prev/next
16807                 changeYear: false, // True if year can be selected directly, false if only prev/next
16808                 yearRange: 'c-10:c+10', // Range of years to display in drop-down,
16809                         // either relative to today's year (-nn:+nn), relative to currently displayed year
16810                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
16811                 showOtherMonths: false, // True to show dates in other months, false to leave blank
16812                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
16813                 showWeek: false, // True to show week of the year, false to not show it
16814                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
16815                         // takes a Date and returns the number of the week for it
16816                 shortYearCutoff: '+10', // Short year values < this are in the current century,
16817                         // > this are in the previous century,
16818                         // string value starting with '+' for current year + value
16819                 minDate: null, // The earliest selectable date, or null for no limit
16820                 maxDate: null, // The latest selectable date, or null for no limit
16821                 duration: 'fast', // Duration of display/closure
16822                 beforeShowDay: null, // Function that takes a date and returns an array with
16823                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
16824                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
16825                 beforeShow: null, // Function that takes an input field and
16826                         // returns a set of custom settings for the date picker
16827                 onSelect: null, // Define a callback function when a date is selected
16828                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
16829                 onClose: null, // Define a callback function when the datepicker is closed
16830                 numberOfMonths: 1, // Number of months to show at a time
16831                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
16832                 stepMonths: 1, // Number of months to step back/forward
16833                 stepBigMonths: 12, // Number of months to step back/forward for the big links
16834                 altField: '', // Selector for an alternate field to store selected dates into
16835                 altFormat: '', // The date format to use for the alternate field
16836                 constrainInput: true, // The input is constrained by the current date format
16837                 showButtonPanel: false, // True to show button panel, false to not show it
16838                 autoSize: false // True to size the input for the date format, false to leave as is
16839         };
16840         $.extend(this._defaults, this.regional['']);
16841         this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>');
16842 }
16843
16844 $.extend(Datepicker.prototype, {
16845         /* Class name added to elements to indicate already configured with a date picker. */
16846         markerClassName: 'hasDatepicker',
16847
16848         /* Debug logging (if enabled). */
16849         log: function () {
16850                 if (this.debug)
16851                         console.log.apply('', arguments);
16852         },
16853         
16854         // TODO rename to "widget" when switching to widget factory
16855         _widgetDatepicker: function() {
16856                 return this.dpDiv;
16857         },
16858
16859         /* Override the default settings for all instances of the date picker.
16860            @param  settings  object - the new settings to use as defaults (anonymous object)
16861            @return the manager object */
16862         setDefaults: function(settings) {
16863                 extendRemove(this._defaults, settings || {});
16864                 return this;
16865         },
16866
16867         /* Attach the date picker to a jQuery selection.
16868            @param  target    element - the target input field or division or span
16869            @param  settings  object - the new settings to use for this date picker instance (anonymous) */
16870         _attachDatepicker: function(target, settings) {
16871                 // check for settings on the control itself - in namespace 'date:'
16872                 var inlineSettings = null;
16873                 for (var attrName in this._defaults) {
16874                         var attrValue = target.getAttribute('date:' + attrName);
16875                         if (attrValue) {
16876                                 inlineSettings = inlineSettings || {};
16877                                 try {
16878                                         inlineSettings[attrName] = eval(attrValue);
16879                                 } catch (err) {
16880                                         inlineSettings[attrName] = attrValue;
16881                                 }
16882                         }
16883                 }
16884                 var nodeName = target.nodeName.toLowerCase();
16885                 var inline = (nodeName == 'div' || nodeName == 'span');
16886                 if (!target.id) {
16887                         this.uuid += 1;
16888                         target.id = 'dp' + this.uuid;
16889                 }
16890                 var inst = this._newInst($(target), inline);
16891                 inst.settings = $.extend({}, settings || {}, inlineSettings || {});
16892                 if (nodeName == 'input') {
16893                         this._connectDatepicker(target, inst);
16894                 } else if (inline) {
16895                         this._inlineDatepicker(target, inst);
16896                 }
16897         },
16898
16899         /* Create a new instance object. */
16900         _newInst: function(target, inline) {
16901                 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
16902                 return {id: id, input: target, // associated target
16903                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
16904                         drawMonth: 0, drawYear: 0, // month being drawn
16905                         inline: inline, // is datepicker inline or not
16906                         dpDiv: (!inline ? this.dpDiv : // presentation div
16907                         $('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))};
16908         },
16909
16910         /* Attach the date picker to an input field. */
16911         _connectDatepicker: function(target, inst) {
16912                 var input = $(target);
16913                 inst.append = $([]);
16914                 inst.trigger = $([]);
16915                 if (input.hasClass(this.markerClassName))
16916                         return;
16917                 this._attachments(input, inst);
16918                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
16919                         keypress(this._doKeyPress).keyup(this._doKeyUp).
16920                         bind("setData.datepicker", function(event, key, value) {
16921                                 inst.settings[key] = value;
16922                         }).bind("getData.datepicker", function(event, key) {
16923                                 return this._get(inst, key);
16924                         });
16925                 this._autoSize(inst);
16926                 $.data(target, PROP_NAME, inst);
16927         },
16928
16929         /* Make attachments based on settings. */
16930         _attachments: function(input, inst) {
16931                 var appendText = this._get(inst, 'appendText');
16932                 var isRTL = this._get(inst, 'isRTL');
16933                 if (inst.append)
16934                         inst.append.remove();
16935                 if (appendText) {
16936                         inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
16937                         input[isRTL ? 'before' : 'after'](inst.append);
16938                 }
16939                 input.unbind('focus', this._showDatepicker);
16940                 if (inst.trigger)
16941                         inst.trigger.remove();
16942                 var showOn = this._get(inst, 'showOn');
16943                 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
16944                         input.focus(this._showDatepicker);
16945                 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
16946                         var buttonText = this._get(inst, 'buttonText');
16947                         var buttonImage = this._get(inst, 'buttonImage');
16948                         inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
16949                                 $('<img/>').addClass(this._triggerClass).
16950                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
16951                                 $('<button type="button"></button>').addClass(this._triggerClass).
16952                                         html(buttonImage == '' ? buttonText : $('<img/>').attr(
16953                                         { src:buttonImage, alt:buttonText, title:buttonText })));
16954                         input[isRTL ? 'before' : 'after'](inst.trigger);
16955                         inst.trigger.click(function() {
16956                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
16957                                         $.datepicker._hideDatepicker();
16958                                 else
16959                                         $.datepicker._showDatepicker(input[0]);
16960                                 return false;
16961                         });
16962                 }
16963         },
16964
16965         /* Apply the maximum length for the date format. */
16966         _autoSize: function(inst) {
16967                 if (this._get(inst, 'autoSize') && !inst.inline) {
16968                         var date = new Date(2009, 12 - 1, 20); // Ensure double digits
16969                         var dateFormat = this._get(inst, 'dateFormat');
16970                         if (dateFormat.match(/[DM]/)) {
16971                                 var findMax = function(names) {
16972                                         var max = 0;
16973                                         var maxI = 0;
16974                                         for (var i = 0; i < names.length; i++) {
16975                                                 if (names[i].length > max) {
16976                                                         max = names[i].length;
16977                                                         maxI = i;
16978                                                 }
16979                                         }
16980                                         return maxI;
16981                                 };
16982                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
16983                                         'monthNames' : 'monthNamesShort'))));
16984                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
16985                                         'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
16986                         }
16987                         inst.input.attr('size', this._formatDate(inst, date).length);
16988                 }
16989         },
16990
16991         /* Attach an inline date picker to a div. */
16992         _inlineDatepicker: function(target, inst) {
16993                 var divSpan = $(target);
16994                 if (divSpan.hasClass(this.markerClassName))
16995                         return;
16996                 divSpan.addClass(this.markerClassName).append(inst.dpDiv).
16997                         bind("setData.datepicker", function(event, key, value){
16998                                 inst.settings[key] = value;
16999                         }).bind("getData.datepicker", function(event, key){
17000                                 return this._get(inst, key);
17001                         });
17002                 $.data(target, PROP_NAME, inst);
17003                 this._setDate(inst, this._getDefaultDate(inst), true);
17004                 this._updateDatepicker(inst);
17005                 this._updateAlternate(inst);
17006                 inst.dpDiv.show();
17007         },
17008
17009         /* Pop-up the date picker in a "dialog" box.
17010            @param  input     element - ignored
17011            @param  date      string or Date - the initial date to display
17012            @param  onSelect  function - the function to call when a date is selected
17013            @param  settings  object - update the dialog date picker instance's settings (anonymous object)
17014            @param  pos       int[2] - coordinates for the dialog's position within the screen or
17015                              event - with x/y coordinates or
17016                              leave empty for default (screen centre)
17017            @return the manager object */
17018         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
17019                 var inst = this._dialogInst; // internal instance
17020                 if (!inst) {
17021                         this.uuid += 1;
17022                         var id = 'dp' + this.uuid;
17023                         this._dialogInput = $('<input type="text" id="' + id +
17024                                 '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
17025                         this._dialogInput.keydown(this._doKeyDown);
17026                         $('body').append(this._dialogInput);
17027                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
17028                         inst.settings = {};
17029                         $.data(this._dialogInput[0], PROP_NAME, inst);
17030                 }
17031                 extendRemove(inst.settings, settings || {});
17032                 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
17033                 this._dialogInput.val(date);
17034
17035                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
17036                 if (!this._pos) {
17037                         var browserWidth = document.documentElement.clientWidth;
17038                         var browserHeight = document.documentElement.clientHeight;
17039                         var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
17040                         var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
17041                         this._pos = // should use actual width/height below
17042                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
17043                 }
17044
17045                 // move input on screen for focus, but hidden behind dialog
17046                 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
17047                 inst.settings.onSelect = onSelect;
17048                 this._inDialog = true;
17049                 this.dpDiv.addClass(this._dialogClass);
17050                 this._showDatepicker(this._dialogInput[0]);
17051                 if ($.blockUI)
17052                         $.blockUI(this.dpDiv);
17053                 $.data(this._dialogInput[0], PROP_NAME, inst);
17054                 return this;
17055         },
17056
17057         /* Detach a datepicker from its control.
17058            @param  target    element - the target input field or division or span */
17059         _destroyDatepicker: function(target) {
17060                 var $target = $(target);
17061                 var inst = $.data(target, PROP_NAME);
17062                 if (!$target.hasClass(this.markerClassName)) {
17063                         return;
17064                 }
17065                 var nodeName = target.nodeName.toLowerCase();
17066                 $.removeData(target, PROP_NAME);
17067                 if (nodeName == 'input') {
17068                         inst.append.remove();
17069                         inst.trigger.remove();
17070                         $target.removeClass(this.markerClassName).
17071                                 unbind('focus', this._showDatepicker).
17072                                 unbind('keydown', this._doKeyDown).
17073                                 unbind('keypress', this._doKeyPress).
17074                                 unbind('keyup', this._doKeyUp);
17075                 } else if (nodeName == 'div' || nodeName == 'span')
17076                         $target.removeClass(this.markerClassName).empty();
17077         },
17078
17079         /* Enable the date picker to a jQuery selection.
17080            @param  target    element - the target input field or division or span */
17081         _enableDatepicker: function(target) {
17082                 var $target = $(target);
17083                 var inst = $.data(target, PROP_NAME);
17084                 if (!$target.hasClass(this.markerClassName)) {
17085                         return;
17086                 }
17087                 var nodeName = target.nodeName.toLowerCase();
17088                 if (nodeName == 'input') {
17089                         target.disabled = false;
17090                         inst.trigger.filter('button').
17091                                 each(function() { this.disabled = false; }).end().
17092                                 filter('img').css({opacity: '1.0', cursor: ''});
17093                 }
17094                 else if (nodeName == 'div' || nodeName == 'span') {
17095                         var inline = $target.children('.' + this._inlineClass);
17096                         inline.children().removeClass('ui-state-disabled');
17097                 }
17098                 this._disabledInputs = $.map(this._disabledInputs,
17099                         function(value) { return (value == target ? null : value); }); // delete entry
17100         },
17101
17102         /* Disable the date picker to a jQuery selection.
17103            @param  target    element - the target input field or division or span */
17104         _disableDatepicker: function(target) {
17105                 var $target = $(target);
17106                 var inst = $.data(target, PROP_NAME);
17107                 if (!$target.hasClass(this.markerClassName)) {
17108                         return;
17109                 }
17110                 var nodeName = target.nodeName.toLowerCase();
17111                 if (nodeName == 'input') {
17112                         target.disabled = true;
17113                         inst.trigger.filter('button').
17114                                 each(function() { this.disabled = true; }).end().
17115                                 filter('img').css({opacity: '0.5', cursor: 'default'});
17116                 }
17117                 else if (nodeName == 'div' || nodeName == 'span') {
17118                         var inline = $target.children('.' + this._inlineClass);
17119                         inline.children().addClass('ui-state-disabled');
17120                 }
17121                 this._disabledInputs = $.map(this._disabledInputs,
17122                         function(value) { return (value == target ? null : value); }); // delete entry
17123                 this._disabledInputs[this._disabledInputs.length] = target;
17124         },
17125
17126         /* Is the first field in a jQuery collection disabled as a datepicker?
17127            @param  target    element - the target input field or division or span
17128            @return boolean - true if disabled, false if enabled */
17129         _isDisabledDatepicker: function(target) {
17130                 if (!target) {
17131                         return false;
17132                 }
17133                 for (var i = 0; i < this._disabledInputs.length; i++) {
17134                         if (this._disabledInputs[i] == target)
17135                                 return true;
17136                 }
17137                 return false;
17138         },
17139
17140         /* Retrieve the instance data for the target control.
17141            @param  target  element - the target input field or division or span
17142            @return  object - the associated instance data
17143            @throws  error if a jQuery problem getting data */
17144         _getInst: function(target) {
17145                 try {
17146                         return $.data(target, PROP_NAME);
17147                 }
17148                 catch (err) {
17149                         throw 'Missing instance data for this datepicker';
17150                 }
17151         },
17152
17153         /* Update or retrieve the settings for a date picker attached to an input field or division.
17154            @param  target  element - the target input field or division or span
17155            @param  name    object - the new settings to update or
17156                            string - the name of the setting to change or retrieve,
17157                            when retrieving also 'all' for all instance settings or
17158                            'defaults' for all global defaults
17159            @param  value   any - the new value for the setting
17160                            (omit if above is an object or to retrieve a value) */
17161         _optionDatepicker: function(target, name, value) {
17162                 var inst = this._getInst(target);
17163                 if (arguments.length == 2 && typeof name == 'string') {
17164                         return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
17165                                 (inst ? (name == 'all' ? $.extend({}, inst.settings) :
17166                                 this._get(inst, name)) : null));
17167                 }
17168                 var settings = name || {};
17169                 if (typeof name == 'string') {
17170                         settings = {};
17171                         settings[name] = value;
17172                 }
17173                 if (inst) {
17174                         if (this._curInst == inst) {
17175                                 this._hideDatepicker();
17176                         }
17177                         var date = this._getDateDatepicker(target, true);
17178                         var minDate = this._getMinMaxDate(inst, 'min');
17179                         var maxDate = this._getMinMaxDate(inst, 'max');
17180                         extendRemove(inst.settings, settings);
17181                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
17182                         if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
17183                                 inst.settings.minDate = this._formatDate(inst, minDate);
17184                         if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
17185                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
17186                         this._attachments($(target), inst);
17187                         this._autoSize(inst);
17188                         this._setDateDatepicker(target, date);
17189                         this._updateDatepicker(inst);
17190                 }
17191         },
17192
17193         // change method deprecated
17194         _changeDatepicker: function(target, name, value) {
17195                 this._optionDatepicker(target, name, value);
17196         },
17197
17198         /* Redraw the date picker attached to an input field or division.
17199            @param  target  element - the target input field or division or span */
17200         _refreshDatepicker: function(target) {
17201                 var inst = this._getInst(target);
17202                 if (inst) {
17203                         this._updateDatepicker(inst);
17204                 }
17205         },
17206
17207         /* Set the dates for a jQuery selection.
17208            @param  target   element - the target input field or division or span
17209            @param  date     Date - the new date */
17210         _setDateDatepicker: function(target, date) {
17211                 var inst = this._getInst(target);
17212                 if (inst) {
17213                         this._setDate(inst, date);
17214                         this._updateDatepicker(inst);
17215                         this._updateAlternate(inst);
17216                 }
17217         },
17218
17219         /* Get the date(s) for the first entry in a jQuery selection.
17220            @param  target     element - the target input field or division or span
17221            @param  noDefault  boolean - true if no default date is to be used
17222            @return Date - the current date */
17223         _getDateDatepicker: function(target, noDefault) {
17224                 var inst = this._getInst(target);
17225                 if (inst && !inst.inline)
17226                         this._setDateFromField(inst, noDefault);
17227                 return (inst ? this._getDate(inst) : null);
17228         },
17229
17230         /* Handle keystrokes. */
17231         _doKeyDown: function(event) {
17232                 var inst = $.datepicker._getInst(event.target);
17233                 var handled = true;
17234                 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
17235                 inst._keyEvent = true;
17236                 if ($.datepicker._datepickerShowing)
17237                         switch (event.keyCode) {
17238                                 case 9: $.datepicker._hideDatepicker();
17239                                                 handled = false;
17240                                                 break; // hide on tab out
17241                                 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 
17242                                                                         $.datepicker._currentClass + ')', inst.dpDiv);
17243                                                 if (sel[0])
17244                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
17245                                                 else
17246                                                         $.datepicker._hideDatepicker();
17247                                                 return false; // don't submit the form
17248                                                 break; // select the value on enter
17249                                 case 27: $.datepicker._hideDatepicker();
17250                                                 break; // hide on escape
17251                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
17252                                                         -$.datepicker._get(inst, 'stepBigMonths') :
17253                                                         -$.datepicker._get(inst, 'stepMonths')), 'M');
17254                                                 break; // previous month/year on page up/+ ctrl
17255                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
17256                                                         +$.datepicker._get(inst, 'stepBigMonths') :
17257                                                         +$.datepicker._get(inst, 'stepMonths')), 'M');
17258                                                 break; // next month/year on page down/+ ctrl
17259                                 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
17260                                                 handled = event.ctrlKey || event.metaKey;
17261                                                 break; // clear on ctrl or command +end
17262                                 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
17263                                                 handled = event.ctrlKey || event.metaKey;
17264                                                 break; // current on ctrl or command +home
17265                                 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
17266                                                 handled = event.ctrlKey || event.metaKey;
17267                                                 // -1 day on ctrl or command +left
17268                                                 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
17269                                                                         -$.datepicker._get(inst, 'stepBigMonths') :
17270                                                                         -$.datepicker._get(inst, 'stepMonths')), 'M');
17271                                                 // next month/year on alt +left on Mac
17272                                                 break;
17273                                 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
17274                                                 handled = event.ctrlKey || event.metaKey;
17275                                                 break; // -1 week on ctrl or command +up
17276                                 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
17277                                                 handled = event.ctrlKey || event.metaKey;
17278                                                 // +1 day on ctrl or command +right
17279                                                 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
17280                                                                         +$.datepicker._get(inst, 'stepBigMonths') :
17281                                                                         +$.datepicker._get(inst, 'stepMonths')), 'M');
17282                                                 // next month/year on alt +right
17283                                                 break;
17284                                 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
17285                                                 handled = event.ctrlKey || event.metaKey;
17286                                                 break; // +1 week on ctrl or command +down
17287                                 default: handled = false;
17288                         }
17289                 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
17290                         $.datepicker._showDatepicker(this);
17291                 else {
17292                         handled = false;
17293                 }
17294                 if (handled) {
17295                         event.preventDefault();
17296                         event.stopPropagation();
17297                 }
17298         },
17299
17300         /* Filter entered characters - based on date format. */
17301         _doKeyPress: function(event) {
17302                 var inst = $.datepicker._getInst(event.target);
17303                 if ($.datepicker._get(inst, 'constrainInput')) {
17304                         var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
17305                         var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
17306                         return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
17307                 }
17308         },
17309
17310         /* Synchronise manual entry and field/alternate field. */
17311         _doKeyUp: function(event) {
17312                 var inst = $.datepicker._getInst(event.target);
17313                 if (inst.input.val() != inst.lastVal) {
17314                         try {
17315                                 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
17316                                         (inst.input ? inst.input.val() : null),
17317                                         $.datepicker._getFormatConfig(inst));
17318                                 if (date) { // only if valid
17319                                         $.datepicker._setDateFromField(inst);
17320                                         $.datepicker._updateAlternate(inst);
17321                                         $.datepicker._updateDatepicker(inst);
17322                                 }
17323                         }
17324                         catch (event) {
17325                                 $.datepicker.log(event);
17326                         }
17327                 }
17328                 return true;
17329         },
17330
17331         /* Pop-up the date picker for a given input field.
17332            @param  input  element - the input field attached to the date picker or
17333                           event - if triggered by focus */
17334         _showDatepicker: function(input) {
17335                 input = input.target || input;
17336                 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
17337                         input = $('input', input.parentNode)[0];
17338                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
17339                         return;
17340                 var inst = $.datepicker._getInst(input);
17341                 if ($.datepicker._curInst && $.datepicker._curInst != inst) {
17342                         $.datepicker._curInst.dpDiv.stop(true, true);
17343                 }
17344                 var beforeShow = $.datepicker._get(inst, 'beforeShow');
17345                 extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
17346                 inst.lastVal = null;
17347                 $.datepicker._lastInput = input;
17348                 $.datepicker._setDateFromField(inst);
17349                 if ($.datepicker._inDialog) // hide cursor
17350                         input.value = '';
17351                 if (!$.datepicker._pos) { // position below input
17352                         $.datepicker._pos = $.datepicker._findPos(input);
17353                         $.datepicker._pos[1] += input.offsetHeight; // add the height
17354                 }
17355                 var isFixed = false;
17356                 $(input).parents().each(function() {
17357                         isFixed |= $(this).css('position') == 'fixed';
17358                         return !isFixed;
17359                 });
17360                 if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
17361                         $.datepicker._pos[0] -= document.documentElement.scrollLeft;
17362                         $.datepicker._pos[1] -= document.documentElement.scrollTop;
17363                 }
17364                 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
17365                 $.datepicker._pos = null;
17366                 //to avoid flashes on Firefox
17367                 inst.dpDiv.empty();
17368                 // determine sizing offscreen
17369                 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
17370                 $.datepicker._updateDatepicker(inst);
17371                 // fix width for dynamic number of date pickers
17372                 // and adjust position before showing
17373                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
17374                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
17375                         'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
17376                         left: offset.left + 'px', top: offset.top + 'px'});
17377                 if (!inst.inline) {
17378                         var showAnim = $.datepicker._get(inst, 'showAnim');
17379                         var duration = $.datepicker._get(inst, 'duration');
17380                         var postProcess = function() {
17381                                 $.datepicker._datepickerShowing = true;
17382                                 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
17383                                 if( !! cover.length ){
17384                                         var borders = $.datepicker._getBorders(inst.dpDiv);
17385                                         cover.css({left: -borders[0], top: -borders[1],
17386                                                 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
17387                                 }
17388                         };
17389                         inst.dpDiv.zIndex($(input).zIndex()+1);
17390                         if ($.effects && $.effects[showAnim])
17391                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
17392                         else
17393                                 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
17394                         if (!showAnim || !duration)
17395                                 postProcess();
17396                         if (inst.input.is(':visible') && !inst.input.is(':disabled'))
17397                                 inst.input.focus();
17398                         $.datepicker._curInst = inst;
17399                 }
17400         },
17401
17402         /* Generate the date picker content. */
17403         _updateDatepicker: function(inst) {
17404                 var self = this;
17405                 var borders = $.datepicker._getBorders(inst.dpDiv);
17406                 inst.dpDiv.empty().append(this._generateHTML(inst));
17407                 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
17408                 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
17409                         cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
17410                 }
17411                 inst.dpDiv.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')
17412                                 .bind('mouseout', function(){
17413                                         $(this).removeClass('ui-state-hover');
17414                                         if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
17415                                         if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
17416                                 })
17417                                 .bind('mouseover', function(){
17418                                         if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) {
17419                                                 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
17420                                                 $(this).addClass('ui-state-hover');
17421                                                 if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
17422                                                 if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
17423                                         }
17424                                 })
17425                         .end()
17426                         .find('.' + this._dayOverClass + ' a')
17427                                 .trigger('mouseover')
17428                         .end();
17429                 var numMonths = this._getNumberOfMonths(inst);
17430                 var cols = numMonths[1];
17431                 var width = 17;
17432                 if (cols > 1)
17433                         inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
17434                 else
17435                         inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
17436                 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
17437                         'Class']('ui-datepicker-multi');
17438                 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
17439                         'Class']('ui-datepicker-rtl');
17440                 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
17441                                 // #6694 - don't focus the input if it's already focused
17442                                 // this breaks the change event in IE
17443                                 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
17444                         inst.input.focus();
17445                 // deffered render of the years select (to avoid flashes on Firefox) 
17446                 if( inst.yearshtml ){
17447                         var origyearshtml = inst.yearshtml;
17448                         setTimeout(function(){
17449                                 //assure that inst.yearshtml didn't change.
17450                                 if( origyearshtml === inst.yearshtml ){
17451                                         inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
17452                                 }
17453                                 origyearshtml = inst.yearshtml = null;
17454                         }, 0);
17455                 }
17456         },
17457
17458         /* Retrieve the size of left and top borders for an element.
17459            @param  elem  (jQuery object) the element of interest
17460            @return  (number[2]) the left and top borders */
17461         _getBorders: function(elem) {
17462                 var convert = function(value) {
17463                         return {thin: 1, medium: 2, thick: 3}[value] || value;
17464                 };
17465                 return [parseFloat(convert(elem.css('border-left-width'))),
17466                         parseFloat(convert(elem.css('border-top-width')))];
17467         },
17468
17469         /* Check positioning to remain on screen. */
17470         _checkOffset: function(inst, offset, isFixed) {
17471                 var dpWidth = inst.dpDiv.outerWidth();
17472                 var dpHeight = inst.dpDiv.outerHeight();
17473                 var inputWidth = inst.input ? inst.input.outerWidth() : 0;
17474                 var inputHeight = inst.input ? inst.input.outerHeight() : 0;
17475                 var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
17476                 var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
17477
17478                 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
17479                 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
17480                 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
17481
17482                 // now check if datepicker is showing outside window viewport - move to a better place if so.
17483                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
17484                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
17485                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
17486                         Math.abs(dpHeight + inputHeight) : 0);
17487
17488                 return offset;
17489         },
17490
17491         /* Find an object's position on the screen. */
17492         _findPos: function(obj) {
17493                 var inst = this._getInst(obj);
17494                 var isRTL = this._get(inst, 'isRTL');
17495         while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
17496             obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
17497         }
17498         var position = $(obj).offset();
17499             return [position.left, position.top];
17500         },
17501
17502         /* Hide the date picker from view.
17503            @param  input  element - the input field attached to the date picker */
17504         _hideDatepicker: function(input) {
17505                 var inst = this._curInst;
17506                 if (!inst || (input && inst != $.data(input, PROP_NAME)))
17507                         return;
17508                 if (this._datepickerShowing) {
17509                         var showAnim = this._get(inst, 'showAnim');
17510                         var duration = this._get(inst, 'duration');
17511                         var postProcess = function() {
17512                                 $.datepicker._tidyDialog(inst);
17513                                 this._curInst = null;
17514                         };
17515                         if ($.effects && $.effects[showAnim])
17516                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
17517                         else
17518                                 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
17519                                         (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
17520                         if (!showAnim)
17521                                 postProcess();
17522                         var onClose = this._get(inst, 'onClose');
17523                         if (onClose)
17524                                 onClose.apply((inst.input ? inst.input[0] : null),
17525                                         [(inst.input ? inst.input.val() : ''), inst]);  // trigger custom callback
17526                         this._datepickerShowing = false;
17527                         this._lastInput = null;
17528                         if (this._inDialog) {
17529                                 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
17530                                 if ($.blockUI) {
17531                                         $.unblockUI();
17532                                         $('body').append(this.dpDiv);
17533                                 }
17534                         }
17535                         this._inDialog = false;
17536                 }
17537         },
17538
17539         /* Tidy up after a dialog display. */
17540         _tidyDialog: function(inst) {
17541                 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
17542         },
17543
17544         /* Close date picker if clicked elsewhere. */
17545         _checkExternalClick: function(event) {
17546                 if (!$.datepicker._curInst)
17547                         return;
17548                 var $target = $(event.target);
17549                 if ($target[0].id != $.datepicker._mainDivId &&
17550                                 $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
17551                                 !$target.hasClass($.datepicker.markerClassName) &&
17552                                 !$target.hasClass($.datepicker._triggerClass) &&
17553                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
17554                         $.datepicker._hideDatepicker();
17555         },
17556
17557         /* Adjust one of the date sub-fields. */
17558         _adjustDate: function(id, offset, period) {
17559                 var target = $(id);
17560                 var inst = this._getInst(target[0]);
17561                 if (this._isDisabledDatepicker(target[0])) {
17562                         return;
17563                 }
17564                 this._adjustInstDate(inst, offset +
17565                         (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
17566                         period);
17567                 this._updateDatepicker(inst);
17568         },
17569
17570         /* Action for current link. */
17571         _gotoToday: function(id) {
17572                 var target = $(id);
17573                 var inst = this._getInst(target[0]);
17574                 if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
17575                         inst.selectedDay = inst.currentDay;
17576                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
17577                         inst.drawYear = inst.selectedYear = inst.currentYear;
17578                 }
17579                 else {
17580                         var date = new Date();
17581                         inst.selectedDay = date.getDate();
17582                         inst.drawMonth = inst.selectedMonth = date.getMonth();
17583                         inst.drawYear = inst.selectedYear = date.getFullYear();
17584                 }
17585                 this._notifyChange(inst);
17586                 this._adjustDate(target);
17587         },
17588
17589         /* Action for selecting a new month/year. */
17590         _selectMonthYear: function(id, select, period) {
17591                 var target = $(id);
17592                 var inst = this._getInst(target[0]);
17593                 inst._selectingMonthYear = false;
17594                 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
17595                 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
17596                         parseInt(select.options[select.selectedIndex].value,10);
17597                 this._notifyChange(inst);
17598                 this._adjustDate(target);
17599         },
17600
17601         /* Restore input focus after not changing month/year. */
17602         _clickMonthYear: function(id) {
17603                 var target = $(id);
17604                 var inst = this._getInst(target[0]);
17605                 if (inst.input && inst._selectingMonthYear) {
17606                         setTimeout(function() {
17607                                 inst.input.focus();
17608                         }, 0);
17609                 }
17610                 inst._selectingMonthYear = !inst._selectingMonthYear;
17611         },
17612
17613         /* Action for selecting a day. */
17614         _selectDay: function(id, month, year, td) {
17615                 var target = $(id);
17616                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
17617                         return;
17618                 }
17619                 var inst = this._getInst(target[0]);
17620                 inst.selectedDay = inst.currentDay = $('a', td).html();
17621                 inst.selectedMonth = inst.currentMonth = month;
17622                 inst.selectedYear = inst.currentYear = year;
17623                 this._selectDate(id, this._formatDate(inst,
17624                         inst.currentDay, inst.currentMonth, inst.currentYear));
17625         },
17626
17627         /* Erase the input field and hide the date picker. */
17628         _clearDate: function(id) {
17629                 var target = $(id);
17630                 var inst = this._getInst(target[0]);
17631                 this._selectDate(target, '');
17632         },
17633
17634         /* Update the input field with the selected date. */
17635         _selectDate: function(id, dateStr) {
17636                 var target = $(id);
17637                 var inst = this._getInst(target[0]);
17638                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
17639                 if (inst.input)
17640                         inst.input.val(dateStr);
17641                 this._updateAlternate(inst);
17642                 var onSelect = this._get(inst, 'onSelect');
17643                 if (onSelect)
17644                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
17645                 else if (inst.input)
17646                         inst.input.trigger('change'); // fire the change event
17647                 if (inst.inline)
17648                         this._updateDatepicker(inst);
17649                 else {
17650                         this._hideDatepicker();
17651                         this._lastInput = inst.input[0];
17652                         if (typeof(inst.input[0]) != 'object')
17653                                 inst.input.focus(); // restore focus
17654                         this._lastInput = null;
17655                 }
17656         },
17657
17658         /* Update any alternate field to synchronise with the main field. */
17659         _updateAlternate: function(inst) {
17660                 var altField = this._get(inst, 'altField');
17661                 if (altField) { // update alternate field too
17662                         var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
17663                         var date = this._getDate(inst);
17664                         var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
17665                         $(altField).each(function() { $(this).val(dateStr); });
17666                 }
17667         },
17668
17669         /* Set as beforeShowDay function to prevent selection of weekends.
17670            @param  date  Date - the date to customise
17671            @return [boolean, string] - is this date selectable?, what is its CSS class? */
17672         noWeekends: function(date) {
17673                 var day = date.getDay();
17674                 return [(day > 0 && day < 6), ''];
17675         },
17676
17677         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
17678            @param  date  Date - the date to get the week for
17679            @return  number - the number of the week within the year that contains this date */
17680         iso8601Week: function(date) {
17681                 var checkDate = new Date(date.getTime());
17682                 // Find Thursday of this week starting on Monday
17683                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
17684                 var time = checkDate.getTime();
17685                 checkDate.setMonth(0); // Compare with Jan 1
17686                 checkDate.setDate(1);
17687                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
17688         },
17689
17690         /* Parse a string value into a date object.
17691            See formatDate below for the possible formats.
17692
17693            @param  format    string - the expected format of the date
17694            @param  value     string - the date in the above format
17695            @param  settings  Object - attributes include:
17696                              shortYearCutoff  number - the cutoff year for determining the century (optional)
17697                              dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
17698                              dayNames         string[7] - names of the days from Sunday (optional)
17699                              monthNamesShort  string[12] - abbreviated names of the months (optional)
17700                              monthNames       string[12] - names of the months (optional)
17701            @return  Date - the extracted date value or null if value is blank */
17702         parseDate: function (format, value, settings) {
17703                 if (format == null || value == null)
17704                         throw 'Invalid arguments';
17705                 value = (typeof value == 'object' ? value.toString() : value + '');
17706                 if (value == '')
17707                         return null;
17708                 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
17709                 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
17710                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
17711                 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
17712                 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
17713                 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
17714                 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
17715                 var year = -1;
17716                 var month = -1;
17717                 var day = -1;
17718                 var doy = -1;
17719                 var literal = false;
17720                 // Check whether a format character is doubled
17721                 var lookAhead = function(match) {
17722                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
17723                         if (matches)
17724                                 iFormat++;
17725                         return matches;
17726                 };
17727                 // Extract a number from the string value
17728                 var getNumber = function(match) {
17729                         var isDoubled = lookAhead(match);
17730                         var size = (match == '@' ? 14 : (match == '!' ? 20 :
17731                                 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
17732                         var digits = new RegExp('^\\d{1,' + size + '}');
17733                         var num = value.substring(iValue).match(digits);
17734                         if (!num)
17735                                 throw 'Missing number at position ' + iValue;
17736                         iValue += num[0].length;
17737                         return parseInt(num[0], 10);
17738                 };
17739                 // Extract a name from the string value and convert to an index
17740                 var getName = function(match, shortNames, longNames) {
17741                         var names = (lookAhead(match) ? longNames : shortNames);
17742                         for (var i = 0; i < names.length; i++) {
17743                                 if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) {
17744                                         iValue += names[i].length;
17745                                         return i + 1;
17746                                 }
17747                         }
17748                         throw 'Unknown name at position ' + iValue;
17749                 };
17750                 // Confirm that a literal character matches the string value
17751                 var checkLiteral = function() {
17752                         if (value.charAt(iValue) != format.charAt(iFormat))
17753                                 throw 'Unexpected literal at position ' + iValue;
17754                         iValue++;
17755                 };
17756                 var iValue = 0;
17757                 for (var iFormat = 0; iFormat < format.length; iFormat++) {
17758                         if (literal)
17759                                 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
17760                                         literal = false;
17761                                 else
17762                                         checkLiteral();
17763                         else
17764                                 switch (format.charAt(iFormat)) {
17765                                         case 'd':
17766                                                 day = getNumber('d');
17767                                                 break;
17768                                         case 'D':
17769                                                 getName('D', dayNamesShort, dayNames);
17770                                                 break;
17771                                         case 'o':
17772                                                 doy = getNumber('o');
17773                                                 break;
17774                                         case 'm':
17775                                                 month = getNumber('m');
17776                                                 break;
17777                                         case 'M':
17778                                                 month = getName('M', monthNamesShort, monthNames);
17779                                                 break;
17780                                         case 'y':
17781                                                 year = getNumber('y');
17782                                                 break;
17783                                         case '@':
17784                                                 var date = new Date(getNumber('@'));
17785                                                 year = date.getFullYear();
17786                                                 month = date.getMonth() + 1;
17787                                                 day = date.getDate();
17788                                                 break;
17789                                         case '!':
17790                                                 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
17791                                                 year = date.getFullYear();
17792                                                 month = date.getMonth() + 1;
17793                                                 day = date.getDate();
17794                                                 break;
17795                                         case "'":
17796                                                 if (lookAhead("'"))
17797                                                         checkLiteral();
17798                                                 else
17799                                                         literal = true;
17800                                                 break;
17801                                         default:
17802                                                 checkLiteral();
17803                                 }
17804                 }
17805                 if (year == -1)
17806                         year = new Date().getFullYear();
17807                 else if (year < 100)
17808                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
17809                                 (year <= shortYearCutoff ? 0 : -100);
17810                 if (doy > -1) {
17811                         month = 1;
17812                         day = doy;
17813                         do {
17814                                 var dim = this._getDaysInMonth(year, month - 1);
17815                                 if (day <= dim)
17816                                         break;
17817                                 month++;
17818                                 day -= dim;
17819                         } while (true);
17820                 }
17821                 var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
17822                 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
17823                         throw 'Invalid date'; // E.g. 31/02/00
17824                 return date;
17825         },
17826
17827         /* Standard date formats. */
17828         ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
17829         COOKIE: 'D, dd M yy',
17830         ISO_8601: 'yy-mm-dd',
17831         RFC_822: 'D, d M y',
17832         RFC_850: 'DD, dd-M-y',
17833         RFC_1036: 'D, d M y',
17834         RFC_1123: 'D, d M yy',
17835         RFC_2822: 'D, d M yy',
17836         RSS: 'D, d M y', // RFC 822
17837         TICKS: '!',
17838         TIMESTAMP: '@',
17839         W3C: 'yy-mm-dd', // ISO 8601
17840
17841         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
17842                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
17843
17844         /* Format a date object into a string value.
17845            The format can be combinations of the following:
17846            d  - day of month (no leading zero)
17847            dd - day of month (two digit)
17848            o  - day of year (no leading zeros)
17849            oo - day of year (three digit)
17850            D  - day name short
17851            DD - day name long
17852            m  - month of year (no leading zero)
17853            mm - month of year (two digit)
17854            M  - month name short
17855            MM - month name long
17856            y  - year (two digit)
17857            yy - year (four digit)
17858            @ - Unix timestamp (ms since 01/01/1970)
17859            ! - Windows ticks (100ns since 01/01/0001)
17860            '...' - literal text
17861            '' - single quote
17862
17863            @param  format    string - the desired format of the date
17864            @param  date      Date - the date value to format
17865            @param  settings  Object - attributes include:
17866                              dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
17867                              dayNames         string[7] - names of the days from Sunday (optional)
17868                              monthNamesShort  string[12] - abbreviated names of the months (optional)
17869                              monthNames       string[12] - names of the months (optional)
17870            @return  string - the date in the above format */
17871         formatDate: function (format, date, settings) {
17872                 if (!date)
17873                         return '';
17874                 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
17875                 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
17876                 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
17877                 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
17878                 // Check whether a format character is doubled
17879                 var lookAhead = function(match) {
17880                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
17881                         if (matches)
17882                                 iFormat++;
17883                         return matches;
17884                 };
17885                 // Format a number, with leading zero if necessary
17886                 var formatNumber = function(match, value, len) {
17887                         var num = '' + value;
17888                         if (lookAhead(match))
17889                                 while (num.length < len)
17890                                         num = '0' + num;
17891                         return num;
17892                 };
17893                 // Format a name, short or long as requested
17894                 var formatName = function(match, value, shortNames, longNames) {
17895                         return (lookAhead(match) ? longNames[value] : shortNames[value]);
17896                 };
17897                 var output = '';
17898                 var literal = false;
17899                 if (date)
17900                         for (var iFormat = 0; iFormat < format.length; iFormat++) {
17901                                 if (literal)
17902                                         if (format.charAt(iFormat) == "'" && !lookAhead("'"))
17903                                                 literal = false;
17904                                         else
17905                                                 output += format.charAt(iFormat);
17906                                 else
17907                                         switch (format.charAt(iFormat)) {
17908                                                 case 'd':
17909                                                         output += formatNumber('d', date.getDate(), 2);
17910                                                         break;
17911                                                 case 'D':
17912                                                         output += formatName('D', date.getDay(), dayNamesShort, dayNames);
17913                                                         break;
17914                                                 case 'o':
17915                                                         output += formatNumber('o',
17916                                                                 (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3);
17917                                                         break;
17918                                                 case 'm':
17919                                                         output += formatNumber('m', date.getMonth() + 1, 2);
17920                                                         break;
17921                                                 case 'M':
17922                                                         output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
17923                                                         break;
17924                                                 case 'y':
17925                                                         output += (lookAhead('y') ? date.getFullYear() :
17926                                                                 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
17927                                                         break;
17928                                                 case '@':
17929                                                         output += date.getTime();
17930                                                         break;
17931                                                 case '!':
17932                                                         output += date.getTime() * 10000 + this._ticksTo1970;
17933                                                         break;
17934                                                 case "'":
17935                                                         if (lookAhead("'"))
17936                                                                 output += "'";
17937                                                         else
17938                                                                 literal = true;
17939                                                         break;
17940                                                 default:
17941                                                         output += format.charAt(iFormat);
17942                                         }
17943                         }
17944                 return output;
17945         },
17946
17947         /* Extract all possible characters from the date format. */
17948         _possibleChars: function (format) {
17949                 var chars = '';
17950                 var literal = false;
17951                 // Check whether a format character is doubled
17952                 var lookAhead = function(match) {
17953                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
17954                         if (matches)
17955                                 iFormat++;
17956                         return matches;
17957                 };
17958                 for (var iFormat = 0; iFormat < format.length; iFormat++)
17959                         if (literal)
17960                                 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
17961                                         literal = false;
17962                                 else
17963                                         chars += format.charAt(iFormat);
17964                         else
17965                                 switch (format.charAt(iFormat)) {
17966                                         case 'd': case 'm': case 'y': case '@':
17967                                                 chars += '0123456789';
17968                                                 break;
17969                                         case 'D': case 'M':
17970                                                 return null; // Accept anything
17971                                         case "'":
17972                                                 if (lookAhead("'"))
17973                                                         chars += "'";
17974                                                 else
17975                                                         literal = true;
17976                                                 break;
17977                                         default:
17978                                                 chars += format.charAt(iFormat);
17979                                 }
17980                 return chars;
17981         },
17982
17983         /* Get a setting value, defaulting if necessary. */
17984         _get: function(inst, name) {
17985                 return inst.settings[name] !== undefined ?
17986                         inst.settings[name] : this._defaults[name];
17987         },
17988
17989         /* Parse existing date and initialise date picker. */
17990         _setDateFromField: function(inst, noDefault) {
17991                 if (inst.input.val() == inst.lastVal) {
17992                         return;
17993                 }
17994                 var dateFormat = this._get(inst, 'dateFormat');
17995                 var dates = inst.lastVal = inst.input ? inst.input.val() : null;
17996                 var date, defaultDate;
17997                 date = defaultDate = this._getDefaultDate(inst);
17998                 var settings = this._getFormatConfig(inst);
17999                 try {
18000                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
18001                 } catch (event) {
18002                         this.log(event);
18003                         dates = (noDefault ? '' : dates);
18004                 }
18005                 inst.selectedDay = date.getDate();
18006                 inst.drawMonth = inst.selectedMonth = date.getMonth();
18007                 inst.drawYear = inst.selectedYear = date.getFullYear();
18008                 inst.currentDay = (dates ? date.getDate() : 0);
18009                 inst.currentMonth = (dates ? date.getMonth() : 0);
18010                 inst.currentYear = (dates ? date.getFullYear() : 0);
18011                 this._adjustInstDate(inst);
18012         },
18013
18014         /* Retrieve the default date shown on opening. */
18015         _getDefaultDate: function(inst) {
18016                 return this._restrictMinMax(inst,
18017                         this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
18018         },
18019
18020         /* A date may be specified as an exact value or a relative one. */
18021         _determineDate: function(inst, date, defaultDate) {
18022                 var offsetNumeric = function(offset) {
18023                         var date = new Date();
18024                         date.setDate(date.getDate() + offset);
18025                         return date;
18026                 };
18027                 var offsetString = function(offset) {
18028                         try {
18029                                 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
18030                                         offset, $.datepicker._getFormatConfig(inst));
18031                         }
18032                         catch (e) {
18033                                 // Ignore
18034                         }
18035                         var date = (offset.toLowerCase().match(/^c/) ?
18036                                 $.datepicker._getDate(inst) : null) || new Date();
18037                         var year = date.getFullYear();
18038                         var month = date.getMonth();
18039                         var day = date.getDate();
18040                         var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
18041                         var matches = pattern.exec(offset);
18042                         while (matches) {
18043                                 switch (matches[2] || 'd') {
18044                                         case 'd' : case 'D' :
18045                                                 day += parseInt(matches[1],10); break;
18046                                         case 'w' : case 'W' :
18047                                                 day += parseInt(matches[1],10) * 7; break;
18048                                         case 'm' : case 'M' :
18049                                                 month += parseInt(matches[1],10);
18050                                                 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
18051                                                 break;
18052                                         case 'y': case 'Y' :
18053                                                 year += parseInt(matches[1],10);
18054                                                 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
18055                                                 break;
18056                                 }
18057                                 matches = pattern.exec(offset);
18058                         }
18059                         return new Date(year, month, day);
18060                 };
18061                 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
18062                         (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
18063                 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
18064                 if (newDate) {
18065                         newDate.setHours(0);
18066                         newDate.setMinutes(0);
18067                         newDate.setSeconds(0);
18068                         newDate.setMilliseconds(0);
18069                 }
18070                 return this._daylightSavingAdjust(newDate);
18071         },
18072
18073         /* Handle switch to/from daylight saving.
18074            Hours may be non-zero on daylight saving cut-over:
18075            > 12 when midnight changeover, but then cannot generate
18076            midnight datetime, so jump to 1AM, otherwise reset.
18077            @param  date  (Date) the date to check
18078            @return  (Date) the corrected date */
18079         _daylightSavingAdjust: function(date) {
18080                 if (!date) return null;
18081                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
18082                 return date;
18083         },
18084
18085         /* Set the date(s) directly. */
18086         _setDate: function(inst, date, noChange) {
18087                 var clear = !date;
18088                 var origMonth = inst.selectedMonth;
18089                 var origYear = inst.selectedYear;
18090                 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
18091                 inst.selectedDay = inst.currentDay = newDate.getDate();
18092                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
18093                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
18094                 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
18095                         this._notifyChange(inst);
18096                 this._adjustInstDate(inst);
18097                 if (inst.input) {
18098                         inst.input.val(clear ? '' : this._formatDate(inst));
18099                 }
18100         },
18101
18102         /* Retrieve the date(s) directly. */
18103         _getDate: function(inst) {
18104                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
18105                         this._daylightSavingAdjust(new Date(
18106                         inst.currentYear, inst.currentMonth, inst.currentDay)));
18107                         return startDate;
18108         },
18109
18110         /* Generate the HTML for the current state of the date picker. */
18111         _generateHTML: function(inst) {
18112                 var today = new Date();
18113                 today = this._daylightSavingAdjust(
18114                         new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
18115                 var isRTL = this._get(inst, 'isRTL');
18116                 var showButtonPanel = this._get(inst, 'showButtonPanel');
18117                 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
18118                 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
18119                 var numMonths = this._getNumberOfMonths(inst);
18120                 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
18121                 var stepMonths = this._get(inst, 'stepMonths');
18122                 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
18123                 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
18124                         new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
18125                 var minDate = this._getMinMaxDate(inst, 'min');
18126                 var maxDate = this._getMinMaxDate(inst, 'max');
18127                 var drawMonth = inst.drawMonth - showCurrentAtPos;
18128                 var drawYear = inst.drawYear;
18129                 if (drawMonth < 0) {
18130                         drawMonth += 12;
18131                         drawYear--;
18132                 }
18133                 if (maxDate) {
18134                         var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
18135                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
18136                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
18137                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
18138                                 drawMonth--;
18139                                 if (drawMonth < 0) {
18140                                         drawMonth = 11;
18141                                         drawYear--;
18142                                 }
18143                         }
18144                 }
18145                 inst.drawMonth = drawMonth;
18146                 inst.drawYear = drawYear;
18147                 var prevText = this._get(inst, 'prevText');
18148                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
18149                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
18150                         this._getFormatConfig(inst)));
18151                 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
18152                         '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
18153                         '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
18154                         ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
18155                         (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
18156                 var nextText = this._get(inst, 'nextText');
18157                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
18158                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
18159                         this._getFormatConfig(inst)));
18160                 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
18161                         '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
18162                         '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
18163                         ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
18164                         (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
18165                 var currentText = this._get(inst, 'currentText');
18166                 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
18167                 currentText = (!navigationAsDateFormat ? currentText :
18168                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
18169                 var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
18170                         '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
18171                 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
18172                         (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
18173                         '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
18174                         '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
18175                 var firstDay = parseInt(this._get(inst, 'firstDay'),10);
18176                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
18177                 var showWeek = this._get(inst, 'showWeek');
18178                 var dayNames = this._get(inst, 'dayNames');
18179                 var dayNamesShort = this._get(inst, 'dayNamesShort');
18180                 var dayNamesMin = this._get(inst, 'dayNamesMin');
18181                 var monthNames = this._get(inst, 'monthNames');
18182                 var monthNamesShort = this._get(inst, 'monthNamesShort');
18183                 var beforeShowDay = this._get(inst, 'beforeShowDay');
18184                 var showOtherMonths = this._get(inst, 'showOtherMonths');
18185                 var selectOtherMonths = this._get(inst, 'selectOtherMonths');
18186                 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
18187                 var defaultDate = this._getDefaultDate(inst);
18188                 var html = '';
18189                 for (var row = 0; row < numMonths[0]; row++) {
18190                         var group = '';
18191                         for (var col = 0; col < numMonths[1]; col++) {
18192                                 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
18193                                 var cornerClass = ' ui-corner-all';
18194                                 var calender = '';
18195                                 if (isMultiMonth) {
18196                                         calender += '<div class="ui-datepicker-group';
18197                                         if (numMonths[1] > 1)
18198                                                 switch (col) {
18199                                                         case 0: calender += ' ui-datepicker-group-first';
18200                                                                 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
18201                                                         case numMonths[1]-1: calender += ' ui-datepicker-group-last';
18202                                                                 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
18203                                                         default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
18204                                                 }
18205                                         calender += '">';
18206                                 }
18207                                 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
18208                                         (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
18209                                         (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
18210                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
18211                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
18212                                         '</div><table class="ui-datepicker-calendar"><thead>' +
18213                                         '<tr>';
18214                                 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
18215                                 for (var dow = 0; dow < 7; dow++) { // days of the week
18216                                         var day = (dow + firstDay) % 7;
18217                                         thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
18218                                                 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
18219                                 }
18220                                 calender += thead + '</tr></thead><tbody>';
18221                                 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
18222                                 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
18223                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
18224                                 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
18225                                 var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
18226                                 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
18227                                 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
18228                                         calender += '<tr>';
18229                                         var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
18230                                                 this._get(inst, 'calculateWeek')(printDate) + '</td>');
18231                                         for (var dow = 0; dow < 7; dow++) { // create date picker days
18232                                                 var daySettings = (beforeShowDay ?
18233                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
18234                                                 var otherMonth = (printDate.getMonth() != drawMonth);
18235                                                 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
18236                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
18237                                                 tbody += '<td class="' +
18238                                                         ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
18239                                                         (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
18240                                                         ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
18241                                                         (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
18242                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
18243                                                         ' ' + this._dayOverClass : '') + // highlight selected day
18244                                                         (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
18245                                                         (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
18246                                                         (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
18247                                                         (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
18248                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
18249                                                         (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
18250                                                         inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
18251                                                         (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
18252                                                         (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
18253                                                         (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
18254                                                         (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
18255                                                         (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
18256                                                         '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
18257                                                 printDate.setDate(printDate.getDate() + 1);
18258                                                 printDate = this._daylightSavingAdjust(printDate);
18259                                         }
18260                                         calender += tbody + '</tr>';
18261                                 }
18262                                 drawMonth++;
18263                                 if (drawMonth > 11) {
18264                                         drawMonth = 0;
18265                                         drawYear++;
18266                                 }
18267                                 calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 
18268                                                         ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
18269                                 group += calender;
18270                         }
18271                         html += group;
18272                 }
18273                 html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
18274                         '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
18275                 inst._keyEvent = false;
18276                 return html;
18277         },
18278
18279         /* Generate the month and year header. */
18280         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
18281                         secondary, monthNames, monthNamesShort) {
18282                 var changeMonth = this._get(inst, 'changeMonth');
18283                 var changeYear = this._get(inst, 'changeYear');
18284                 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
18285                 var html = '<div class="ui-datepicker-title">';
18286                 var monthHtml = '';
18287                 // month selection
18288                 if (secondary || !changeMonth)
18289                         monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
18290                 else {
18291                         var inMinYear = (minDate && minDate.getFullYear() == drawYear);
18292                         var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
18293                         monthHtml += '<select class="ui-datepicker-month" ' +
18294                                 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
18295                                 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
18296                                 '>';
18297                         for (var month = 0; month < 12; month++) {
18298                                 if ((!inMinYear || month >= minDate.getMonth()) &&
18299                                                 (!inMaxYear || month <= maxDate.getMonth()))
18300                                         monthHtml += '<option value="' + month + '"' +
18301                                                 (month == drawMonth ? ' selected="selected"' : '') +
18302                                                 '>' + monthNamesShort[month] + '</option>';
18303                         }
18304                         monthHtml += '</select>';
18305                 }
18306                 if (!showMonthAfterYear)
18307                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
18308                 // year selection
18309                 if ( !inst.yearshtml ) {
18310                         inst.yearshtml = '';
18311                         if (secondary || !changeYear)
18312                                 html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
18313                         else {
18314                                 // determine range of years to display
18315                                 var years = this._get(inst, 'yearRange').split(':');
18316                                 var thisYear = new Date().getFullYear();
18317                                 var determineYear = function(value) {
18318                                         var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
18319                                                 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
18320                                                 parseInt(value, 10)));
18321                                         return (isNaN(year) ? thisYear : year);
18322                                 };
18323                                 var year = determineYear(years[0]);
18324                                 var endYear = Math.max(year, determineYear(years[1] || ''));
18325                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
18326                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
18327                                 inst.yearshtml += '<select class="ui-datepicker-year" ' +
18328                                         'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
18329                                         'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
18330                                         '>';
18331                                 for (; year <= endYear; year++) {
18332                                         inst.yearshtml += '<option value="' + year + '"' +
18333                                                 (year == drawYear ? ' selected="selected"' : '') +
18334                                                 '>' + year + '</option>';
18335                                 }
18336                                 inst.yearshtml += '</select>';
18337                                 //when showing there is no need for later update
18338                                 if( ! $.browser.mozilla ){
18339                                         html += inst.yearshtml;
18340                                         inst.yearshtml = null;
18341                                 } else {
18342                                         // will be replaced later with inst.yearshtml
18343                                         html += '<select class="ui-datepicker-year"><option value="' + drawYear + '" selected="selected">' + drawYear + '</option></select>';
18344                                 }
18345                         }
18346                 }
18347                 html += this._get(inst, 'yearSuffix');
18348                 if (showMonthAfterYear)
18349                         html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
18350                 html += '</div>'; // Close datepicker_header
18351                 return html;
18352         },
18353
18354         /* Adjust one of the date sub-fields. */
18355         _adjustInstDate: function(inst, offset, period) {
18356                 var year = inst.drawYear + (period == 'Y' ? offset : 0);
18357                 var month = inst.drawMonth + (period == 'M' ? offset : 0);
18358                 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
18359                         (period == 'D' ? offset : 0);
18360                 var date = this._restrictMinMax(inst,
18361                         this._daylightSavingAdjust(new Date(year, month, day)));
18362                 inst.selectedDay = date.getDate();
18363                 inst.drawMonth = inst.selectedMonth = date.getMonth();
18364                 inst.drawYear = inst.selectedYear = date.getFullYear();
18365                 if (period == 'M' || period == 'Y')
18366                         this._notifyChange(inst);
18367         },
18368
18369         /* Ensure a date is within any min/max bounds. */
18370         _restrictMinMax: function(inst, date) {
18371                 var minDate = this._getMinMaxDate(inst, 'min');
18372                 var maxDate = this._getMinMaxDate(inst, 'max');
18373                 var newDate = (minDate && date < minDate ? minDate : date);
18374                 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
18375                 return newDate;
18376         },
18377
18378         /* Notify change of month/year. */
18379         _notifyChange: function(inst) {
18380                 var onChange = this._get(inst, 'onChangeMonthYear');
18381                 if (onChange)
18382                         onChange.apply((inst.input ? inst.input[0] : null),
18383                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
18384         },
18385
18386         /* Determine the number of months to show. */
18387         _getNumberOfMonths: function(inst) {
18388                 var numMonths = this._get(inst, 'numberOfMonths');
18389                 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
18390         },
18391
18392         /* Determine the current maximum date - ensure no time components are set. */
18393         _getMinMaxDate: function(inst, minMax) {
18394                 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
18395         },
18396
18397         /* Find the number of days in a given month. */
18398         _getDaysInMonth: function(year, month) {
18399                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
18400         },
18401
18402         /* Find the day of the week of the first of a month. */
18403         _getFirstDayOfMonth: function(year, month) {
18404                 return new Date(year, month, 1).getDay();
18405         },
18406
18407         /* Determines if we should allow a "next/prev" month display change. */
18408         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
18409                 var numMonths = this._getNumberOfMonths(inst);
18410                 var date = this._daylightSavingAdjust(new Date(curYear,
18411                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
18412                 if (offset < 0)
18413                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
18414                 return this._isInRange(inst, date);
18415         },
18416
18417         /* Is the given date in the accepted range? */
18418         _isInRange: function(inst, date) {
18419                 var minDate = this._getMinMaxDate(inst, 'min');
18420                 var maxDate = this._getMinMaxDate(inst, 'max');
18421                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
18422                         (!maxDate || date.getTime() <= maxDate.getTime()));
18423         },
18424
18425         /* Provide the configuration settings for formatting/parsing. */
18426         _getFormatConfig: function(inst) {
18427                 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
18428                 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
18429                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
18430                 return {shortYearCutoff: shortYearCutoff,
18431                         dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
18432                         monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
18433         },
18434
18435         /* Format the given date for display. */
18436         _formatDate: function(inst, day, month, year) {
18437                 if (!day) {
18438                         inst.currentDay = inst.selectedDay;
18439                         inst.currentMonth = inst.selectedMonth;
18440                         inst.currentYear = inst.selectedYear;
18441                 }
18442                 var date = (day ? (typeof day == 'object' ? day :
18443                         this._daylightSavingAdjust(new Date(year, month, day))) :
18444                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
18445                 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
18446         }
18447 });
18448
18449 /* jQuery extend now ignores nulls! */
18450 function extendRemove(target, props) {
18451         $.extend(target, props);
18452         for (var name in props)
18453                 if (props[name] == null || props[name] == undefined)
18454                         target[name] = props[name];
18455         return target;
18456 };
18457
18458 /* Determine whether an object is an array. */
18459 function isArray(a) {
18460         return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
18461                 (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
18462 };
18463
18464 /* Invoke the datepicker functionality.
18465    @param  options  string - a command, optionally followed by additional parameters or
18466                     Object - settings for attaching new datepicker functionality
18467    @return  jQuery object */
18468 $.fn.datepicker = function(options){
18469         
18470         /* Verify an empty collection wasn't passed - Fixes #6976 */
18471         if ( !this.length ) {
18472                 return this;
18473         }
18474         
18475         /* Initialise the date picker. */
18476         if (!$.datepicker.initialized) {
18477                 $(document).mousedown($.datepicker._checkExternalClick).
18478                         find('body').append($.datepicker.dpDiv);
18479                 $.datepicker.initialized = true;
18480         }
18481
18482         var otherArgs = Array.prototype.slice.call(arguments, 1);
18483         if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
18484                 return $.datepicker['_' + options + 'Datepicker'].
18485                         apply($.datepicker, [this[0]].concat(otherArgs));
18486         if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
18487                 return $.datepicker['_' + options + 'Datepicker'].
18488                         apply($.datepicker, [this[0]].concat(otherArgs));
18489         return this.each(function() {
18490                 typeof options == 'string' ?
18491                         $.datepicker['_' + options + 'Datepicker'].
18492                                 apply($.datepicker, [this].concat(otherArgs)) :
18493                         $.datepicker._attachDatepicker(this, options);
18494         });
18495 };
18496
18497 $.datepicker = new Datepicker(); // singleton instance
18498 $.datepicker.initialized = false;
18499 $.datepicker.uuid = new Date().getTime();
18500 $.datepicker.version = "1.8.12";
18501
18502 // Workaround for #4055
18503 // Add another global to avoid noConflict issues with inline event handlers
18504 window['DP_jQuery_' + dpuuid] = $;
18505
18506 })(jQuery);
18507 /*
18508  * jQuery UI Dialog 1.8.12
18509  *
18510  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
18511  * Dual licensed under the MIT or GPL Version 2 licenses.
18512  * http://jquery.org/license
18513  *
18514  * http://docs.jquery.com/UI/Dialog
18515  *
18516  * Depends:
18517  *      jquery.ui.core.js
18518  *      jquery.ui.widget.js
18519  *  jquery.ui.button.js
18520  *      jquery.ui.draggable.js
18521  *      jquery.ui.mouse.js
18522  *      jquery.ui.position.js
18523  *      jquery.ui.resizable.js
18524  */
18525 (function( $, undefined ) {
18526
18527 var uiDialogClasses =
18528                 'ui-dialog ' +
18529                 'ui-widget ' +
18530                 'ui-widget-content ' +
18531                 'ui-corner-all ',
18532         sizeRelatedOptions = {
18533                 buttons: true,
18534                 height: true,
18535                 maxHeight: true,
18536                 maxWidth: true,
18537                 minHeight: true,
18538                 minWidth: true,
18539                 width: true
18540         },
18541         resizableRelatedOptions = {
18542                 maxHeight: true,
18543                 maxWidth: true,
18544                 minHeight: true,
18545                 minWidth: true
18546         },
18547         // support for jQuery 1.3.2 - handle common attrFn methods for dialog
18548         attrFn = $.attrFn || {
18549                 val: true,
18550                 css: true,
18551                 html: true,
18552                 text: true,
18553                 data: true,
18554                 width: true,
18555                 height: true,
18556                 offset: true,
18557                 click: true
18558         };
18559
18560 $.widget("ui.dialog", {
18561         options: {
18562                 autoOpen: true,
18563                 buttons: {},
18564                 closeOnEscape: true,
18565                 closeText: 'close',
18566                 dialogClass: '',
18567                 draggable: true,
18568                 hide: null,
18569                 height: 'auto',
18570                 maxHeight: false,
18571                 maxWidth: false,
18572                 minHeight: 150,
18573                 minWidth: 150,
18574                 modal: false,
18575                 position: {
18576                         my: 'center',
18577                         at: 'center',
18578                         collision: 'fit',
18579                         // ensure that the titlebar is never outside the document
18580                         using: function(pos) {
18581                                 var topOffset = $(this).css(pos).offset().top;
18582                                 if (topOffset < 0) {
18583                                         $(this).css('top', pos.top - topOffset);
18584                                 }
18585                         }
18586                 },
18587                 resizable: true,
18588                 show: null,
18589                 stack: true,
18590                 title: '',
18591                 width: 300,
18592                 zIndex: 1000
18593         },
18594
18595         _create: function() {
18596                 this.originalTitle = this.element.attr('title');
18597                 // #5742 - .attr() might return a DOMElement
18598                 if ( typeof this.originalTitle !== "string" ) {
18599                         this.originalTitle = "";
18600                 }
18601
18602                 this.options.title = this.options.title || this.originalTitle;
18603                 var self = this,
18604                         options = self.options,
18605
18606                         title = options.title || '&#160;',
18607                         titleId = $.ui.dialog.getTitleId(self.element),
18608
18609                         uiDialog = (self.uiDialog = $('<div></div>'))
18610                                 .appendTo(document.body)
18611                                 .hide()
18612                                 .addClass(uiDialogClasses + options.dialogClass)
18613                                 .css({
18614                                         zIndex: options.zIndex
18615                                 })
18616                                 // setting tabIndex makes the div focusable
18617                                 // setting outline to 0 prevents a border on focus in Mozilla
18618                                 .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
18619                                         if (options.closeOnEscape && event.keyCode &&
18620                                                 event.keyCode === $.ui.keyCode.ESCAPE) {
18621                                                 
18622                                                 self.close(event);
18623                                                 event.preventDefault();
18624                                         }
18625                                 })
18626                                 .attr({
18627                                         role: 'dialog',
18628                                         'aria-labelledby': titleId
18629                                 })
18630                                 .mousedown(function(event) {
18631                                         self.moveToTop(false, event);
18632                                 }),
18633
18634                         uiDialogContent = self.element
18635                                 .show()
18636                                 .removeAttr('title')
18637                                 .addClass(
18638                                         'ui-dialog-content ' +
18639                                         'ui-widget-content')
18640                                 .appendTo(uiDialog),
18641
18642                         uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
18643                                 .addClass(
18644                                         'ui-dialog-titlebar ' +
18645                                         'ui-widget-header ' +
18646                                         'ui-corner-top ' +
18647                                         'ui-helper-clearfix'
18648                                 )
18649                                 .prependTo(uiDialog),
18650
18651                         uiDialogTitlebarClose = $('<a href="#"></a>')
18652                                 .addClass(
18653                                         'ui-dialog-titlebar-close ' +
18654                                         'ui-corner-all'
18655                                 )
18656                                 .attr('role', 'button')
18657                                 .hover(
18658                                         function() {
18659                                                 uiDialogTitlebarClose.addClass('ui-state-hover');
18660                                         },
18661                                         function() {
18662                                                 uiDialogTitlebarClose.removeClass('ui-state-hover');
18663                                         }
18664                                 )
18665                                 .focus(function() {
18666                                         uiDialogTitlebarClose.addClass('ui-state-focus');
18667                                 })
18668                                 .blur(function() {
18669                                         uiDialogTitlebarClose.removeClass('ui-state-focus');
18670                                 })
18671                                 .click(function(event) {
18672                                         self.close(event);
18673                                         return false;
18674                                 })
18675                                 .appendTo(uiDialogTitlebar),
18676
18677                         uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
18678                                 .addClass(
18679                                         'ui-icon ' +
18680                                         'ui-icon-closethick'
18681                                 )
18682                                 .text(options.closeText)
18683                                 .appendTo(uiDialogTitlebarClose),
18684
18685                         uiDialogTitle = $('<span></span>')
18686                                 .addClass('ui-dialog-title')
18687                                 .attr('id', titleId)
18688                                 .html(title)
18689                                 .prependTo(uiDialogTitlebar);
18690
18691                 //handling of deprecated beforeclose (vs beforeClose) option
18692                 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
18693                 //TODO: remove in 1.9pre
18694                 if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
18695                         options.beforeClose = options.beforeclose;
18696                 }
18697
18698                 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
18699
18700                 if (options.draggable && $.fn.draggable) {
18701                         self._makeDraggable();
18702                 }
18703                 if (options.resizable && $.fn.resizable) {
18704                         self._makeResizable();
18705                 }
18706
18707                 self._createButtons(options.buttons);
18708                 self._isOpen = false;
18709
18710                 if ($.fn.bgiframe) {
18711                         uiDialog.bgiframe();
18712                 }
18713         },
18714
18715         _init: function() {
18716                 if ( this.options.autoOpen ) {
18717                         this.open();
18718                 }
18719         },
18720
18721         destroy: function() {
18722                 var self = this;
18723                 
18724                 if (self.overlay) {
18725                         self.overlay.destroy();
18726                 }
18727                 self.uiDialog.hide();
18728                 self.element
18729                         .unbind('.dialog')
18730                         .removeData('dialog')
18731                         .removeClass('ui-dialog-content ui-widget-content')
18732                         .hide().appendTo('body');
18733                 self.uiDialog.remove();
18734
18735                 if (self.originalTitle) {
18736                         self.element.attr('title', self.originalTitle);
18737                 }
18738
18739                 return self;
18740         },
18741
18742         widget: function() {
18743                 return this.uiDialog;
18744         },
18745
18746         close: function(event) {
18747                 var self = this,
18748                         maxZ, thisZ;
18749                 
18750                 if (false === self._trigger('beforeClose', event)) {
18751                         return;
18752                 }
18753
18754                 if (self.overlay) {
18755                         self.overlay.destroy();
18756                 }
18757                 self.uiDialog.unbind('keypress.ui-dialog');
18758
18759                 self._isOpen = false;
18760
18761                 if (self.options.hide) {
18762                         self.uiDialog.hide(self.options.hide, function() {
18763                                 self._trigger('close', event);
18764                         });
18765                 } else {
18766                         self.uiDialog.hide();
18767                         self._trigger('close', event);
18768                 }
18769
18770                 $.ui.dialog.overlay.resize();
18771
18772                 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
18773                 if (self.options.modal) {
18774                         maxZ = 0;
18775                         $('.ui-dialog').each(function() {
18776                                 if (this !== self.uiDialog[0]) {
18777                                         thisZ = $(this).css('z-index');
18778                                         if(!isNaN(thisZ)) {
18779                                                 maxZ = Math.max(maxZ, thisZ);
18780                                         }
18781                                 }
18782                         });
18783                         $.ui.dialog.maxZ = maxZ;
18784                 }
18785
18786                 return self;
18787         },
18788
18789         isOpen: function() {
18790                 return this._isOpen;
18791         },
18792
18793         // the force parameter allows us to move modal dialogs to their correct
18794         // position on open
18795         moveToTop: function(force, event) {
18796                 var self = this,
18797                         options = self.options,
18798                         saveScroll;
18799
18800                 if ((options.modal && !force) ||
18801                         (!options.stack && !options.modal)) {
18802                         return self._trigger('focus', event);
18803                 }
18804
18805                 if (options.zIndex > $.ui.dialog.maxZ) {
18806                         $.ui.dialog.maxZ = options.zIndex;
18807                 }
18808                 if (self.overlay) {
18809                         $.ui.dialog.maxZ += 1;
18810                         self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
18811                 }
18812
18813                 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
18814                 //  http://ui.jquery.com/bugs/ticket/3193
18815                 saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') };
18816                 $.ui.dialog.maxZ += 1;
18817                 self.uiDialog.css('z-index', $.ui.dialog.maxZ);
18818                 self.element.attr(saveScroll);
18819                 self._trigger('focus', event);
18820
18821                 return self;
18822         },
18823
18824         open: function() {
18825                 if (this._isOpen) { return; }
18826
18827                 var self = this,
18828                         options = self.options,
18829                         uiDialog = self.uiDialog;
18830
18831                 self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
18832                 self._size();
18833                 self._position(options.position);
18834                 uiDialog.show(options.show);
18835                 self.moveToTop(true);
18836
18837                 // prevent tabbing out of modal dialogs
18838                 if (options.modal) {
18839                         uiDialog.bind('keypress.ui-dialog', function(event) {
18840                                 if (event.keyCode !== $.ui.keyCode.TAB) {
18841                                         return;
18842                                 }
18843
18844                                 var tabbables = $(':tabbable', this),
18845                                         first = tabbables.filter(':first'),
18846                                         last  = tabbables.filter(':last');
18847
18848                                 if (event.target === last[0] && !event.shiftKey) {
18849                                         first.focus(1);
18850                                         return false;
18851                                 } else if (event.target === first[0] && event.shiftKey) {
18852                                         last.focus(1);
18853                                         return false;
18854                                 }
18855                         });
18856                 }
18857
18858                 // set focus to the first tabbable element in the content area or the first button
18859                 // if there are no tabbable elements, set focus on the dialog itself
18860                 $(self.element.find(':tabbable').get().concat(
18861                         uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
18862                                 uiDialog.get()))).eq(0).focus();
18863
18864                 self._isOpen = true;
18865                 self._trigger('open');
18866
18867                 return self;
18868         },
18869
18870         _createButtons: function(buttons) {
18871                 var self = this,
18872                         hasButtons = false,
18873                         uiDialogButtonPane = $('<div></div>')
18874                                 .addClass(
18875                                         'ui-dialog-buttonpane ' +
18876                                         'ui-widget-content ' +
18877                                         'ui-helper-clearfix'
18878                                 ),
18879                         uiButtonSet = $( "<div></div>" )
18880                                 .addClass( "ui-dialog-buttonset" )
18881                                 .appendTo( uiDialogButtonPane );
18882
18883                 // if we already have a button pane, remove it
18884                 self.uiDialog.find('.ui-dialog-buttonpane').remove();
18885
18886                 if (typeof buttons === 'object' && buttons !== null) {
18887                         $.each(buttons, function() {
18888                                 return !(hasButtons = true);
18889                         });
18890                 }
18891                 if (hasButtons) {
18892                         $.each(buttons, function(name, props) {
18893                                 props = $.isFunction( props ) ?
18894                                         { click: props, text: name } :
18895                                         props;
18896                                 var button = $('<button type="button"></button>')
18897                                         .click(function() {
18898                                                 props.click.apply(self.element[0], arguments);
18899                                         })
18900                                         .appendTo(uiButtonSet);
18901                                 // can't use .attr( props, true ) with jQuery 1.3.2.
18902                                 $.each( props, function( key, value ) {
18903                                         if ( key === "click" ) {
18904                                                 return;
18905                                         }
18906                                         if ( key in attrFn ) {
18907                                                 button[ key ]( value );
18908                                         } else {
18909                                                 button.attr( key, value );
18910                                         }
18911                                 });
18912                                 if ($.fn.button) {
18913                                         button.button();
18914                                 }
18915                         });
18916                         uiDialogButtonPane.appendTo(self.uiDialog);
18917                 }
18918         },
18919
18920         _makeDraggable: function() {
18921                 var self = this,
18922                         options = self.options,
18923                         doc = $(document),
18924                         heightBeforeDrag;
18925
18926                 function filteredUi(ui) {
18927                         return {
18928                                 position: ui.position,
18929                                 offset: ui.offset
18930                         };
18931                 }
18932
18933                 self.uiDialog.draggable({
18934                         cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
18935                         handle: '.ui-dialog-titlebar',
18936                         containment: 'document',
18937                         start: function(event, ui) {
18938                                 heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
18939                                 $(this).height($(this).height()).addClass("ui-dialog-dragging");
18940                                 self._trigger('dragStart', event, filteredUi(ui));
18941                         },
18942                         drag: function(event, ui) {
18943                                 self._trigger('drag', event, filteredUi(ui));
18944                         },
18945                         stop: function(event, ui) {
18946                                 options.position = [ui.position.left - doc.scrollLeft(),
18947                                         ui.position.top - doc.scrollTop()];
18948                                 $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
18949                                 self._trigger('dragStop', event, filteredUi(ui));
18950                                 $.ui.dialog.overlay.resize();
18951                         }
18952                 });
18953         },
18954
18955         _makeResizable: function(handles) {
18956                 handles = (handles === undefined ? this.options.resizable : handles);
18957                 var self = this,
18958                         options = self.options,
18959                         // .ui-resizable has position: relative defined in the stylesheet
18960                         // but dialogs have to use absolute or fixed positioning
18961                         position = self.uiDialog.css('position'),
18962                         resizeHandles = (typeof handles === 'string' ?
18963                                 handles :
18964                                 'n,e,s,w,se,sw,ne,nw'
18965                         );
18966
18967                 function filteredUi(ui) {
18968                         return {
18969                                 originalPosition: ui.originalPosition,
18970                                 originalSize: ui.originalSize,
18971                                 position: ui.position,
18972                                 size: ui.size
18973                         };
18974                 }
18975
18976                 self.uiDialog.resizable({
18977                         cancel: '.ui-dialog-content',
18978                         containment: 'document',
18979                         alsoResize: self.element,
18980                         maxWidth: options.maxWidth,
18981                         maxHeight: options.maxHeight,
18982                         minWidth: options.minWidth,
18983                         minHeight: self._minHeight(),
18984                         handles: resizeHandles,
18985                         start: function(event, ui) {
18986                                 $(this).addClass("ui-dialog-resizing");
18987                                 self._trigger('resizeStart', event, filteredUi(ui));
18988                         },
18989                         resize: function(event, ui) {
18990                                 self._trigger('resize', event, filteredUi(ui));
18991                         },
18992                         stop: function(event, ui) {
18993                                 $(this).removeClass("ui-dialog-resizing");
18994                                 options.height = $(this).height();
18995                                 options.width = $(this).width();
18996                                 self._trigger('resizeStop', event, filteredUi(ui));
18997                                 $.ui.dialog.overlay.resize();
18998                         }
18999                 })
19000                 .css('position', position)
19001                 .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
19002         },
19003
19004         _minHeight: function() {
19005                 var options = this.options;
19006
19007                 if (options.height === 'auto') {
19008                         return options.minHeight;
19009                 } else {
19010                         return Math.min(options.minHeight, options.height);
19011                 }
19012         },
19013
19014         _position: function(position) {
19015                 var myAt = [],
19016                         offset = [0, 0],
19017                         isVisible;
19018
19019                 if (position) {
19020                         // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
19021         //              if (typeof position == 'string' || $.isArray(position)) {
19022         //                      myAt = $.isArray(position) ? position : position.split(' ');
19023
19024                         if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
19025                                 myAt = position.split ? position.split(' ') : [position[0], position[1]];
19026                                 if (myAt.length === 1) {
19027                                         myAt[1] = myAt[0];
19028                                 }
19029
19030                                 $.each(['left', 'top'], function(i, offsetPosition) {
19031                                         if (+myAt[i] === myAt[i]) {
19032                                                 offset[i] = myAt[i];
19033                                                 myAt[i] = offsetPosition;
19034                                         }
19035                                 });
19036
19037                                 position = {
19038                                         my: myAt.join(" "),
19039                                         at: myAt.join(" "),
19040                                         offset: offset.join(" ")
19041                                 };
19042                         } 
19043
19044                         position = $.extend({}, $.ui.dialog.prototype.options.position, position);
19045                 } else {
19046                         position = $.ui.dialog.prototype.options.position;
19047                 }
19048
19049                 // need to show the dialog to get the actual offset in the position plugin
19050                 isVisible = this.uiDialog.is(':visible');
19051                 if (!isVisible) {
19052                         this.uiDialog.show();
19053                 }
19054                 this.uiDialog
19055                         // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
19056                         .css({ top: 0, left: 0 })
19057                         .position($.extend({ of: window }, position));
19058                 if (!isVisible) {
19059                         this.uiDialog.hide();
19060                 }
19061         },
19062
19063         _setOptions: function( options ) {
19064                 var self = this,
19065                         resizableOptions = {},
19066                         resize = false;
19067
19068                 $.each( options, function( key, value ) {
19069                         self._setOption( key, value );
19070                         
19071                         if ( key in sizeRelatedOptions ) {
19072                                 resize = true;
19073                         }
19074                         if ( key in resizableRelatedOptions ) {
19075                                 resizableOptions[ key ] = value;
19076                         }
19077                 });
19078
19079                 if ( resize ) {
19080                         this._size();
19081                 }
19082                 if ( this.uiDialog.is( ":data(resizable)" ) ) {
19083                         this.uiDialog.resizable( "option", resizableOptions );
19084                 }
19085         },
19086
19087         _setOption: function(key, value){
19088                 var self = this,
19089                         uiDialog = self.uiDialog;
19090
19091                 switch (key) {
19092                         //handling of deprecated beforeclose (vs beforeClose) option
19093                         //Ticket #4669 http://dev.jqueryui.com/ticket/4669
19094                         //TODO: remove in 1.9pre
19095                         case "beforeclose":
19096                                 key = "beforeClose";
19097                                 break;
19098                         case "buttons":
19099                                 self._createButtons(value);
19100                                 break;
19101                         case "closeText":
19102                                 // ensure that we always pass a string
19103                                 self.uiDialogTitlebarCloseText.text("" + value);
19104                                 break;
19105                         case "dialogClass":
19106                                 uiDialog
19107                                         .removeClass(self.options.dialogClass)
19108                                         .addClass(uiDialogClasses + value);
19109                                 break;
19110                         case "disabled":
19111                                 if (value) {
19112                                         uiDialog.addClass('ui-dialog-disabled');
19113                                 } else {
19114                                         uiDialog.removeClass('ui-dialog-disabled');
19115                                 }
19116                                 break;
19117                         case "draggable":
19118                                 var isDraggable = uiDialog.is( ":data(draggable)" );
19119                                 if ( isDraggable && !value ) {
19120                                         uiDialog.draggable( "destroy" );
19121                                 }
19122                                 
19123                                 if ( !isDraggable && value ) {
19124                                         self._makeDraggable();
19125                                 }
19126                                 break;
19127                         case "position":
19128                                 self._position(value);
19129                                 break;
19130                         case "resizable":
19131                                 // currently resizable, becoming non-resizable
19132                                 var isResizable = uiDialog.is( ":data(resizable)" );
19133                                 if (isResizable && !value) {
19134                                         uiDialog.resizable('destroy');
19135                                 }
19136
19137                                 // currently resizable, changing handles
19138                                 if (isResizable && typeof value === 'string') {
19139                                         uiDialog.resizable('option', 'handles', value);
19140                                 }
19141
19142                                 // currently non-resizable, becoming resizable
19143                                 if (!isResizable && value !== false) {
19144                                         self._makeResizable(value);
19145                                 }
19146                                 break;
19147                         case "title":
19148                                 // convert whatever was passed in o a string, for html() to not throw up
19149                                 $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
19150                                 break;
19151                 }
19152
19153                 $.Widget.prototype._setOption.apply(self, arguments);
19154         },
19155
19156         _size: function() {
19157                 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
19158                  * divs will both have width and height set, so we need to reset them
19159                  */
19160                 var options = this.options,
19161                         nonContentHeight,
19162                         minContentHeight,
19163                         isVisible = this.uiDialog.is( ":visible" );
19164
19165                 // reset content sizing
19166                 this.element.show().css({
19167                         width: 'auto',
19168                         minHeight: 0,
19169                         height: 0
19170                 });
19171
19172                 if (options.minWidth > options.width) {
19173                         options.width = options.minWidth;
19174                 }
19175
19176                 // reset wrapper sizing
19177                 // determine the height of all the non-content elements
19178                 nonContentHeight = this.uiDialog.css({
19179                                 height: 'auto',
19180                                 width: options.width
19181                         })
19182                         .height();
19183                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
19184                 
19185                 if ( options.height === "auto" ) {
19186                         // only needed for IE6 support
19187                         if ( $.support.minHeight ) {
19188                                 this.element.css({
19189                                         minHeight: minContentHeight,
19190                                         height: "auto"
19191                                 });
19192                         } else {
19193                                 this.uiDialog.show();
19194                                 var autoHeight = this.element.css( "height", "auto" ).height();
19195                                 if ( !isVisible ) {
19196                                         this.uiDialog.hide();
19197                                 }
19198                                 this.element.height( Math.max( autoHeight, minContentHeight ) );
19199                         }
19200                 } else {
19201                         this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
19202                 }
19203
19204                 if (this.uiDialog.is(':data(resizable)')) {
19205                         this.uiDialog.resizable('option', 'minHeight', this._minHeight());
19206                 }
19207         }
19208 });
19209
19210 $.extend($.ui.dialog, {
19211         version: "1.8.12",
19212
19213         uuid: 0,
19214         maxZ: 0,
19215
19216         getTitleId: function($el) {
19217                 var id = $el.attr('id');
19218                 if (!id) {
19219                         this.uuid += 1;
19220                         id = this.uuid;
19221                 }
19222                 return 'ui-dialog-title-' + id;
19223         },
19224
19225         overlay: function(dialog) {
19226                 this.$el = $.ui.dialog.overlay.create(dialog);
19227         }
19228 });
19229
19230 $.extend($.ui.dialog.overlay, {
19231         instances: [],
19232         // reuse old instances due to IE memory leak with alpha transparency (see #5185)
19233         oldInstances: [],
19234         maxZ: 0,
19235         events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
19236                 function(event) { return event + '.dialog-overlay'; }).join(' '),
19237         create: function(dialog) {
19238                 if (this.instances.length === 0) {
19239                         // prevent use of anchors and inputs
19240                         // we use a setTimeout in case the overlay is created from an
19241                         // event that we're going to be cancelling (see #2804)
19242                         setTimeout(function() {
19243                                 // handle $(el).dialog().dialog('close') (see #4065)
19244                                 if ($.ui.dialog.overlay.instances.length) {
19245                                         $(document).bind($.ui.dialog.overlay.events, function(event) {
19246                                                 // stop events if the z-index of the target is < the z-index of the overlay
19247                                                 // we cannot return true when we don't want to cancel the event (#3523)
19248                                                 if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
19249                                                         return false;
19250                                                 }
19251                                         });
19252                                 }
19253                         }, 1);
19254
19255                         // allow closing by pressing the escape key
19256                         $(document).bind('keydown.dialog-overlay', function(event) {
19257                                 if (dialog.options.closeOnEscape && event.keyCode &&
19258                                         event.keyCode === $.ui.keyCode.ESCAPE) {
19259                                         
19260                                         dialog.close(event);
19261                                         event.preventDefault();
19262                                 }
19263                         });
19264
19265                         // handle window resize
19266                         $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
19267                 }
19268
19269                 var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
19270                         .appendTo(document.body)
19271                         .css({
19272                                 width: this.width(),
19273                                 height: this.height()
19274                         });
19275
19276                 if ($.fn.bgiframe) {
19277                         $el.bgiframe();
19278                 }
19279
19280                 this.instances.push($el);
19281                 return $el;
19282         },
19283
19284         destroy: function($el) {
19285                 var indexOf = $.inArray($el, this.instances);
19286                 if (indexOf != -1){
19287                         this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
19288                 }
19289
19290                 if (this.instances.length === 0) {
19291                         $([document, window]).unbind('.dialog-overlay');
19292                 }
19293
19294                 $el.remove();
19295                 
19296                 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
19297                 var maxZ = 0;
19298                 $.each(this.instances, function() {
19299                         maxZ = Math.max(maxZ, this.css('z-index'));
19300                 });
19301                 this.maxZ = maxZ;
19302         },
19303
19304         height: function() {
19305                 var scrollHeight,
19306                         offsetHeight;
19307                 // handle IE 6
19308                 if ($.browser.msie && $.browser.version < 7) {
19309                         scrollHeight = Math.max(
19310                                 document.documentElement.scrollHeight,
19311                                 document.body.scrollHeight
19312                         );
19313                         offsetHeight = Math.max(
19314                                 document.documentElement.offsetHeight,
19315                                 document.body.offsetHeight
19316                         );
19317
19318                         if (scrollHeight < offsetHeight) {
19319                                 return $(window).height() + 'px';
19320                         } else {
19321                                 return scrollHeight + 'px';
19322                         }
19323                 // handle "good" browsers
19324                 } else {
19325                         return $(document).height() + 'px';
19326                 }
19327         },
19328
19329         width: function() {
19330                 var scrollWidth,
19331                         offsetWidth;
19332                 // handle IE 6
19333                 if ($.browser.msie && $.browser.version < 7) {
19334                         scrollWidth = Math.max(
19335                                 document.documentElement.scrollWidth,
19336                                 document.body.scrollWidth
19337                         );
19338                         offsetWidth = Math.max(
19339                                 document.documentElement.offsetWidth,
19340                                 document.body.offsetWidth
19341                         );
19342
19343                         if (scrollWidth < offsetWidth) {
19344                                 return $(window).width() + 'px';
19345                         } else {
19346                                 return scrollWidth + 'px';
19347                         }
19348                 // handle "good" browsers
19349                 } else {
19350                         return $(document).width() + 'px';
19351                 }
19352         },
19353
19354         resize: function() {
19355                 /* If the dialog is draggable and the user drags it past the
19356                  * right edge of the window, the document becomes wider so we
19357                  * need to stretch the overlay. If the user then drags the
19358                  * dialog back to the left, the document will become narrower,
19359                  * so we need to shrink the overlay to the appropriate size.
19360                  * This is handled by shrinking the overlay before setting it
19361                  * to the full document size.
19362                  */
19363                 var $overlays = $([]);
19364                 $.each($.ui.dialog.overlay.instances, function() {
19365                         $overlays = $overlays.add(this);
19366                 });
19367
19368                 $overlays.css({
19369                         width: 0,
19370                         height: 0
19371                 }).css({
19372                         width: $.ui.dialog.overlay.width(),
19373                         height: $.ui.dialog.overlay.height()
19374                 });
19375         }
19376 });
19377
19378 $.extend($.ui.dialog.overlay.prototype, {
19379         destroy: function() {
19380                 $.ui.dialog.overlay.destroy(this.$el);
19381         }
19382 });
19383
19384 }(jQuery));
19385 /*
19386  * jQuery UI Position 1.8.12
19387  *
19388  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
19389  * Dual licensed under the MIT or GPL Version 2 licenses.
19390  * http://jquery.org/license
19391  *
19392  * http://docs.jquery.com/UI/Position
19393  */
19394 (function( $, undefined ) {
19395
19396 $.ui = $.ui || {};
19397
19398 var horizontalPositions = /left|center|right/,
19399         verticalPositions = /top|center|bottom/,
19400         center = "center",
19401         _position = $.fn.position,
19402         _offset = $.fn.offset;
19403
19404 $.fn.position = function( options ) {
19405         if ( !options || !options.of ) {
19406                 return _position.apply( this, arguments );
19407         }
19408
19409         // make a copy, we don't want to modify arguments
19410         options = $.extend( {}, options );
19411
19412         var target = $( options.of ),
19413                 targetElem = target[0],
19414                 collision = ( options.collision || "flip" ).split( " " ),
19415                 offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
19416                 targetWidth,
19417                 targetHeight,
19418                 basePosition;
19419
19420         if ( targetElem.nodeType === 9 ) {
19421                 targetWidth = target.width();
19422                 targetHeight = target.height();
19423                 basePosition = { top: 0, left: 0 };
19424         // TODO: use $.isWindow() in 1.9
19425         } else if ( targetElem.setTimeout ) {
19426                 targetWidth = target.width();
19427                 targetHeight = target.height();
19428                 basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
19429         } else if ( targetElem.preventDefault ) {
19430                 // force left top to allow flipping
19431                 options.at = "left top";
19432                 targetWidth = targetHeight = 0;
19433                 basePosition = { top: options.of.pageY, left: options.of.pageX };
19434         } else {
19435                 targetWidth = target.outerWidth();
19436                 targetHeight = target.outerHeight();
19437                 basePosition = target.offset();
19438         }
19439
19440         // force my and at to have valid horizontal and veritcal positions
19441         // if a value is missing or invalid, it will be converted to center 
19442         $.each( [ "my", "at" ], function() {
19443                 var pos = ( options[this] || "" ).split( " " );
19444                 if ( pos.length === 1) {
19445                         pos = horizontalPositions.test( pos[0] ) ?
19446                                 pos.concat( [center] ) :
19447                                 verticalPositions.test( pos[0] ) ?
19448                                         [ center ].concat( pos ) :
19449                                         [ center, center ];
19450                 }
19451                 pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
19452                 pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
19453                 options[ this ] = pos;
19454         });
19455
19456         // normalize collision option
19457         if ( collision.length === 1 ) {
19458                 collision[ 1 ] = collision[ 0 ];
19459         }
19460
19461         // normalize offset option
19462         offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
19463         if ( offset.length === 1 ) {
19464                 offset[ 1 ] = offset[ 0 ];
19465         }
19466         offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
19467
19468         if ( options.at[0] === "right" ) {
19469                 basePosition.left += targetWidth;
19470         } else if ( options.at[0] === center ) {
19471                 basePosition.left += targetWidth / 2;
19472         }
19473
19474         if ( options.at[1] === "bottom" ) {
19475                 basePosition.top += targetHeight;
19476         } else if ( options.at[1] === center ) {
19477                 basePosition.top += targetHeight / 2;
19478         }
19479
19480         basePosition.left += offset[ 0 ];
19481         basePosition.top += offset[ 1 ];
19482
19483         return this.each(function() {
19484                 var elem = $( this ),
19485                         elemWidth = elem.outerWidth(),
19486                         elemHeight = elem.outerHeight(),
19487                         marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
19488                         marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
19489                         collisionWidth = elemWidth + marginLeft +
19490                                 ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
19491                         collisionHeight = elemHeight + marginTop +
19492                                 ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
19493                         position = $.extend( {}, basePosition ),
19494                         collisionPosition;
19495
19496                 if ( options.my[0] === "right" ) {
19497                         position.left -= elemWidth;
19498                 } else if ( options.my[0] === center ) {
19499                         position.left -= elemWidth / 2;
19500                 }
19501
19502                 if ( options.my[1] === "bottom" ) {
19503                         position.top -= elemHeight;
19504                 } else if ( options.my[1] === center ) {
19505                         position.top -= elemHeight / 2;
19506                 }
19507
19508                 // prevent fractions (see #5280)
19509                 position.left = Math.round( position.left );
19510                 position.top = Math.round( position.top );
19511
19512                 collisionPosition = {
19513                         left: position.left - marginLeft,
19514                         top: position.top - marginTop
19515                 };
19516
19517                 $.each( [ "left", "top" ], function( i, dir ) {
19518                         if ( $.ui.position[ collision[i] ] ) {
19519                                 $.ui.position[ collision[i] ][ dir ]( position, {
19520                                         targetWidth: targetWidth,
19521                                         targetHeight: targetHeight,
19522                                         elemWidth: elemWidth,
19523                                         elemHeight: elemHeight,
19524                                         collisionPosition: collisionPosition,
19525                                         collisionWidth: collisionWidth,
19526                                         collisionHeight: collisionHeight,
19527                                         offset: offset,
19528                                         my: options.my,
19529                                         at: options.at
19530                                 });
19531                         }
19532                 });
19533
19534                 if ( $.fn.bgiframe ) {
19535                         elem.bgiframe();
19536                 }
19537                 elem.offset( $.extend( position, { using: options.using } ) );
19538         });
19539 };
19540
19541 $.ui.position = {
19542         fit: {
19543                 left: function( position, data ) {
19544                         var win = $( window ),
19545                                 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
19546                         position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
19547                 },
19548                 top: function( position, data ) {
19549                         var win = $( window ),
19550                                 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
19551                         position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
19552                 }
19553         },
19554
19555         flip: {
19556                 left: function( position, data ) {
19557                         if ( data.at[0] === center ) {
19558                                 return;
19559                         }
19560                         var win = $( window ),
19561                                 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
19562                                 myOffset = data.my[ 0 ] === "left" ?
19563                                         -data.elemWidth :
19564                                         data.my[ 0 ] === "right" ?
19565                                                 data.elemWidth :
19566                                                 0,
19567                                 atOffset = data.at[ 0 ] === "left" ?
19568                                         data.targetWidth :
19569                                         -data.targetWidth,
19570                                 offset = -2 * data.offset[ 0 ];
19571                         position.left += data.collisionPosition.left < 0 ?
19572                                 myOffset + atOffset + offset :
19573                                 over > 0 ?
19574                                         myOffset + atOffset + offset :
19575                                         0;
19576                 },
19577                 top: function( position, data ) {
19578                         if ( data.at[1] === center ) {
19579                                 return;
19580                         }
19581                         var win = $( window ),
19582                                 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
19583                                 myOffset = data.my[ 1 ] === "top" ?
19584                                         -data.elemHeight :
19585                                         data.my[ 1 ] === "bottom" ?
19586                                                 data.elemHeight :
19587                                                 0,
19588                                 atOffset = data.at[ 1 ] === "top" ?
19589                                         data.targetHeight :
19590                                         -data.targetHeight,
19591                                 offset = -2 * data.offset[ 1 ];
19592                         position.top += data.collisionPosition.top < 0 ?
19593                                 myOffset + atOffset + offset :
19594                                 over > 0 ?
19595                                         myOffset + atOffset + offset :
19596                                         0;
19597                 }
19598         }
19599 };
19600
19601 // offset setter from jQuery 1.4
19602 if ( !$.offset.setOffset ) {
19603         $.offset.setOffset = function( elem, options ) {
19604                 // set position first, in-case top/left are set even on static elem
19605                 if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
19606                         elem.style.position = "relative";
19607                 }
19608                 var curElem   = $( elem ),
19609                         curOffset = curElem.offset(),
19610                         curTop    = parseInt( $.curCSS( elem, "top",  true ), 10 ) || 0,
19611                         curLeft   = parseInt( $.curCSS( elem, "left", true ), 10)  || 0,
19612                         props     = {
19613                                 top:  (options.top  - curOffset.top)  + curTop,
19614                                 left: (options.left - curOffset.left) + curLeft
19615                         };
19616                 
19617                 if ( 'using' in options ) {
19618                         options.using.call( elem, props );
19619                 } else {
19620                         curElem.css( props );
19621                 }
19622         };
19623
19624         $.fn.offset = function( options ) {
19625                 var elem = this[ 0 ];
19626                 if ( !elem || !elem.ownerDocument ) { return null; }
19627                 if ( options ) { 
19628                         return this.each(function() {
19629                                 $.offset.setOffset( this, options );
19630                         });
19631                 }
19632                 return _offset.call( this );
19633         };
19634 }
19635
19636 }( jQuery ));
19637 /*
19638  * jQuery UI Progressbar 1.8.12
19639  *
19640  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
19641  * Dual licensed under the MIT or GPL Version 2 licenses.
19642  * http://jquery.org/license
19643  *
19644  * http://docs.jquery.com/UI/Progressbar
19645  *
19646  * Depends:
19647  *   jquery.ui.core.js
19648  *   jquery.ui.widget.js
19649  */
19650 (function( $, undefined ) {
19651
19652 $.widget( "ui.progressbar", {
19653         options: {
19654                 value: 0,
19655                 max: 100
19656         },
19657
19658         min: 0,
19659
19660         _create: function() {
19661                 this.element
19662                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
19663                         .attr({
19664                                 role: "progressbar",
19665                                 "aria-valuemin": this.min,
19666                                 "aria-valuemax": this.options.max,
19667                                 "aria-valuenow": this._value()
19668                         });
19669
19670                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
19671                         .appendTo( this.element );
19672
19673                 this.oldValue = this._value();
19674                 this._refreshValue();
19675         },
19676
19677         destroy: function() {
19678                 this.element
19679                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
19680                         .removeAttr( "role" )
19681                         .removeAttr( "aria-valuemin" )
19682                         .removeAttr( "aria-valuemax" )
19683                         .removeAttr( "aria-valuenow" );
19684
19685                 this.valueDiv.remove();
19686
19687                 $.Widget.prototype.destroy.apply( this, arguments );
19688         },
19689
19690         value: function( newValue ) {
19691                 if ( newValue === undefined ) {
19692                         return this._value();
19693                 }
19694
19695                 this._setOption( "value", newValue );
19696                 return this;
19697         },
19698
19699         _setOption: function( key, value ) {
19700                 if ( key === "value" ) {
19701                         this.options.value = value;
19702                         this._refreshValue();
19703                         if ( this._value() === this.options.max ) {
19704                                 this._trigger( "complete" );
19705                         }
19706                 }
19707
19708                 $.Widget.prototype._setOption.apply( this, arguments );
19709         },
19710
19711         _value: function() {
19712                 var val = this.options.value;
19713                 // normalize invalid value
19714                 if ( typeof val !== "number" ) {
19715                         val = 0;
19716                 }
19717                 return Math.min( this.options.max, Math.max( this.min, val ) );
19718         },
19719
19720         _percentage: function() {
19721                 return 100 * this._value() / this.options.max;
19722         },
19723
19724         _refreshValue: function() {
19725                 var value = this.value();
19726                 var percentage = this._percentage();
19727
19728                 if ( this.oldValue !== value ) {
19729                         this.oldValue = value;
19730                         this._trigger( "change" );
19731                 }
19732
19733                 this.valueDiv
19734                         .toggle( value > this.min )
19735                         .toggleClass( "ui-corner-right", value === this.options.max )
19736                         .width( percentage.toFixed(0) + "%" );
19737                 this.element.attr( "aria-valuenow", value );
19738         }
19739 });
19740
19741 $.extend( $.ui.progressbar, {
19742         version: "1.8.12"
19743 });
19744
19745 })( jQuery );
19746 /*
19747  * jQuery UI Slider 1.8.12
19748  *
19749  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
19750  * Dual licensed under the MIT or GPL Version 2 licenses.
19751  * http://jquery.org/license
19752  *
19753  * http://docs.jquery.com/UI/Slider
19754  *
19755  * Depends:
19756  *      jquery.ui.core.js
19757  *      jquery.ui.mouse.js
19758  *      jquery.ui.widget.js
19759  */
19760 (function( $, undefined ) {
19761
19762 // number of pages in a slider
19763 // (how many times can you page up/down to go through the whole range)
19764 var numPages = 5;
19765
19766 $.widget( "ui.slider", $.ui.mouse, {
19767
19768         widgetEventPrefix: "slide",
19769
19770         options: {
19771                 animate: false,
19772                 distance: 0,
19773                 max: 100,
19774                 min: 0,
19775                 orientation: "horizontal",
19776                 range: false,
19777                 step: 1,
19778                 value: 0,
19779                 values: null
19780         },
19781
19782         _create: function() {
19783                 var self = this,
19784                         o = this.options;
19785
19786                 this._keySliding = false;
19787                 this._mouseSliding = false;
19788                 this._animateOff = true;
19789                 this._handleIndex = null;
19790                 this._detectOrientation();
19791                 this._mouseInit();
19792
19793                 this.element
19794                         .addClass( "ui-slider" +
19795                                 " ui-slider-" + this.orientation +
19796                                 " ui-widget" +
19797                                 " ui-widget-content" +
19798                                 " ui-corner-all" );
19799                 
19800                 if ( o.disabled ) {
19801                         this.element.addClass( "ui-slider-disabled ui-disabled" );
19802                 }
19803
19804                 this.range = $([]);
19805
19806                 if ( o.range ) {
19807                         if ( o.range === true ) {
19808                                 this.range = $( "<div></div>" );
19809                                 if ( !o.values ) {
19810                                         o.values = [ this._valueMin(), this._valueMin() ];
19811                                 }
19812                                 if ( o.values.length && o.values.length !== 2 ) {
19813                                         o.values = [ o.values[0], o.values[0] ];
19814                                 }
19815                         } else {
19816                                 this.range = $( "<div></div>" );
19817                         }
19818
19819                         this.range
19820                                 .appendTo( this.element )
19821                                 .addClass( "ui-slider-range" );
19822
19823                         if ( o.range === "min" || o.range === "max" ) {
19824                                 this.range.addClass( "ui-slider-range-" + o.range );
19825                         }
19826
19827                         // note: this isn't the most fittingly semantic framework class for this element,
19828                         // but worked best visually with a variety of themes
19829                         this.range.addClass( "ui-widget-header" );
19830                 }
19831
19832                 if ( $( ".ui-slider-handle", this.element ).length === 0 ) {
19833                         $( "<a href='#'></a>" )
19834                                 .appendTo( this.element )
19835                                 .addClass( "ui-slider-handle" );
19836                 }
19837
19838                 if ( o.values && o.values.length ) {
19839                         while ( $(".ui-slider-handle", this.element).length < o.values.length ) {
19840                                 $( "<a href='#'></a>" )
19841                                         .appendTo( this.element )
19842                                         .addClass( "ui-slider-handle" );
19843                         }
19844                 }
19845
19846                 this.handles = $( ".ui-slider-handle", this.element )
19847                         .addClass( "ui-state-default" +
19848                                 " ui-corner-all" );
19849
19850                 this.handle = this.handles.eq( 0 );
19851
19852                 this.handles.add( this.range ).filter( "a" )
19853                         .click(function( event ) {
19854                                 event.preventDefault();
19855                         })
19856                         .hover(function() {
19857                                 if ( !o.disabled ) {
19858                                         $( this ).addClass( "ui-state-hover" );
19859                                 }
19860                         }, function() {
19861                                 $( this ).removeClass( "ui-state-hover" );
19862                         })
19863                         .focus(function() {
19864                                 if ( !o.disabled ) {
19865                                         $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
19866                                         $( this ).addClass( "ui-state-focus" );
19867                                 } else {
19868                                         $( this ).blur();
19869                                 }
19870                         })
19871                         .blur(function() {
19872                                 $( this ).removeClass( "ui-state-focus" );
19873                         });
19874
19875                 this.handles.each(function( i ) {
19876                         $( this ).data( "index.ui-slider-handle", i );
19877                 });
19878
19879                 this.handles
19880                         .keydown(function( event ) {
19881                                 var ret = true,
19882                                         index = $( this ).data( "index.ui-slider-handle" ),
19883                                         allowed,
19884                                         curVal,
19885                                         newVal,
19886                                         step;
19887         
19888                                 if ( self.options.disabled ) {
19889                                         return;
19890                                 }
19891         
19892                                 switch ( event.keyCode ) {
19893                                         case $.ui.keyCode.HOME:
19894                                         case $.ui.keyCode.END:
19895                                         case $.ui.keyCode.PAGE_UP:
19896                                         case $.ui.keyCode.PAGE_DOWN:
19897                                         case $.ui.keyCode.UP:
19898                                         case $.ui.keyCode.RIGHT:
19899                                         case $.ui.keyCode.DOWN:
19900                                         case $.ui.keyCode.LEFT:
19901                                                 ret = false;
19902                                                 if ( !self._keySliding ) {
19903                                                         self._keySliding = true;
19904                                                         $( this ).addClass( "ui-state-active" );
19905                                                         allowed = self._start( event, index );
19906                                                         if ( allowed === false ) {
19907                                                                 return;
19908                                                         }
19909                                                 }
19910                                                 break;
19911                                 }
19912         
19913                                 step = self.options.step;
19914                                 if ( self.options.values && self.options.values.length ) {
19915                                         curVal = newVal = self.values( index );
19916                                 } else {
19917                                         curVal = newVal = self.value();
19918                                 }
19919         
19920                                 switch ( event.keyCode ) {
19921                                         case $.ui.keyCode.HOME:
19922                                                 newVal = self._valueMin();
19923                                                 break;
19924                                         case $.ui.keyCode.END:
19925                                                 newVal = self._valueMax();
19926                                                 break;
19927                                         case $.ui.keyCode.PAGE_UP:
19928                                                 newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
19929                                                 break;
19930                                         case $.ui.keyCode.PAGE_DOWN:
19931                                                 newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
19932                                                 break;
19933                                         case $.ui.keyCode.UP:
19934                                         case $.ui.keyCode.RIGHT:
19935                                                 if ( curVal === self._valueMax() ) {
19936                                                         return;
19937                                                 }
19938                                                 newVal = self._trimAlignValue( curVal + step );
19939                                                 break;
19940                                         case $.ui.keyCode.DOWN:
19941                                         case $.ui.keyCode.LEFT:
19942                                                 if ( curVal === self._valueMin() ) {
19943                                                         return;
19944                                                 }
19945                                                 newVal = self._trimAlignValue( curVal - step );
19946                                                 break;
19947                                 }
19948         
19949                                 self._slide( event, index, newVal );
19950         
19951                                 return ret;
19952         
19953                         })
19954                         .keyup(function( event ) {
19955                                 var index = $( this ).data( "index.ui-slider-handle" );
19956         
19957                                 if ( self._keySliding ) {
19958                                         self._keySliding = false;
19959                                         self._stop( event, index );
19960                                         self._change( event, index );
19961                                         $( this ).removeClass( "ui-state-active" );
19962                                 }
19963         
19964                         });
19965
19966                 this._refreshValue();
19967
19968                 this._animateOff = false;
19969         },
19970
19971         destroy: function() {
19972                 this.handles.remove();
19973                 this.range.remove();
19974
19975                 this.element
19976                         .removeClass( "ui-slider" +
19977                                 " ui-slider-horizontal" +
19978                                 " ui-slider-vertical" +
19979                                 " ui-slider-disabled" +
19980                                 " ui-widget" +
19981                                 " ui-widget-content" +
19982                                 " ui-corner-all" )
19983                         .removeData( "slider" )
19984                         .unbind( ".slider" );
19985
19986                 this._mouseDestroy();
19987
19988                 return this;
19989         },
19990
19991         _mouseCapture: function( event ) {
19992                 var o = this.options,
19993                         position,
19994                         normValue,
19995                         distance,
19996                         closestHandle,
19997                         self,
19998                         index,
19999                         allowed,
20000                         offset,
20001                         mouseOverHandle;
20002
20003                 if ( o.disabled ) {
20004                         return false;
20005                 }
20006
20007                 this.elementSize = {
20008                         width: this.element.outerWidth(),
20009                         height: this.element.outerHeight()
20010                 };
20011                 this.elementOffset = this.element.offset();
20012
20013                 position = { x: event.pageX, y: event.pageY };
20014                 normValue = this._normValueFromMouse( position );
20015                 distance = this._valueMax() - this._valueMin() + 1;
20016                 self = this;
20017                 this.handles.each(function( i ) {
20018                         var thisDistance = Math.abs( normValue - self.values(i) );
20019                         if ( distance > thisDistance ) {
20020                                 distance = thisDistance;
20021                                 closestHandle = $( this );
20022                                 index = i;
20023                         }
20024                 });
20025
20026                 // workaround for bug #3736 (if both handles of a range are at 0,
20027                 // the first is always used as the one with least distance,
20028                 // and moving it is obviously prevented by preventing negative ranges)
20029                 if( o.range === true && this.values(1) === o.min ) {
20030                         index += 1;
20031                         closestHandle = $( this.handles[index] );
20032                 }
20033
20034                 allowed = this._start( event, index );
20035                 if ( allowed === false ) {
20036                         return false;
20037                 }
20038                 this._mouseSliding = true;
20039
20040                 self._handleIndex = index;
20041
20042                 closestHandle
20043                         .addClass( "ui-state-active" )
20044                         .focus();
20045                 
20046                 offset = closestHandle.offset();
20047                 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
20048                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
20049                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
20050                         top: event.pageY - offset.top -
20051                                 ( closestHandle.height() / 2 ) -
20052                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
20053                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
20054                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
20055                 };
20056
20057                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
20058                         this._slide( event, index, normValue );
20059                 }
20060                 this._animateOff = true;
20061                 return true;
20062         },
20063
20064         _mouseStart: function( event ) {
20065                 return true;
20066         },
20067
20068         _mouseDrag: function( event ) {
20069                 var position = { x: event.pageX, y: event.pageY },
20070                         normValue = this._normValueFromMouse( position );
20071                 
20072                 this._slide( event, this._handleIndex, normValue );
20073
20074                 return false;
20075         },
20076
20077         _mouseStop: function( event ) {
20078                 this.handles.removeClass( "ui-state-active" );
20079                 this._mouseSliding = false;
20080
20081                 this._stop( event, this._handleIndex );
20082                 this._change( event, this._handleIndex );
20083
20084                 this._handleIndex = null;
20085                 this._clickOffset = null;
20086                 this._animateOff = false;
20087
20088                 return false;
20089         },
20090         
20091         _detectOrientation: function() {
20092                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
20093         },
20094
20095         _normValueFromMouse: function( position ) {
20096                 var pixelTotal,
20097                         pixelMouse,
20098                         percentMouse,
20099                         valueTotal,
20100                         valueMouse;
20101
20102                 if ( this.orientation === "horizontal" ) {
20103                         pixelTotal = this.elementSize.width;
20104                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
20105                 } else {
20106                         pixelTotal = this.elementSize.height;
20107                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
20108                 }
20109
20110                 percentMouse = ( pixelMouse / pixelTotal );
20111                 if ( percentMouse > 1 ) {
20112                         percentMouse = 1;
20113                 }
20114                 if ( percentMouse < 0 ) {
20115                         percentMouse = 0;
20116                 }
20117                 if ( this.orientation === "vertical" ) {
20118                         percentMouse = 1 - percentMouse;
20119                 }
20120
20121                 valueTotal = this._valueMax() - this._valueMin();
20122                 valueMouse = this._valueMin() + percentMouse * valueTotal;
20123
20124                 return this._trimAlignValue( valueMouse );
20125         },
20126
20127         _start: function( event, index ) {
20128                 var uiHash = {
20129                         handle: this.handles[ index ],
20130                         value: this.value()
20131                 };
20132                 if ( this.options.values && this.options.values.length ) {
20133                         uiHash.value = this.values( index );
20134                         uiHash.values = this.values();
20135                 }
20136                 return this._trigger( "start", event, uiHash );
20137         },
20138
20139         _slide: function( event, index, newVal ) {
20140                 var otherVal,
20141                         newValues,
20142                         allowed;
20143
20144                 if ( this.options.values && this.options.values.length ) {
20145                         otherVal = this.values( index ? 0 : 1 );
20146
20147                         if ( ( this.options.values.length === 2 && this.options.range === true ) && 
20148                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
20149                                 ) {
20150                                 newVal = otherVal;
20151                         }
20152
20153                         if ( newVal !== this.values( index ) ) {
20154                                 newValues = this.values();
20155                                 newValues[ index ] = newVal;
20156                                 // A slide can be canceled by returning false from the slide callback
20157                                 allowed = this._trigger( "slide", event, {
20158                                         handle: this.handles[ index ],
20159                                         value: newVal,
20160                                         values: newValues
20161                                 } );
20162                                 otherVal = this.values( index ? 0 : 1 );
20163                                 if ( allowed !== false ) {
20164                                         this.values( index, newVal, true );
20165                                 }
20166                         }
20167                 } else {
20168                         if ( newVal !== this.value() ) {
20169                                 // A slide can be canceled by returning false from the slide callback
20170                                 allowed = this._trigger( "slide", event, {
20171                                         handle: this.handles[ index ],
20172                                         value: newVal
20173                                 } );
20174                                 if ( allowed !== false ) {
20175                                         this.value( newVal );
20176                                 }
20177                         }
20178                 }
20179         },
20180
20181         _stop: function( event, index ) {
20182                 var uiHash = {
20183                         handle: this.handles[ index ],
20184                         value: this.value()
20185                 };
20186                 if ( this.options.values && this.options.values.length ) {
20187                         uiHash.value = this.values( index );
20188                         uiHash.values = this.values();
20189                 }
20190
20191                 this._trigger( "stop", event, uiHash );
20192         },
20193
20194         _change: function( event, index ) {
20195                 if ( !this._keySliding && !this._mouseSliding ) {
20196                         var uiHash = {
20197                                 handle: this.handles[ index ],
20198                                 value: this.value()
20199                         };
20200                         if ( this.options.values && this.options.values.length ) {
20201                                 uiHash.value = this.values( index );
20202                                 uiHash.values = this.values();
20203                         }
20204
20205                         this._trigger( "change", event, uiHash );
20206                 }
20207         },
20208
20209         value: function( newValue ) {
20210                 if ( arguments.length ) {
20211                         this.options.value = this._trimAlignValue( newValue );
20212                         this._refreshValue();
20213                         this._change( null, 0 );
20214                         return;
20215                 }
20216
20217                 return this._value();
20218         },
20219
20220         values: function( index, newValue ) {
20221                 var vals,
20222                         newValues,
20223                         i;
20224
20225                 if ( arguments.length > 1 ) {
20226                         this.options.values[ index ] = this._trimAlignValue( newValue );
20227                         this._refreshValue();
20228                         this._change( null, index );
20229                         return;
20230                 }
20231
20232                 if ( arguments.length ) {
20233                         if ( $.isArray( arguments[ 0 ] ) ) {
20234                                 vals = this.options.values;
20235                                 newValues = arguments[ 0 ];
20236                                 for ( i = 0; i < vals.length; i += 1 ) {
20237                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
20238                                         this._change( null, i );
20239                                 }
20240                                 this._refreshValue();
20241                         } else {
20242                                 if ( this.options.values && this.options.values.length ) {
20243                                         return this._values( index );
20244                                 } else {
20245                                         return this.value();
20246                                 }
20247                         }
20248                 } else {
20249                         return this._values();
20250                 }
20251         },
20252
20253         _setOption: function( key, value ) {
20254                 var i,
20255                         valsLength = 0;
20256
20257                 if ( $.isArray( this.options.values ) ) {
20258                         valsLength = this.options.values.length;
20259                 }
20260
20261                 $.Widget.prototype._setOption.apply( this, arguments );
20262
20263                 switch ( key ) {
20264                         case "disabled":
20265                                 if ( value ) {
20266                                         this.handles.filter( ".ui-state-focus" ).blur();
20267                                         this.handles.removeClass( "ui-state-hover" );
20268                                         this.handles.attr( "disabled", "disabled" );
20269                                         this.element.addClass( "ui-disabled" );
20270                                 } else {
20271                                         this.handles.removeAttr( "disabled" );
20272                                         this.element.removeClass( "ui-disabled" );
20273                                 }
20274                                 break;
20275                         case "orientation":
20276                                 this._detectOrientation();
20277                                 this.element
20278                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
20279                                         .addClass( "ui-slider-" + this.orientation );
20280                                 this._refreshValue();
20281                                 break;
20282                         case "value":
20283                                 this._animateOff = true;
20284                                 this._refreshValue();
20285                                 this._change( null, 0 );
20286                                 this._animateOff = false;
20287                                 break;
20288                         case "values":
20289                                 this._animateOff = true;
20290                                 this._refreshValue();
20291                                 for ( i = 0; i < valsLength; i += 1 ) {
20292                                         this._change( null, i );
20293                                 }
20294                                 this._animateOff = false;
20295                                 break;
20296                 }
20297         },
20298
20299         //internal value getter
20300         // _value() returns value trimmed by min and max, aligned by step
20301         _value: function() {
20302                 var val = this.options.value;
20303                 val = this._trimAlignValue( val );
20304
20305                 return val;
20306         },
20307
20308         //internal values getter
20309         // _values() returns array of values trimmed by min and max, aligned by step
20310         // _values( index ) returns single value trimmed by min and max, aligned by step
20311         _values: function( index ) {
20312                 var val,
20313                         vals,
20314                         i;
20315
20316                 if ( arguments.length ) {
20317                         val = this.options.values[ index ];
20318                         val = this._trimAlignValue( val );
20319
20320                         return val;
20321                 } else {
20322                         // .slice() creates a copy of the array
20323                         // this copy gets trimmed by min and max and then returned
20324                         vals = this.options.values.slice();
20325                         for ( i = 0; i < vals.length; i+= 1) {
20326                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
20327                         }
20328
20329                         return vals;
20330                 }
20331         },
20332         
20333         // returns the step-aligned value that val is closest to, between (inclusive) min and max
20334         _trimAlignValue: function( val ) {
20335                 if ( val <= this._valueMin() ) {
20336                         return this._valueMin();
20337                 }
20338                 if ( val >= this._valueMax() ) {
20339                         return this._valueMax();
20340                 }
20341                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
20342                         valModStep = (val - this._valueMin()) % step;
20343                         alignValue = val - valModStep;
20344
20345                 if ( Math.abs(valModStep) * 2 >= step ) {
20346                         alignValue += ( valModStep > 0 ) ? step : ( -step );
20347                 }
20348
20349                 // Since JavaScript has problems with large floats, round
20350                 // the final value to 5 digits after the decimal point (see #4124)
20351                 return parseFloat( alignValue.toFixed(5) );
20352         },
20353
20354         _valueMin: function() {
20355                 return this.options.min;
20356         },
20357
20358         _valueMax: function() {
20359                 return this.options.max;
20360         },
20361         
20362         _refreshValue: function() {
20363                 var oRange = this.options.range,
20364                         o = this.options,
20365                         self = this,
20366                         animate = ( !this._animateOff ) ? o.animate : false,
20367                         valPercent,
20368                         _set = {},
20369                         lastValPercent,
20370                         value,
20371                         valueMin,
20372                         valueMax;
20373
20374                 if ( this.options.values && this.options.values.length ) {
20375                         this.handles.each(function( i, j ) {
20376                                 valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
20377                                 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
20378                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
20379                                 if ( self.options.range === true ) {
20380                                         if ( self.orientation === "horizontal" ) {
20381                                                 if ( i === 0 ) {
20382                                                         self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
20383                                                 }
20384                                                 if ( i === 1 ) {
20385                                                         self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
20386                                                 }
20387                                         } else {
20388                                                 if ( i === 0 ) {
20389                                                         self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
20390                                                 }
20391                                                 if ( i === 1 ) {
20392                                                         self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
20393                                                 }
20394                                         }
20395                                 }
20396                                 lastValPercent = valPercent;
20397                         });
20398                 } else {
20399                         value = this.value();
20400                         valueMin = this._valueMin();
20401                         valueMax = this._valueMax();
20402                         valPercent = ( valueMax !== valueMin ) ?
20403                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
20404                                         0;
20405                         _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
20406                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
20407
20408                         if ( oRange === "min" && this.orientation === "horizontal" ) {
20409                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
20410                         }
20411                         if ( oRange === "max" && this.orientation === "horizontal" ) {
20412                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
20413                         }
20414                         if ( oRange === "min" && this.orientation === "vertical" ) {
20415                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
20416                         }
20417                         if ( oRange === "max" && this.orientation === "vertical" ) {
20418                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
20419                         }
20420                 }
20421         }
20422
20423 });
20424
20425 $.extend( $.ui.slider, {
20426         version: "1.8.12"
20427 });
20428
20429 }(jQuery));
20430 /*
20431  * jQuery UI Tabs 1.8.12
20432  *
20433  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
20434  * Dual licensed under the MIT or GPL Version 2 licenses.
20435  * http://jquery.org/license
20436  *
20437  * http://docs.jquery.com/UI/Tabs
20438  *
20439  * Depends:
20440  *      jquery.ui.core.js
20441  *      jquery.ui.widget.js
20442  */
20443 (function( $, undefined ) {
20444
20445 var tabId = 0,
20446         listId = 0;
20447
20448 function getNextTabId() {
20449         return ++tabId;
20450 }
20451
20452 function getNextListId() {
20453         return ++listId;
20454 }
20455
20456 $.widget( "ui.tabs", {
20457         options: {
20458                 add: null,
20459                 ajaxOptions: null,
20460                 cache: false,
20461                 cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
20462                 collapsible: false,
20463                 disable: null,
20464                 disabled: [],
20465                 enable: null,
20466                 event: "click",
20467                 fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
20468                 idPrefix: "ui-tabs-",
20469                 load: null,
20470                 panelTemplate: "<div></div>",
20471                 remove: null,
20472                 select: null,
20473                 show: null,
20474                 spinner: "<em>Loading&#8230;</em>",
20475                 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
20476         },
20477
20478         _create: function() {
20479                 this._tabify( true );
20480         },
20481
20482         _setOption: function( key, value ) {
20483                 if ( key == "selected" ) {
20484                         if (this.options.collapsible && value == this.options.selected ) {
20485                                 return;
20486                         }
20487                         this.select( value );
20488                 } else {
20489                         this.options[ key ] = value;
20490                         this._tabify();
20491                 }
20492         },
20493
20494         _tabId: function( a ) {
20495                 return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
20496                         this.options.idPrefix + getNextTabId();
20497         },
20498
20499         _sanitizeSelector: function( hash ) {
20500                 // we need this because an id may contain a ":"
20501                 return hash.replace( /:/g, "\\:" );
20502         },
20503
20504         _cookie: function() {
20505                 var cookie = this.cookie ||
20506                         ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
20507                 return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
20508         },
20509
20510         _ui: function( tab, panel ) {
20511                 return {
20512                         tab: tab,
20513                         panel: panel,
20514                         index: this.anchors.index( tab )
20515                 };
20516         },
20517
20518         _cleanup: function() {
20519                 // restore all former loading tabs labels
20520                 this.lis.filter( ".ui-state-processing" )
20521                         .removeClass( "ui-state-processing" )
20522                         .find( "span:data(label.tabs)" )
20523                                 .each(function() {
20524                                         var el = $( this );
20525                                         el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
20526                                 });
20527         },
20528
20529         _tabify: function( init ) {
20530                 var self = this,
20531                         o = this.options,
20532                         fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
20533
20534                 this.list = this.element.find( "ol,ul" ).eq( 0 );
20535                 this.lis = $( " > li:has(a[href])", this.list );
20536                 this.anchors = this.lis.map(function() {
20537                         return $( "a", this )[ 0 ];
20538                 });
20539                 this.panels = $( [] );
20540
20541                 this.anchors.each(function( i, a ) {
20542                         var href = $( a ).attr( "href" );
20543                         // For dynamically created HTML that contains a hash as href IE < 8 expands
20544                         // such href to the full page url with hash and then misinterprets tab as ajax.
20545                         // Same consideration applies for an added tab with a fragment identifier
20546                         // since a[href=#fragment-identifier] does unexpectedly not match.
20547                         // Thus normalize href attribute...
20548                         var hrefBase = href.split( "#" )[ 0 ],
20549                                 baseEl;
20550                         if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
20551                                         ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
20552                                 href = a.hash;
20553                                 a.href = href;
20554                         }
20555
20556                         // inline tab
20557                         if ( fragmentId.test( href ) ) {
20558                                 self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
20559                         // remote tab
20560                         // prevent loading the page itself if href is just "#"
20561                         } else if ( href && href !== "#" ) {
20562                                 // required for restore on destroy
20563                                 $.data( a, "href.tabs", href );
20564
20565                                 // TODO until #3808 is fixed strip fragment identifier from url
20566                                 // (IE fails to load from such url)
20567                                 $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
20568
20569                                 var id = self._tabId( a );
20570                                 a.href = "#" + id;
20571                                 var $panel = self.element.find( "#" + id );
20572                                 if ( !$panel.length ) {
20573                                         $panel = $( o.panelTemplate )
20574                                                 .attr( "id", id )
20575                                                 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
20576                                                 .insertAfter( self.panels[ i - 1 ] || self.list );
20577                                         $panel.data( "destroy.tabs", true );
20578                                 }
20579                                 self.panels = self.panels.add( $panel );
20580                         // invalid tab href
20581                         } else {
20582                                 o.disabled.push( i );
20583                         }
20584                 });
20585
20586                 // initialization from scratch
20587                 if ( init ) {
20588                         // attach necessary classes for styling
20589                         this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
20590                         this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
20591                         this.lis.addClass( "ui-state-default ui-corner-top" );
20592                         this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
20593
20594                         // Selected tab
20595                         // use "selected" option or try to retrieve:
20596                         // 1. from fragment identifier in url
20597                         // 2. from cookie
20598                         // 3. from selected class attribute on <li>
20599                         if ( o.selected === undefined ) {
20600                                 if ( location.hash ) {
20601                                         this.anchors.each(function( i, a ) {
20602                                                 if ( a.hash == location.hash ) {
20603                                                         o.selected = i;
20604                                                         return false;
20605                                                 }
20606                                         });
20607                                 }
20608                                 if ( typeof o.selected !== "number" && o.cookie ) {
20609                                         o.selected = parseInt( self._cookie(), 10 );
20610                                 }
20611                                 if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
20612                                         o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
20613                                 }
20614                                 o.selected = o.selected || ( this.lis.length ? 0 : -1 );
20615                         } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
20616                                 o.selected = -1;
20617                         }
20618
20619                         // sanity check - default to first tab...
20620                         o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
20621                                 ? o.selected
20622                                 : 0;
20623
20624                         // Take disabling tabs via class attribute from HTML
20625                         // into account and update option properly.
20626                         // A selected tab cannot become disabled.
20627                         o.disabled = $.unique( o.disabled.concat(
20628                                 $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
20629                                         return self.lis.index( n );
20630                                 })
20631                         ) ).sort();
20632
20633                         if ( $.inArray( o.selected, o.disabled ) != -1 ) {
20634                                 o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
20635                         }
20636
20637                         // highlight selected tab
20638                         this.panels.addClass( "ui-tabs-hide" );
20639                         this.lis.removeClass( "ui-tabs-selected ui-state-active" );
20640                         // check for length avoids error when initializing empty list
20641                         if ( o.selected >= 0 && this.anchors.length ) {
20642                                 self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
20643                                 this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
20644
20645                                 // seems to be expected behavior that the show callback is fired
20646                                 self.element.queue( "tabs", function() {
20647                                         self._trigger( "show", null,
20648                                                 self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
20649                                 });
20650
20651                                 this.load( o.selected );
20652                         }
20653
20654                         // clean up to avoid memory leaks in certain versions of IE 6
20655                         // TODO: namespace this event
20656                         $( window ).bind( "unload", function() {
20657                                 self.lis.add( self.anchors ).unbind( ".tabs" );
20658                                 self.lis = self.anchors = self.panels = null;
20659                         });
20660                 // update selected after add/remove
20661                 } else {
20662                         o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
20663                 }
20664
20665                 // update collapsible
20666                 // TODO: use .toggleClass()
20667                 this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
20668
20669                 // set or update cookie after init and add/remove respectively
20670                 if ( o.cookie ) {
20671                         this._cookie( o.selected, o.cookie );
20672                 }
20673
20674                 // disable tabs
20675                 for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
20676                         $( li )[ $.inArray( i, o.disabled ) != -1 &&
20677                                 // TODO: use .toggleClass()
20678                                 !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
20679                 }
20680
20681                 // reset cache if switching from cached to not cached
20682                 if ( o.cache === false ) {
20683                         this.anchors.removeData( "cache.tabs" );
20684                 }
20685
20686                 // remove all handlers before, tabify may run on existing tabs after add or option change
20687                 this.lis.add( this.anchors ).unbind( ".tabs" );
20688
20689                 if ( o.event !== "mouseover" ) {
20690                         var addState = function( state, el ) {
20691                                 if ( el.is( ":not(.ui-state-disabled)" ) ) {
20692                                         el.addClass( "ui-state-" + state );
20693                                 }
20694                         };
20695                         var removeState = function( state, el ) {
20696                                 el.removeClass( "ui-state-" + state );
20697                         };
20698                         this.lis.bind( "mouseover.tabs" , function() {
20699                                 addState( "hover", $( this ) );
20700                         });
20701                         this.lis.bind( "mouseout.tabs", function() {
20702                                 removeState( "hover", $( this ) );
20703                         });
20704                         this.anchors.bind( "focus.tabs", function() {
20705                                 addState( "focus", $( this ).closest( "li" ) );
20706                         });
20707                         this.anchors.bind( "blur.tabs", function() {
20708                                 removeState( "focus", $( this ).closest( "li" ) );
20709                         });
20710                 }
20711
20712                 // set up animations
20713                 var hideFx, showFx;
20714                 if ( o.fx ) {
20715                         if ( $.isArray( o.fx ) ) {
20716                                 hideFx = o.fx[ 0 ];
20717                                 showFx = o.fx[ 1 ];
20718                         } else {
20719                                 hideFx = showFx = o.fx;
20720                         }
20721                 }
20722
20723                 // Reset certain styles left over from animation
20724                 // and prevent IE's ClearType bug...
20725                 function resetStyle( $el, fx ) {
20726                         $el.css( "display", "" );
20727                         if ( !$.support.opacity && fx.opacity ) {
20728                                 $el[ 0 ].style.removeAttribute( "filter" );
20729                         }
20730                 }
20731
20732                 // Show a tab...
20733                 var showTab = showFx
20734                         ? function( clicked, $show ) {
20735                                 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
20736                                 $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
20737                                         .animate( showFx, showFx.duration || "normal", function() {
20738                                                 resetStyle( $show, showFx );
20739                                                 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
20740                                         });
20741                         }
20742                         : function( clicked, $show ) {
20743                                 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
20744                                 $show.removeClass( "ui-tabs-hide" );
20745                                 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
20746                         };
20747
20748                 // Hide a tab, $show is optional...
20749                 var hideTab = hideFx
20750                         ? function( clicked, $hide ) {
20751                                 $hide.animate( hideFx, hideFx.duration || "normal", function() {
20752                                         self.lis.removeClass( "ui-tabs-selected ui-state-active" );
20753                                         $hide.addClass( "ui-tabs-hide" );
20754                                         resetStyle( $hide, hideFx );
20755                                         self.element.dequeue( "tabs" );
20756                                 });
20757                         }
20758                         : function( clicked, $hide, $show ) {
20759                                 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
20760                                 $hide.addClass( "ui-tabs-hide" );
20761                                 self.element.dequeue( "tabs" );
20762                         };
20763
20764                 // attach tab event handler, unbind to avoid duplicates from former tabifying...
20765                 this.anchors.bind( o.event + ".tabs", function() {
20766                         var el = this,
20767                                 $li = $(el).closest( "li" ),
20768                                 $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
20769                                 $show = self.element.find( self._sanitizeSelector( el.hash ) );
20770
20771                         // If tab is already selected and not collapsible or tab disabled or
20772                         // or is already loading or click callback returns false stop here.
20773                         // Check if click handler returns false last so that it is not executed
20774                         // for a disabled or loading tab!
20775                         if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
20776                                 $li.hasClass( "ui-state-disabled" ) ||
20777                                 $li.hasClass( "ui-state-processing" ) ||
20778                                 self.panels.filter( ":animated" ).length ||
20779                                 self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
20780                                 this.blur();
20781                                 return false;
20782                         }
20783
20784                         o.selected = self.anchors.index( this );
20785
20786                         self.abort();
20787
20788                         // if tab may be closed
20789                         if ( o.collapsible ) {
20790                                 if ( $li.hasClass( "ui-tabs-selected" ) ) {
20791                                         o.selected = -1;
20792
20793                                         if ( o.cookie ) {
20794                                                 self._cookie( o.selected, o.cookie );
20795                                         }
20796
20797                                         self.element.queue( "tabs", function() {
20798                                                 hideTab( el, $hide );
20799                                         }).dequeue( "tabs" );
20800
20801                                         this.blur();
20802                                         return false;
20803                                 } else if ( !$hide.length ) {
20804                                         if ( o.cookie ) {
20805                                                 self._cookie( o.selected, o.cookie );
20806                                         }
20807
20808                                         self.element.queue( "tabs", function() {
20809                                                 showTab( el, $show );
20810                                         });
20811
20812                                         // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
20813                                         self.load( self.anchors.index( this ) );
20814
20815                                         this.blur();
20816                                         return false;
20817                                 }
20818                         }
20819
20820                         if ( o.cookie ) {
20821                                 self._cookie( o.selected, o.cookie );
20822                         }
20823
20824                         // show new tab
20825                         if ( $show.length ) {
20826                                 if ( $hide.length ) {
20827                                         self.element.queue( "tabs", function() {
20828                                                 hideTab( el, $hide );
20829                                         });
20830                                 }
20831                                 self.element.queue( "tabs", function() {
20832                                         showTab( el, $show );
20833                                 });
20834
20835                                 self.load( self.anchors.index( this ) );
20836                         } else {
20837                                 throw "jQuery UI Tabs: Mismatching fragment identifier.";
20838                         }
20839
20840                         // Prevent IE from keeping other link focussed when using the back button
20841                         // and remove dotted border from clicked link. This is controlled via CSS
20842                         // in modern browsers; blur() removes focus from address bar in Firefox
20843                         // which can become a usability and annoying problem with tabs('rotate').
20844                         if ( $.browser.msie ) {
20845                                 this.blur();
20846                         }
20847                 });
20848
20849                 // disable click in any case
20850                 this.anchors.bind( "click.tabs", function(){
20851                         return false;
20852                 });
20853         },
20854
20855     _getIndex: function( index ) {
20856                 // meta-function to give users option to provide a href string instead of a numerical index.
20857                 // also sanitizes numerical indexes to valid values.
20858                 if ( typeof index == "string" ) {
20859                         index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
20860                 }
20861
20862                 return index;
20863         },
20864
20865         destroy: function() {
20866                 var o = this.options;
20867
20868                 this.abort();
20869
20870                 this.element
20871                         .unbind( ".tabs" )
20872                         .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
20873                         .removeData( "tabs" );
20874
20875                 this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
20876
20877                 this.anchors.each(function() {
20878                         var href = $.data( this, "href.tabs" );
20879                         if ( href ) {
20880                                 this.href = href;
20881                         }
20882                         var $this = $( this ).unbind( ".tabs" );
20883                         $.each( [ "href", "load", "cache" ], function( i, prefix ) {
20884                                 $this.removeData( prefix + ".tabs" );
20885                         });
20886                 });
20887
20888                 this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
20889                         if ( $.data( this, "destroy.tabs" ) ) {
20890                                 $( this ).remove();
20891                         } else {
20892                                 $( this ).removeClass([
20893                                         "ui-state-default",
20894                                         "ui-corner-top",
20895                                         "ui-tabs-selected",
20896                                         "ui-state-active",
20897                                         "ui-state-hover",
20898                                         "ui-state-focus",
20899                                         "ui-state-disabled",
20900                                         "ui-tabs-panel",
20901                                         "ui-widget-content",
20902                                         "ui-corner-bottom",
20903                                         "ui-tabs-hide"
20904                                 ].join( " " ) );
20905                         }
20906                 });
20907
20908                 if ( o.cookie ) {
20909                         this._cookie( null, o.cookie );
20910                 }
20911
20912                 return this;
20913         },
20914
20915         add: function( url, label, index ) {
20916                 if ( index === undefined ) {
20917                         index = this.anchors.length;
20918                 }
20919
20920                 var self = this,
20921                         o = this.options,
20922                         $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
20923                         id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
20924
20925                 $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
20926
20927                 // try to find an existing element before creating a new one
20928                 var $panel = self.element.find( "#" + id );
20929                 if ( !$panel.length ) {
20930                         $panel = $( o.panelTemplate )
20931                                 .attr( "id", id )
20932                                 .data( "destroy.tabs", true );
20933                 }
20934                 $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
20935
20936                 if ( index >= this.lis.length ) {
20937                         $li.appendTo( this.list );
20938                         $panel.appendTo( this.list[ 0 ].parentNode );
20939                 } else {
20940                         $li.insertBefore( this.lis[ index ] );
20941                         $panel.insertBefore( this.panels[ index ] );
20942                 }
20943
20944                 o.disabled = $.map( o.disabled, function( n, i ) {
20945                         return n >= index ? ++n : n;
20946                 });
20947
20948                 this._tabify();
20949
20950                 if ( this.anchors.length == 1 ) {
20951                         o.selected = 0;
20952                         $li.addClass( "ui-tabs-selected ui-state-active" );
20953                         $panel.removeClass( "ui-tabs-hide" );
20954                         this.element.queue( "tabs", function() {
20955                                 self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
20956                         });
20957
20958                         this.load( 0 );
20959                 }
20960
20961                 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
20962                 return this;
20963         },
20964
20965         remove: function( index ) {
20966                 index = this._getIndex( index );
20967                 var o = this.options,
20968                         $li = this.lis.eq( index ).remove(),
20969                         $panel = this.panels.eq( index ).remove();
20970
20971                 // If selected tab was removed focus tab to the right or
20972                 // in case the last tab was removed the tab to the left.
20973                 if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
20974                         this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
20975                 }
20976
20977                 o.disabled = $.map(
20978                         $.grep( o.disabled, function(n, i) {
20979                                 return n != index;
20980                         }),
20981                         function( n, i ) {
20982                                 return n >= index ? --n : n;
20983                         });
20984
20985                 this._tabify();
20986
20987                 this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
20988                 return this;
20989         },
20990
20991         enable: function( index ) {
20992                 index = this._getIndex( index );
20993                 var o = this.options;
20994                 if ( $.inArray( index, o.disabled ) == -1 ) {
20995                         return;
20996                 }
20997
20998                 this.lis.eq( index ).removeClass( "ui-state-disabled" );
20999                 o.disabled = $.grep( o.disabled, function( n, i ) {
21000                         return n != index;
21001                 });
21002
21003                 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
21004                 return this;
21005         },
21006
21007         disable: function( index ) {
21008                 index = this._getIndex( index );
21009                 var self = this, o = this.options;
21010                 // cannot disable already selected tab
21011                 if ( index != o.selected ) {
21012                         this.lis.eq( index ).addClass( "ui-state-disabled" );
21013
21014                         o.disabled.push( index );
21015                         o.disabled.sort();
21016
21017                         this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
21018                 }
21019
21020                 return this;
21021         },
21022
21023         select: function( index ) {
21024                 index = this._getIndex( index );
21025                 if ( index == -1 ) {
21026                         if ( this.options.collapsible && this.options.selected != -1 ) {
21027                                 index = this.options.selected;
21028                         } else {
21029                                 return this;
21030                         }
21031                 }
21032                 this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
21033                 return this;
21034         },
21035
21036         load: function( index ) {
21037                 index = this._getIndex( index );
21038                 var self = this,
21039                         o = this.options,
21040                         a = this.anchors.eq( index )[ 0 ],
21041                         url = $.data( a, "load.tabs" );
21042
21043                 this.abort();
21044
21045                 // not remote or from cache
21046                 if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
21047                         this.element.dequeue( "tabs" );
21048                         return;
21049                 }
21050
21051                 // load remote from here on
21052                 this.lis.eq( index ).addClass( "ui-state-processing" );
21053
21054                 if ( o.spinner ) {
21055                         var span = $( "span", a );
21056                         span.data( "label.tabs", span.html() ).html( o.spinner );
21057                 }
21058
21059                 this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
21060                         url: url,
21061                         success: function( r, s ) {
21062                                 self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
21063
21064                                 // take care of tab labels
21065                                 self._cleanup();
21066
21067                                 if ( o.cache ) {
21068                                         $.data( a, "cache.tabs", true );
21069                                 }
21070
21071                                 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
21072                                 try {
21073                                         o.ajaxOptions.success( r, s );
21074                                 }
21075                                 catch ( e ) {}
21076                         },
21077                         error: function( xhr, s, e ) {
21078                                 // take care of tab labels
21079                                 self._cleanup();
21080
21081                                 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
21082                                 try {
21083                                         // Passing index avoid a race condition when this method is
21084                                         // called after the user has selected another tab.
21085                                         // Pass the anchor that initiated this request allows
21086                                         // loadError to manipulate the tab content panel via $(a.hash)
21087                                         o.ajaxOptions.error( xhr, s, index, a );
21088                                 }
21089                                 catch ( e ) {}
21090                         }
21091                 } ) );
21092
21093                 // last, so that load event is fired before show...
21094                 self.element.dequeue( "tabs" );
21095
21096                 return this;
21097         },
21098
21099         abort: function() {
21100                 // stop possibly running animations
21101                 this.element.queue( [] );
21102                 this.panels.stop( false, true );
21103
21104                 // "tabs" queue must not contain more than two elements,
21105                 // which are the callbacks for the latest clicked tab...
21106                 this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
21107
21108                 // terminate pending requests from other tabs
21109                 if ( this.xhr ) {
21110                         this.xhr.abort();
21111                         delete this.xhr;
21112                 }
21113
21114                 // take care of tab labels
21115                 this._cleanup();
21116                 return this;
21117         },
21118
21119         url: function( index, url ) {
21120                 this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
21121                 return this;
21122         },
21123
21124         length: function() {
21125                 return this.anchors.length;
21126         }
21127 });
21128
21129 $.extend( $.ui.tabs, {
21130         version: "1.8.12"
21131 });
21132
21133 /*
21134  * Tabs Extensions
21135  */
21136
21137 /*
21138  * Rotate
21139  */
21140 $.extend( $.ui.tabs.prototype, {
21141         rotation: null,
21142         rotate: function( ms, continuing ) {
21143                 var self = this,
21144                         o = this.options;
21145
21146                 var rotate = self._rotate || ( self._rotate = function( e ) {
21147                         clearTimeout( self.rotation );
21148                         self.rotation = setTimeout(function() {
21149                                 var t = o.selected;
21150                                 self.select( ++t < self.anchors.length ? t : 0 );
21151                         }, ms );
21152                         
21153                         if ( e ) {
21154                                 e.stopPropagation();
21155                         }
21156                 });
21157
21158                 var stop = self._unrotate || ( self._unrotate = !continuing
21159                         ? function(e) {
21160                                 if (e.clientX) { // in case of a true click
21161                                         self.rotate(null);
21162                                 }
21163                         }
21164                         : function( e ) {
21165                                 t = o.selected;
21166                                 rotate();
21167                         });
21168
21169                 // start rotation
21170                 if ( ms ) {
21171                         this.element.bind( "tabsshow", rotate );
21172                         this.anchors.bind( o.event + ".tabs", stop );
21173                         rotate();
21174                 // stop rotation
21175                 } else {
21176                         clearTimeout( self.rotation );
21177                         this.element.unbind( "tabsshow", rotate );
21178                         this.anchors.unbind( o.event + ".tabs", stop );
21179                         delete this._rotate;
21180                         delete this._unrotate;
21181                 }
21182
21183                 return this;
21184         }
21185 });
21186
21187 })( jQuery );
21188 /*
21189  * jQuery Tooltip plugin 1.3
21190  *
21191  * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
21192  * http://docs.jquery.com/Plugins/Tooltip
21193  *
21194  * Copyright (c) 2006 - 2008 Jörn Zaefferer
21195  *
21196  * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
21197  * 
21198  * Dual licensed under the MIT and GPL licenses:
21199  *   http://www.opensource.org/licenses/mit-license.php
21200  *   http://www.gnu.org/licenses/gpl.html
21201  */
21202  
21203 ;(function($) {
21204         
21205                 // the tooltip element
21206         var helper = {},
21207                 // the current tooltipped element
21208                 current,
21209                 // the title of the current element, used for restoring
21210                 title,
21211                 // timeout id for delayed tooltips
21212                 tID,
21213                 // IE 5.5 or 6
21214                 IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
21215                 // flag for mouse tracking
21216                 track = false;
21217         
21218         $.tooltip = {
21219                 blocked: false,
21220                 defaults: {
21221                         delay: 200,
21222                         fade: false,
21223                         showURL: true,
21224                         extraClass: "",
21225                         top: 15,
21226                         left: 15,
21227                         id: "tooltip"
21228                 },
21229                 block: function() {
21230                         $.tooltip.blocked = !$.tooltip.blocked;
21231                 }
21232         };
21233         
21234         $.fn.extend({
21235                 tooltip: function(settings) {
21236                         settings = $.extend({}, $.tooltip.defaults, settings);
21237                         createHelper(settings);
21238                         return this.each(function() {
21239                                         $.data(this, "tooltip", settings);
21240                                         this.tOpacity = helper.parent.css("opacity");
21241                                         // copy tooltip into its own expando and remove the title
21242                                         this.tooltipText = this.title;
21243                                         $(this).removeAttr("title");
21244                                         // also remove alt attribute to prevent default tooltip in IE
21245                                         this.alt = "";
21246                                 })
21247                                 .mouseover(save)
21248                                 .mouseout(hide)
21249                                 .click(hide);
21250                 },
21251                 fixPNG: IE ? function() {
21252                         return this.each(function () {
21253                                 var image = $(this).css('backgroundImage');
21254                                 if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
21255                                         image = RegExp.$1;
21256                                         $(this).css({
21257                                                 'backgroundImage': 'none',
21258                                                 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
21259                                         }).each(function () {
21260                                                 var position = $(this).css('position');
21261                                                 if (position != 'absolute' && position != 'relative')
21262                                                         $(this).css('position', 'relative');
21263                                         });
21264                                 }
21265                         });
21266                 } : function() { return this; },
21267                 unfixPNG: IE ? function() {
21268                         return this.each(function () {
21269                                 $(this).css({'filter': '', backgroundImage: ''});
21270                         });
21271                 } : function() { return this; },
21272                 hideWhenEmpty: function() {
21273                         return this.each(function() {
21274                                 $(this)[ $(this).html() ? "show" : "hide" ]();
21275                         });
21276                 },
21277                 url: function() {
21278                         return this.attr('href') || this.attr('src');
21279                 }
21280         });
21281         
21282         function createHelper(settings) {
21283                 // there can be only one tooltip helper
21284                 if( helper.parent )
21285                         return;
21286                 // create the helper, h3 for title, div for url
21287                 helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>')
21288                         // add to document
21289                         .appendTo(document.body)
21290                         // hide it at first
21291                         .hide();
21292                         
21293                 // apply bgiframe if available
21294                 if ( $.fn.bgiframe )
21295                         helper.parent.bgiframe();
21296                 
21297                 // save references to title and url elements
21298                 helper.title = $('h3', helper.parent);
21299                 helper.body = $('div.body', helper.parent);
21300                 helper.url = $('div.url', helper.parent);
21301         }
21302         
21303         function settings(element) {
21304                 return $.data(element, "tooltip");
21305         }
21306         
21307         // main event handler to start showing tooltips
21308         function handle(event) {
21309                 // show helper, either with timeout or on instant
21310                 if( settings(this).delay )
21311                         tID = setTimeout(show, settings(this).delay);
21312                 else
21313                         show();
21314                 
21315                 // if selected, update the helper position when the mouse moves
21316                 track = !!settings(this).track;
21317                 $(document.body).bind('mousemove', update);
21318                         
21319                 // update at least once
21320                 update(event);
21321         }
21322         
21323         // save elements title before the tooltip is displayed
21324         function save() {
21325                 // if this is the current source, or it has no title (occurs with click event), stop
21326                 if ( $.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler) )
21327                         return;
21328
21329                 // save current
21330                 current = this;
21331                 title = this.tooltipText;
21332                 
21333                 if ( settings(this).bodyHandler ) {
21334                         helper.title.hide();
21335                         var bodyContent = settings(this).bodyHandler.call(this);
21336                         if (bodyContent.nodeType || bodyContent.jquery) {
21337                                 helper.body.empty().append(bodyContent)
21338                         } else {
21339                                 helper.body.html( bodyContent );
21340                         }
21341                         helper.body.show();
21342                 } else if ( settings(this).showBody ) {
21343                         var parts = title.split(settings(this).showBody);
21344                         helper.title.html(parts.shift()).show();
21345                         helper.body.empty();
21346                         for(var i = 0, part; (part = parts[i]); i++) {
21347                                 if(i > 0)
21348                                         helper.body.append("<br/>");
21349                                 helper.body.append(part);
21350                         }
21351                         helper.body.hideWhenEmpty();
21352                 } else {
21353                         helper.title.html(title).show();
21354                         helper.body.hide();
21355                 }
21356                 
21357                 // if element has href or src, add and show it, otherwise hide it
21358                 if( settings(this).showURL && $(this).url() )
21359                         helper.url.html( $(this).url().replace('http://', '') ).show();
21360                 else 
21361                         helper.url.hide();
21362                 
21363                 // add an optional class for this tip
21364                 helper.parent.addClass(settings(this).extraClass);
21365
21366                 // fix PNG background for IE
21367                 if (settings(this).fixPNG )
21368                         helper.parent.fixPNG();
21369                         
21370                 handle.apply(this, arguments);
21371         }
21372         
21373         // delete timeout and show helper
21374         function show() {
21375                 tID = null;
21376                 if ((!IE || !$.fn.bgiframe) && settings(current).fade) {
21377                         if (helper.parent.is(":animated"))
21378                                 helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity);
21379                         else
21380                                 helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);
21381                 } else {
21382                         helper.parent.show();
21383                 }
21384                 update();
21385         }
21386         
21387         /**
21388          * callback for mousemove
21389          * updates the helper position
21390          * removes itself when no current element
21391          */
21392         function update(event)  {
21393                 if($.tooltip.blocked)
21394                         return;
21395                 
21396                 if (event && event.target.tagName == "OPTION") {
21397                         return;
21398                 }
21399                 
21400                 // stop updating when tracking is disabled and the tooltip is visible
21401                 if ( !track && helper.parent.is(":visible")) {
21402                         $(document.body).unbind('mousemove', update)
21403                 }
21404                 
21405                 // if no current element is available, remove this listener
21406                 if( current == null ) {
21407                         $(document.body).unbind('mousemove', update);
21408                         return; 
21409                 }
21410                 
21411                 // remove position helper classes
21412                 helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");
21413                 
21414                 var left = helper.parent[0].offsetLeft;
21415                 var top = helper.parent[0].offsetTop;
21416                 if (event) {
21417                         // position the helper 15 pixel to bottom right, starting from mouse position
21418                         left = event.pageX + settings(current).left;
21419                         top = event.pageY + settings(current).top;
21420                         var right='auto';
21421                         if (settings(current).positionLeft) {
21422                                 right = $(window).width() - left;
21423                                 left = 'auto';
21424                         }
21425                         helper.parent.css({
21426                                 left: left,
21427                                 right: right,
21428                                 top: top
21429                         });
21430                 }
21431                 
21432                 var v = viewport(),
21433                         h = helper.parent[0];
21434                 // check horizontal position
21435                 if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {
21436                         left -= h.offsetWidth + 20 + settings(current).left;
21437                         helper.parent.css({left: left + 'px'}).addClass("viewport-right");
21438                 }
21439                 // check vertical position
21440                 if (v.y + v.cy < h.offsetTop + h.offsetHeight) {
21441                         top -= h.offsetHeight + 20 + settings(current).top;
21442                         helper.parent.css({top: top + 'px'}).addClass("viewport-bottom");
21443                 }
21444         }
21445         
21446         function viewport() {
21447                 return {
21448                         x: $(window).scrollLeft(),
21449                         y: $(window).scrollTop(),
21450                         cx: $(window).width(),
21451                         cy: $(window).height()
21452                 };
21453         }
21454         
21455         // hide helper and restore added classes and the title
21456         function hide(event) {
21457                 if($.tooltip.blocked)
21458                         return;
21459                 // clear timeout if possible
21460                 if(tID)
21461                         clearTimeout(tID);
21462                 // no more current element
21463                 current = null;
21464                 
21465                 var tsettings = settings(this);
21466                 function complete() {
21467                         helper.parent.removeClass( tsettings.extraClass ).hide().css("opacity", "");
21468                 }
21469                 if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
21470                         if (helper.parent.is(':animated'))
21471                                 helper.parent.stop().fadeTo(tsettings.fade, 0, complete);
21472                         else
21473                                 helper.parent.stop().fadeOut(tsettings.fade, complete);
21474                 } else
21475                         complete();
21476                 
21477                 if( settings(this).fixPNG )
21478                         helper.parent.unfixPNG();
21479         }
21480         
21481 })(jQuery);
21482 /*!
21483 Math.uuid.js (v1.4)
21484 http://www.broofa.com
21485 mailto:robert@broofa.com
21486
21487 Copyright (c) 2010 Robert Kieffer
21488 Dual licensed under the MIT and GPL licenses.
21489 */
21490
21491 /*
21492  * Generate a random uuid.
21493  *
21494  * USAGE: Math.uuid(length, radix)
21495  *   length - the desired number of characters
21496  *   radix  - the number of allowable values for each character.
21497  *
21498  * EXAMPLES:
21499  *   // No arguments  - returns RFC4122, version 4 ID
21500  *   >>> Math.uuid()
21501  *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
21502  *
21503  *   // One argument - returns ID of the specified length
21504  *   >>> Math.uuid(15)     // 15 character ID (default base=62)
21505  *   "VcydxgltxrVZSTV"
21506  *
21507  *   // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
21508  *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
21509  *   "01001010"
21510  *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
21511  *   "47473046"
21512  *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
21513  *   "098F4D35"
21514  */
21515 (function() {
21516   // Private array of chars to use
21517   var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
21518
21519   Math.uuid = function (len, radix) {
21520     var chars = CHARS, uuid = [], i;
21521     radix = radix || chars.length;
21522
21523     if (len) {
21524       // Compact form
21525       for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
21526     } else {
21527       // rfc4122, version 4 form
21528       var r;
21529
21530       // rfc4122 requires these characters
21531       uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
21532       uuid[14] = '4';
21533
21534       // Fill in random data.  At i==19 set the high bits of clock sequence as
21535       // per rfc4122, sec. 4.1.5
21536       for (i = 0; i < 36; i++) {
21537         if (!uuid[i]) {
21538           r = 0 | Math.random()*16;
21539           uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
21540         }
21541       }
21542     }
21543
21544     return uuid.join('');
21545   };
21546
21547   // A more performant, but slightly bulkier, RFC4122v4 solution.  We boost performance
21548   // by minimizing calls to random()
21549   Math.uuidFast = function() {
21550     var chars = CHARS, uuid = new Array(36), rnd=0, r;
21551     for (var i = 0; i < 36; i++) {
21552       if (i==8 || i==13 ||  i==18 || i==23) {
21553         uuid[i] = '-';
21554       } else if (i==14) {
21555         uuid[i] = '4';
21556       } else {
21557         if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0;
21558         r = rnd & 0xf;
21559         rnd = rnd >> 4;
21560         uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
21561       }
21562     }
21563     return uuid.join('');
21564   };
21565
21566   // A more compact, but less performant, RFC4122v4 solution:
21567   Math.uuidCompact = function() {
21568     return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
21569       var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
21570       return v.toString(16);
21571     });
21572   };
21573 })();
21574 // jXHR.js (JSON-P XHR)\r
21575 // v0.1 (c) Kyle Simpson\r
21576 // MIT License\r
21577 \r
21578 (function(global){\r
21579         var SETTIMEOUT = global.setTimeout, // for better compression\r
21580                 doc = global.document,\r
21581                 callback_counter = 0;\r
21582                 \r
21583         global.jXHR = function() {\r
21584                 var script_url,\r
21585                         script_loaded,\r
21586                         jsonp_callback,\r
21587                         scriptElem,\r
21588                         publicAPI = null;\r
21589                         \r
21590                 function removeScript() { try { scriptElem.parentNode.removeChild(scriptElem); } catch (err) { } }\r
21591                         \r
21592                 function reset() {\r
21593                         script_loaded = false;\r
21594                         script_url = "";\r
21595                         removeScript();\r
21596                         scriptElem = null;\r
21597                         fireReadyStateChange(0);\r
21598                 }\r
21599                 \r
21600                 function ThrowError(msg) {\r
21601                         try { publicAPI.onerror.call(publicAPI,msg,script_url); } catch (err) { throw new Error(msg); }\r
21602                 }\r
21603 \r
21604                 function handleScriptLoad() {\r
21605                         if ((this.readyState && this.readyState!=="complete" && this.readyState!=="loaded") || script_loaded) { return; }\r
21606                         this.onload = this.onreadystatechange = null; // prevent memory leak\r
21607                         script_loaded = true;\r
21608                         if (publicAPI.readyState !== 4) ThrowError("Script failed to load ["+script_url+"].");\r
21609                         removeScript();\r
21610                 }\r
21611                 \r
21612                 function fireReadyStateChange(rs,args) {\r
21613                         args = args || [];\r
21614                         publicAPI.readyState = rs;\r
21615                         if (typeof publicAPI.onreadystatechange === "function") publicAPI.onreadystatechange.apply(publicAPI,args);\r
21616                 }\r
21617                                 \r
21618                 publicAPI = {\r
21619                         onerror:null,\r
21620                         onreadystatechange:null,\r
21621                         readyState:0,\r
21622                         open:function(method,url){\r
21623                                 reset();\r
21624                                 internal_callback = "cb"+(callback_counter++);\r
21625                                 (function(icb){\r
21626                                         global.jXHR[icb] = function() {\r
21627                                                 try { fireReadyStateChange.call(publicAPI,4,arguments); } \r
21628                                                 catch(err) { \r
21629                                                         publicAPI.readyState = -1;\r
21630                                                         ThrowError("Script failed to run ["+script_url+"]."); \r
21631                                                 }\r
21632                                                 global.jXHR[icb] = null;\r
21633                                         };\r
21634                                 })(internal_callback);\r
21635                                 script_url = url.replace(/=\?/,"=jXHR."+internal_callback);\r
21636                                 fireReadyStateChange(1);\r
21637                         },\r
21638                         send:function(){\r
21639                                 SETTIMEOUT(function(){\r
21640                                         scriptElem = doc.createElement("script");\r
21641                                         scriptElem.setAttribute("type","text/javascript");\r
21642                                         scriptElem.onload = scriptElem.onreadystatechange = function(){handleScriptLoad.call(scriptElem);};\r
21643                                         scriptElem.setAttribute("src",script_url);\r
21644                                         doc.getElementsByTagName("head")[0].appendChild(scriptElem);\r
21645                                 },0);\r
21646                                 fireReadyStateChange(2);\r
21647                         },\r
21648                         setRequestHeader:function(){}, // noop\r
21649                         getResponseHeader:function(){return "";}, // basically noop\r
21650                         getAllResponseHeaders:function(){return [];} // ditto\r
21651                 };\r
21652 \r
21653                 reset();\r
21654                 \r
21655                 return publicAPI;\r
21656         };\r
21657 })(window);//////////////////////////////////////////////////////////////////////////////
21658 //                                                                          //
21659 // Wii Opera SDK - 3D Math Class v2.7.22 2008-12-14                         //
21660 // (c) 2007-2008 Daniel Gump. All Rights Reserved.                          //
21661 // http://wiioperasdk.com, http://hullbreachonline.com                      //
21662 // hullbreach@hullbreachonline.com                                          //
21663 //                                                                          //
21664 //  Wii is a trademark of Nintendo Co., Ltd.                                //
21665 //  Opera is a trademark of Opera, ASA.                                     //
21666 //  This software package is not associated with either company             //
21667 //  but was created to support users of both.  Its alternative name         //
21668 //  when supporting other products is the HULLBREACH SDK.                   //
21669 //                                                                          //
21670 //  Redistribution and use in source and binary forms, with or without      //
21671 //  modification, are permitted provided that the following conditions      //
21672 //  are met:                                                                //
21673 //    * Redistributions of source code must retain the above copyright      //
21674 //      notice, this list of conditions and the following disclaimer.       //
21675 //    * Redistributions in binary form must reproduce the above copyright   //
21676 //      notice, this list of conditions and the following disclaimer in     //
21677 //      the documentation and/or other materials provided with the          //
21678 //      distribution.                                                       //
21679 //    * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names //
21680 //      of its contributors may be used to endorse or promote products      //
21681 //      derived from this software without specific prior written           //
21682 //      permission.                                                         //
21683 //    * If the explicit purpose of the software is not to support the       //
21684 //      Nintendo Wii or the Opera Web browser, then the names of such must  //
21685 //      not be used in any derived product. The name shall be the           //
21686 //      HULLBREACH SDK with a reference link to http://hullbreachonline.    //
21687 //                                                                          //
21688 //  THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   //
21689 //  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          //
21690 //  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  //
21691 //  DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     //
21692 //  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      //
21693 //  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      //
21694 //  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      //
21695 //  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     //
21696 //  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   //
21697 //  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      //
21698 //  POSSIBILITY OF SUCH DAMAGE.                                             //
21699 //////////////////////////////////////////////////////////////////////////////
21700
21701 function ThreeD(){
21702         POLYMESH = new Array();
21703
21704         CENTERX = 400; CENTERY = 240;
21705         LIGHTX = -1000; LIGHTY = -1000; LIGHTZ = -1000;
21706         ORIGINX = 0; ORIGINY = 0; ORIGINZ = 0;
21707         ANGLEX = 0; ANGLEY = 0; ANGLEZ = 0;
21708 }
21709
21710 ThreeD.prototype.setPoints = function(Points){
21711         POLYMESH = [];
21712         for(var value=Points.length;--value>=0;) POLYMESH[value] = Points[value].slice();
21713 }
21714 ThreeD.prototype.loadMesh = function(array){
21715         if(POLYMESH = array.split(";")) for(i=POLYMESH.length;--i>=0;) POLYMESH[i] = POLYMESH[i].split(",");
21716 }
21717 ThreeD.prototype.getPoints = function(){ return POLYMESH; }
21718
21719 ThreeD.prototype.setCenter = function(x,y){ CENTERX = x|0; CENTERY = y|0; }
21720 ThreeD.prototype.setLight = function(x,y,z){ LIGHTX = x|0; LIGHTY = y|0; LIGHTZ = z|0; }
21721
21722 ThreeD.prototype.explode = function(z){
21723         var x1, y1, z1, x2, y2, z2;
21724         var normali, normalj, normalk, magNormal;
21725
21726         for(var value=POLYMESH.length;--value>=0;){
21727                 x1 = POLYMESH[value][3]-POLYMESH[value][0]; y1 = POLYMESH[value][4]-POLYMESH[value][1]; z1 = POLYMESH[value][5]-POLYMESH[value][2]; 
21728                 x2 = POLYMESH[value][6]-POLYMESH[value][0]; y2 = POLYMESH[value][7]-POLYMESH[value][1]; z2 = POLYMESH[value][8]-POLYMESH[value][2]; 
21729
21730                 normali = y2*z1-y1*z2; normalj = x1*z2-x2*z1; normalk = x2*y1-x1*y2;
21731                 magNormal = z/Math.sqrt(normali*normali+normalj*normalj+normalk*normalk);
21732
21733                 var movex = -normali*magNormal|0;
21734                 var movey = -normalj*magNormal|0;
21735                 var movez = -normalk*magNormal|0;
21736
21737                 POLYMESH[value][0] += movex; POLYMESH[value][1] += movey; POLYMESH[value][2] += movez;
21738                 POLYMESH[value][3] += movex; POLYMESH[value][4] += movey; POLYMESH[value][5] += movez;
21739                 POLYMESH[value][6] += movex; POLYMESH[value][7] += movey; POLYMESH[value][8] += movez;
21740         }
21741 }
21742 ThreeD.prototype.normalMap = function(normalMap){
21743         var x1, y1, z1, x2, y2, z2;
21744         var normali, normalj, normalk, magNormal;
21745
21746         for(var value=POLYMESH.length;--value>=0;){
21747                 x1 = POLYMESH[value][3]-POLYMESH[value][0]; y1 = POLYMESH[value][4]-POLYMESH[value][1]; z1 = POLYMESH[value][5]-POLYMESH[value][2]; 
21748                 x2 = POLYMESH[value][6]-POLYMESH[value][0]; y2 = POLYMESH[value][7]-POLYMESH[value][1]; z2 = POLYMESH[value][8]-POLYMESH[value][2]; 
21749
21750                 normali = y2*z1-y1*z2; normalj = x1*z2-x2*z1; normalk = x2*y1-x1*y2;
21751                 normal = 1/Math.sqrt(normali*normali+normalj*normalj+normalk*normalk);
21752                 
21753                 for(index2=0; index2<4; index2++){
21754                         for(index=0; index<=index2; index++){
21755                                 magNormal = normalMap[index][index2]*normal|0;
21756
21757                                 var movex = -normali*magNormal;
21758                                 var movey = -normalj*magNormal;
21759                                 var movez = -normalk*magNormal;
21760                                 
21761                                 POLYMESH[POLYMESH.length] = new Array(POLYMESH[value][0]+movex,POLYMESH[value][1]+movey,POLYMESH[value][2]+movez,
21762                                                         POLYMESH[value][3]+movex,POLYMESH[value][4]+movey,POLYMESH[value][7]+movez,
21763                                                         POLYMESH[value][6]+movex,POLYMESH[value][7]+movey,POLYMESH[value][8]+movez,
21764                                                         POLYMESH[value][9],POLYMESH[value][10],POLYMESH[value][11],
21765                                                         POLYMESH[value][12],POLYMESH[value][13], true, index, index2);
21766                         }
21767                 }
21768         }
21769 }
21770 ThreeD.prototype.move = function(x,y,z){
21771         for(var value=POLYMESH.length;--value>=0;)
21772                 for(var point=-1;++point<3;){
21773                         POLYMESH[value][point*3+2] += z;
21774                         POLYMESH[value][point*3+1] += y;
21775                         POLYMESH[value][point*3] += x;
21776                 }
21777 }
21778 ThreeD.prototype.rotate = function(anglex,angley,anglez){
21779         var cosx = Math.cos(anglex*0.01745329); var sinx = Math.sin(anglex*0.01745329);
21780         var cosy = Math.cos(angley*0.01745329); var siny = Math.sin(angley*0.01745329);
21781         var cosz = Math.cos(anglez*0.01745329); var sinz = Math.sin(anglez*0.01745329);
21782
21783         for(var value=POLYMESH.length;--value>=0;)
21784                 for(var point=-1;++point<3;){
21785                         var tempz = sinx*POLYMESH[value][point*3+1]+cosx*POLYMESH[value][point*3+2];
21786                         var tempy = cosx*POLYMESH[value][point*3+1]-sinx*POLYMESH[value][point*3+2];
21787                         var tempx = cosy*POLYMESH[value][point*3]+siny*tempz;
21788                         POLYMESH[value][point*3+2] = cosy*tempz-siny*POLYMESH[value][point*3];
21789                         POLYMESH[value][point*3+1] = sinz*tempx+cosz*tempy;
21790                         POLYMESH[value][point*3] = cosz*tempx-sinz*tempy;
21791                 }
21792 }
21793 ThreeD.prototype.scale = function(scalex,scaley,scalez){
21794         for(var value=POLYMESH.length;--value>=0;)
21795                 for(var point=-1;++point<3;){
21796                         POLYMESH[value][point*3+2] *= scalex;
21797                         POLYMESH[value][point*3+1] *= scaley;
21798                         POLYMESH[value][point*3] *= scalez;
21799                 }
21800 }
21801
21802 ThreeD.prototype.backface = function(){
21803         for(var value=POLYMESH.length, newvalue=0, TempPOLYMESH = [];--value>=0;)
21804                 if((POLYMESH[value][3]-POLYMESH[value][0])*(POLYMESH[value][7]-POLYMESH[value][1])-(POLYMESH[value][6]-POLYMESH[value][0])*(POLYMESH[value][4]-POLYMESH[value][1])>0){
21805                         TempPOLYMESH[newvalue++] = POLYMESH[value].slice();
21806                 }
21807         POLYMESH = TempPOLYMESH;
21808 }
21809 ThreeD.prototype.zSort = function(){ POLYMESH.sort(function(b,a){return b[2]+b[5]+b[8]-a[2]-a[5]-a[8]}); }
21810
21811 ThreeD.prototype.fade = function(bright){
21812         for(var value=POLYMESH.length;--value>=0;) POLYMESH[value][13] += bright;
21813 }
21814 ThreeD.prototype.shade = function(){
21815         var x1, y1, z1, x2, y2, z2;
21816         var normali, normalj, normalk, magNormal;
21817         var lighti, lightj, lightk, magLight;
21818
21819         for(var value=POLYMESH.length;--value>=0;){
21820                 x1 = POLYMESH[value][3]-POLYMESH[value][0]; y1 = POLYMESH[value][4]-POLYMESH[value][1]; z1 = POLYMESH[value][5]-POLYMESH[value][2]; 
21821                 x2 = POLYMESH[value][6]-POLYMESH[value][0]; y2 = POLYMESH[value][7]-POLYMESH[value][1]; z2 = POLYMESH[value][8]-POLYMESH[value][2]; 
21822
21823                 normali = y1*z2-y2*z1; normalj = x2*z1-x1*z2; normalk = x1*y2-x2*y1;
21824
21825                 lighti = LIGHTX-(POLYMESH[value][0]+POLYMESH[value][3]+POLYMESH[value][6])*0.33333333333333333;
21826                 lightj = LIGHTY-(POLYMESH[value][1]+POLYMESH[value][4]+POLYMESH[value][7])*0.33333333333333333;
21827                 lightk = LIGHTZ-(POLYMESH[value][2]+POLYMESH[value][5]+POLYMESH[value][8])*0.33333333333333333;
21828
21829                 POLYMESH[value][13] = 2*(normali*lighti + normalj*lightj + normalk*lightk)/Math.sqrt((normali*normali+normalj*normalj+normalk*normalk)*(lighti*lighti+lightj*lightj+lightk*lightk))-1;
21830         }
21831 }
21832 ThreeD.prototype.reColor = function(r,g,b){
21833         r=r>255?255:(r<0?0:r|0);
21834         g=g>255?255:(g<0?0:g|0);
21835         b=b>255?255:(b<0?0:b|0);
21836         for(var value=POLYMESH.length;--value>=0;){
21837                 POLYMESH[value][9]=r;
21838                 POLYMESH[value][10]=g;
21839                 POLYMESH[value][11]=b;
21840         }
21841 }
21842 ThreeD.prototype.shadow = function(){
21843         rayorigins = []; 
21844         raynormals = [];
21845         edge1 = [];
21846         edge2 = [];
21847
21848         for(var value=0, normali, normalj, normalk, magNormal;value<POLYMESH.length;value++){
21849                 edge1[value] = new Array(POLYMESH[value][3]-POLYMESH[value][0], POLYMESH[value][4]-POLYMESH[value][1], POLYMESH[value][5]-POLYMESH[value][2]);
21850                 edge2[value] = new Array(POLYMESH[value][6]-POLYMESH[value][0], POLYMESH[value][7]-POLYMESH[value][1], POLYMESH[value][8]-POLYMESH[value][2]);
21851
21852                 rayorigins[value] = new Array((POLYMESH[value][0]+POLYMESH[value][3]+POLYMESH[value][6])*0.33333333333333333, (POLYMESH[value][1]+POLYMESH[value][4]+POLYMESH[value][7])*0.33333333333333333, (POLYMESH[value][2]+POLYMESH[value][5]+POLYMESH[value][8])*0.33333333333333333);
21853
21854                 normali = LIGHTX-rayorigins[value][0];
21855                 normalj = LIGHTY-rayorigins[value][1];
21856                 normalk = LIGHTZ-rayorigins[value][2];
21857                 magNormal = 1/Math.sqrt(normali*normali+normalj*normalj+normalk*normalk);
21858                 raynormals[value] = new Array(normali*magNormal, normalj*magNormal, normalk*magNormal);
21859         }
21860
21861         for(var value=POLYMESH.length;--value>=0;){
21862                 for(var value2=POLYMESH.length;--value2>=0;){
21863                         if(value2!=value){
21864                                 var pvecti = raynormals[value][1]*edge2[value2][2]-edge2[value2][1]*raynormals[value][2];
21865                                 var pvectj = edge2[value2][0]*raynormals[value][2]-raynormals[value][0]*edge2[value2][2];
21866                                 var pvectk = raynormals[value][0]*edge2[value2][1]-edge2[value2][0]*raynormals[value][1];
21867
21868                                 if((det = edge1[value2][0]*pvecti+edge1[value2][1]*pvectj+edge1[value2][2]*pvectk)<0){
21869                                         det=1/det;
21870
21871                                         var tvecti = rayorigins[value][0]-POLYMESH[value2][0];
21872                                         var tvectj = rayorigins[value][1]-POLYMESH[value2][1];
21873                                         var tvectk = rayorigins[value][2]-POLYMESH[value2][2];
21874
21875                                         if((u = (pvecti*tvecti+pvectj*tvectj+pvectk*tvectk) * det)>=0 && u<=1){
21876                                                 if((v = (raynormals[value][0]*(tvectj*edge1[value2][2]-edge1[value2][1]*tvectk)+raynormals[value][1]*(edge1[value2][0]*tvectk-tvecti*edge1[value2][2])+raynormals[value][2]*(tvecti*edge1[value2][1]-edge1[value2][0]*tvectj)) * det)>=0 && u+v<=1){
21877                                                         POLYMESH[value][13] -=.5;
21878                                                         break;
21879                                                 }
21880                                         }
21881                                 }
21882                                 
21883                         }
21884                 }
21885         }
21886 }
21887
21888 ThreeD.prototype.getTranslation = function(){
21889         for(var value=POLYMESH.length,newvalue=0,TransPOLYMESH = [];--value>=0;){
21890                 var POLYMESH2=5000/(5000-POLYMESH[value][2]), POLYMESH5=5000/(5000-POLYMESH[value][5]), POLYMESH8=5000/(5000-POLYMESH[value][8]);
21891                 TransPOLYMESH[newvalue++] = new Array((CENTERX+POLYMESH[value][0]*POLYMESH2),(CENTERY+POLYMESH[value][1]*POLYMESH2),
21892                                                                         (CENTERX+POLYMESH[value][3]*POLYMESH5),(CENTERY+POLYMESH[value][4]*POLYMESH5),
21893                                                                         (CENTERX+POLYMESH[value][6]*POLYMESH8),(CENTERY+POLYMESH[value][7]*POLYMESH8),
21894                                                                         POLYMESH[value][9]|0,POLYMESH[value][10]|0,POLYMESH[value][11]|0,POLYMESH[value][12]|0,POLYMESH[value][13]);
21895         }
21896         return TransPOLYMESH;
21897 }
21898
21899 ThreeDee = new ThreeD();/**
21900  * @author mrdoob / http://mrdoob.com/
21901  */
21902
21903 var THREE = THREE || { REVISION: '51' };
21904
21905 if ( self.console === undefined ) {
21906
21907     self.console = {
21908
21909         info: function () {},
21910         log: function () {},
21911         debug: function () {},
21912         warn: function () {},
21913         error: function () {}
21914
21915     };
21916
21917 }
21918
21919 if ( self.Int32Array === undefined ) {
21920
21921     self.Int32Array = Array;
21922     self.Float32Array = Array;
21923
21924 }
21925
21926 // Shims for "startsWith", "endsWith", and "trim" for browsers where this is not yet implemented
21927 // not sure we should have this, or at least not have it here
21928
21929 // http://stackoverflow.com/questions/646628/javascript-startswith
21930 // http://stackoverflow.com/questions/498970/how-do-i-trim-a-string-in-javascript
21931 // http://wiki.ecmascript.org/doku.php?id=harmony%3astring_extras
21932
21933 if ( String.prototype.startsWith === undefined ) {
21934
21935     String.prototype.startsWith = function ( str ) {
21936
21937         return this.slice( 0, str.length ) === str;
21938
21939     };
21940
21941 }
21942
21943 if ( String.prototype.endsWith === undefined ) {
21944
21945     String.prototype.endsWith = function ( str ) {
21946
21947         var t = String( str );
21948         var index = this.lastIndexOf( t );
21949         return index >= 0 && index === this.length - t.length;
21950
21951     };
21952
21953 }
21954
21955 if ( ! String.prototype.trim === undefined ) {
21956
21957     String.prototype.trim = function () {
21958
21959         return this.replace( /^\s+|\s+$/g, '' );
21960
21961     };
21962
21963 }
21964
21965 // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
21966 // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
21967
21968 // requestAnimationFrame polyfill by Erik Möller
21969 // fixes from Paul Irish and Tino Zijdel
21970
21971 ( function () {
21972
21973     var lastTime = 0;
21974     var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
21975
21976     for ( var x = 0; x < vendors.length && !window.requestAnimationFrame; ++ x ) {
21977
21978         window.requestAnimationFrame = window[ vendors[ x ] + 'RequestAnimationFrame' ];
21979         window.cancelAnimationFrame = window[ vendors[ x ] + 'CancelAnimationFrame' ] || window[ vendors[ x ] + 'CancelRequestAnimationFrame' ];
21980
21981     }
21982
21983     if ( window.requestAnimationFrame === undefined ) {
21984
21985         window.requestAnimationFrame = function ( callback, element ) {
21986
21987             var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
21988             var id = window.setTimeout( function() { callback( currTime + timeToCall ); }, timeToCall );
21989             lastTime = currTime + timeToCall;
21990             return id;
21991
21992         };
21993
21994     }
21995
21996
21997     if ( window.cancelAnimationFrame === undefined ) {
21998
21999         window.cancelAnimationFrame = function ( id ) { clearTimeout( id ); };
22000
22001     }
22002
22003 }() );
22004
22005
22006 // MATERIAL CONSTANTS
22007
22008 // side
22009
22010 THREE.FrontSide = 0;
22011 THREE.BackSide = 1;
22012 THREE.DoubleSide = 2;
22013
22014 // shading
22015
22016 THREE.NoShading = 0;
22017 THREE.FlatShading = 1;
22018 THREE.SmoothShading = 2;
22019
22020 // colors
22021
22022 THREE.NoColors = 0;
22023 THREE.FaceColors = 1;
22024 THREE.VertexColors = 2;
22025
22026 // blending modes
22027
22028 THREE.NoBlending = 0;
22029 THREE.NormalBlending = 1;
22030 THREE.AdditiveBlending = 2;
22031 THREE.SubtractiveBlending = 3;
22032 THREE.MultiplyBlending = 4;
22033 THREE.CustomBlending = 5;
22034
22035 // custom blending equations
22036 // (numbers start from 100 not to clash with other
22037 //  mappings to OpenGL constants defined in Texture.js)
22038
22039 THREE.AddEquation = 100;
22040 THREE.SubtractEquation = 101;
22041 THREE.ReverseSubtractEquation = 102;
22042
22043 // custom blending destination factors
22044
22045 THREE.ZeroFactor = 200;
22046 THREE.OneFactor = 201;
22047 THREE.SrcColorFactor = 202;
22048 THREE.OneMinusSrcColorFactor = 203;
22049 THREE.SrcAlphaFactor = 204;
22050 THREE.OneMinusSrcAlphaFactor = 205;
22051 THREE.DstAlphaFactor = 206;
22052 THREE.OneMinusDstAlphaFactor = 207;
22053
22054 // custom blending source factors
22055
22056 //THREE.ZeroFactor = 200;
22057 //THREE.OneFactor = 201;
22058 //THREE.SrcAlphaFactor = 204;
22059 //THREE.OneMinusSrcAlphaFactor = 205;
22060 //THREE.DstAlphaFactor = 206;
22061 //THREE.OneMinusDstAlphaFactor = 207;
22062 THREE.DstColorFactor = 208;
22063 THREE.OneMinusDstColorFactor = 209;
22064 THREE.SrcAlphaSaturateFactor = 210;
22065
22066
22067 // TEXTURE CONSTANTS
22068
22069 THREE.MultiplyOperation = 0;
22070 THREE.MixOperation = 1;
22071
22072 // Mapping modes
22073
22074 THREE.UVMapping = function () {};
22075
22076 THREE.CubeReflectionMapping = function () {};
22077 THREE.CubeRefractionMapping = function () {};
22078
22079 THREE.SphericalReflectionMapping = function () {};
22080 THREE.SphericalRefractionMapping = function () {};
22081
22082 // Wrapping modes
22083
22084 THREE.RepeatWrapping = 1000;
22085 THREE.ClampToEdgeWrapping = 1001;
22086 THREE.MirroredRepeatWrapping = 1002;
22087
22088 // Filters
22089
22090 THREE.NearestFilter = 1003;
22091 THREE.NearestMipMapNearestFilter = 1004;
22092 THREE.NearestMipMapLinearFilter = 1005;
22093 THREE.LinearFilter = 1006;
22094 THREE.LinearMipMapNearestFilter = 1007;
22095 THREE.LinearMipMapLinearFilter = 1008;
22096
22097 // Data types
22098
22099 THREE.UnsignedByteType = 1009;
22100 THREE.ByteType = 1010;
22101 THREE.ShortType = 1011;
22102 THREE.UnsignedShortType = 1012;
22103 THREE.IntType = 1013;
22104 THREE.UnsignedIntType = 1014;
22105 THREE.FloatType = 1015;
22106
22107 // Pixel types
22108
22109 //THREE.UnsignedByteType = 1009;
22110 THREE.UnsignedShort4444Type = 1016;
22111 THREE.UnsignedShort5551Type = 1017;
22112 THREE.UnsignedShort565Type = 1018;
22113
22114 // Pixel formats
22115
22116 THREE.AlphaFormat = 1019;
22117 THREE.RGBFormat = 1020;
22118 THREE.RGBAFormat = 1021;
22119 THREE.LuminanceFormat = 1022;
22120 THREE.LuminanceAlphaFormat = 1023;
22121
22122 // Compressed texture formats
22123
22124 THREE.RGB_S3TC_DXT1_Format = 2001;
22125 THREE.RGBA_S3TC_DXT1_Format = 2002;
22126 THREE.RGBA_S3TC_DXT3_Format = 2003;
22127 THREE.RGBA_S3TC_DXT5_Format = 2004;
22128
22129 /*
22130 // Potential future PVRTC compressed texture formats
22131 THREE.RGB_PVRTC_4BPPV1_Format = 2100;
22132 THREE.RGB_PVRTC_2BPPV1_Format = 2101;
22133 THREE.RGBA_PVRTC_4BPPV1_Format = 2102;
22134 THREE.RGBA_PVRTC_2BPPV1_Format = 2103;
22135 */
22136 /**
22137  * @author alteredq / http://alteredqualia.com/
22138  */
22139
22140 THREE.Clock = function ( autoStart ) {
22141
22142     this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
22143
22144     this.startTime = 0;
22145     this.oldTime = 0;
22146     this.elapsedTime = 0;
22147
22148     this.running = false;
22149
22150 };
22151
22152 THREE.Clock.prototype.start = function () {
22153
22154     this.startTime = Date.now();
22155     this.oldTime = this.startTime;
22156
22157     this.running = true;
22158
22159 };
22160
22161 THREE.Clock.prototype.stop = function () {
22162
22163     this.getElapsedTime();
22164
22165     this.running = false;
22166
22167 };
22168
22169 THREE.Clock.prototype.getElapsedTime = function () {
22170
22171     this.elapsedTime += this.getDelta();
22172
22173     return this.elapsedTime;
22174
22175 };
22176
22177
22178 THREE.Clock.prototype.getDelta = function () {
22179
22180     var diff = 0;
22181
22182     if ( this.autoStart && ! this.running ) {
22183
22184         this.start();
22185
22186     }
22187
22188     if ( this.running ) {
22189
22190         var newTime = Date.now();
22191         diff = 0.001 * ( newTime - this.oldTime );
22192         this.oldTime = newTime;
22193
22194         this.elapsedTime += diff;
22195
22196     }
22197
22198     return diff;
22199
22200 };/**
22201  * @author mrdoob / http://mrdoob.com/
22202  */
22203
22204 THREE.Color = function ( hex ) {
22205
22206     if ( hex !== undefined ) this.setHex( hex );
22207
22208     return this;
22209
22210 };
22211
22212 THREE.Color.prototype = {
22213
22214     constructor: THREE.Color,
22215
22216     r: 1, g: 1, b: 1,
22217
22218     copy: function ( color ) {
22219
22220         this.r = color.r;
22221         this.g = color.g;
22222         this.b = color.b;
22223
22224         return this;
22225
22226     },
22227
22228     copyGammaToLinear: function ( color ) {
22229
22230         this.r = color.r * color.r;
22231         this.g = color.g * color.g;
22232         this.b = color.b * color.b;
22233
22234         return this;
22235
22236     },
22237
22238     copyLinearToGamma: function ( color ) {
22239
22240         this.r = Math.sqrt( color.r );
22241         this.g = Math.sqrt( color.g );
22242         this.b = Math.sqrt( color.b );
22243
22244         return this;
22245
22246     },
22247
22248     convertGammaToLinear: function () {
22249
22250         var r = this.r, g = this.g, b = this.b;
22251
22252         this.r = r * r;
22253         this.g = g * g;
22254         this.b = b * b;
22255
22256         return this;
22257
22258     },
22259
22260     convertLinearToGamma: function () {
22261
22262         this.r = Math.sqrt( this.r );
22263         this.g = Math.sqrt( this.g );
22264         this.b = Math.sqrt( this.b );
22265
22266         return this;
22267
22268     },
22269
22270     setRGB: function ( r, g, b ) {
22271
22272         this.r = r;
22273         this.g = g;
22274         this.b = b;
22275
22276         return this;
22277
22278     },
22279
22280     setHSV: function ( h, s, v ) {
22281
22282         // based on MochiKit implementation by Bob Ippolito
22283         // h,s,v ranges are < 0.0 - 1.0 >
22284
22285         var i, f, p, q, t;
22286
22287         if ( v === 0 ) {
22288
22289             this.r = this.g = this.b = 0;
22290
22291         } else {
22292
22293             i = Math.floor( h * 6 );
22294             f = ( h * 6 ) - i;
22295             p = v * ( 1 - s );
22296             q = v * ( 1 - ( s * f ) );
22297             t = v * ( 1 - ( s * ( 1 - f ) ) );
22298
22299             if ( i === 0 ) {
22300
22301                 this.r = v;
22302                 this.g = t;
22303                 this.b = p;
22304
22305             } else if ( i === 1 ) {
22306
22307                 this.r = q;
22308                 this.g = v;
22309                 this.b = p;
22310
22311             } else if ( i === 2 ) {
22312
22313                 this.r = p;
22314                 this.g = v;
22315                 this.b = t;
22316
22317             } else if ( i === 3 ) {
22318
22319                 this.r = p;
22320                 this.g = q;
22321                 this.b = v;
22322
22323             } else if ( i === 4 ) {
22324
22325                 this.r = t;
22326                 this.g = p;
22327                 this.b = v;
22328
22329             } else if ( i === 5 ) {
22330
22331                 this.r = v;
22332                 this.g = p;
22333                 this.b = q;
22334
22335             }
22336
22337         }
22338
22339         return this;
22340
22341     },
22342
22343     setHex: function ( hex ) {
22344
22345         hex = Math.floor( hex );
22346
22347         this.r = ( hex >> 16 & 255 ) / 255;
22348         this.g = ( hex >> 8 & 255 ) / 255;
22349         this.b = ( hex & 255 ) / 255;
22350
22351         return this;
22352
22353     },
22354
22355     lerpSelf: function ( color, alpha ) {
22356
22357         this.r += ( color.r - this.r ) * alpha;
22358         this.g += ( color.g - this.g ) * alpha;
22359         this.b += ( color.b - this.b ) * alpha;
22360
22361         return this;
22362
22363     },
22364
22365     getHex: function () {
22366
22367         return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;
22368
22369     },
22370
22371     getContextStyle: function () {
22372
22373         return 'rgb(' + ( ( this.r * 255 ) | 0 )  + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
22374
22375     },
22376
22377     clone: function () {
22378
22379         return new THREE.Color().setRGB( this.r, this.g, this.b );
22380
22381     }
22382
22383 };
22384 /**
22385  * @author mrdoob / http://mrdoob.com/
22386  * @author philogb / http://blog.thejit.org/
22387  * @author egraether / http://egraether.com/
22388  * @author zz85 / http://www.lab4games.net/zz85/blog
22389  */
22390
22391 THREE.Vector2 = function ( x, y ) {
22392
22393     this.x = x || 0;
22394     this.y = y || 0;
22395
22396 };
22397
22398 THREE.Vector2.prototype = {
22399
22400     constructor: THREE.Vector2,
22401
22402     set: function ( x, y ) {
22403
22404         this.x = x;
22405         this.y = y;
22406
22407         return this;
22408
22409     },
22410
22411     copy: function ( v ) {
22412
22413         this.x = v.x;
22414         this.y = v.y;
22415
22416         return this;
22417
22418     },
22419
22420     add: function ( a, b ) {
22421
22422         this.x = a.x + b.x;
22423         this.y = a.y + b.y;
22424
22425         return this;
22426
22427     },
22428
22429     addSelf: function ( v ) {
22430
22431         this.x += v.x;
22432         this.y += v.y;
22433
22434         return this;
22435
22436     },
22437
22438     sub: function ( a, b ) {
22439
22440         this.x = a.x - b.x;
22441         this.y = a.y - b.y;
22442
22443         return this;
22444
22445     },
22446
22447     subSelf: function ( v ) {
22448
22449         this.x -= v.x;
22450         this.y -= v.y;
22451
22452         return this;
22453
22454     },
22455
22456     multiplyScalar: function ( s ) {
22457
22458         this.x *= s;
22459         this.y *= s;
22460
22461         return this;
22462
22463     },
22464
22465     divideScalar: function ( s ) {
22466
22467         if ( s ) {
22468
22469             this.x /= s;
22470             this.y /= s;
22471
22472         } else {
22473
22474             this.set( 0, 0 );
22475
22476         }
22477
22478         return this;
22479
22480     },
22481
22482     negate: function() {
22483
22484         return this.multiplyScalar( - 1 );
22485
22486     },
22487
22488     dot: function ( v ) {
22489
22490         return this.x * v.x + this.y * v.y;
22491
22492     },
22493
22494     lengthSq: function () {
22495
22496         return this.x * this.x + this.y * this.y;
22497
22498     },
22499
22500     length: function () {
22501
22502         return Math.sqrt( this.lengthSq() );
22503
22504     },
22505
22506     normalize: function () {
22507
22508         return this.divideScalar( this.length() );
22509
22510     },
22511
22512     distanceTo: function ( v ) {
22513
22514         return Math.sqrt( this.distanceToSquared( v ) );
22515
22516     },
22517
22518     distanceToSquared: function ( v ) {
22519
22520         var dx = this.x - v.x, dy = this.y - v.y;
22521         return dx * dx + dy * dy;
22522
22523     },
22524
22525     setLength: function ( l ) {
22526
22527         return this.normalize().multiplyScalar( l );
22528
22529     },
22530
22531     lerpSelf: function ( v, alpha ) {
22532
22533         this.x += ( v.x - this.x ) * alpha;
22534         this.y += ( v.y - this.y ) * alpha;
22535
22536         return this;
22537
22538     },
22539
22540     equals: function( v ) {
22541
22542         return ( ( v.x === this.x ) && ( v.y === this.y ) );
22543
22544     },
22545
22546     isZero: function () {
22547
22548         return ( this.lengthSq() < 0.0001 /* almostZero */ );
22549
22550     },
22551
22552     clone: function () {
22553
22554         return new THREE.Vector2( this.x, this.y );
22555
22556     }
22557
22558 };
22559 /**
22560  * @author mrdoob / http://mrdoob.com/
22561  * @author kile / http://kile.stravaganza.org/
22562  * @author philogb / http://blog.thejit.org/
22563  * @author mikael emtinger / http://gomo.se/
22564  * @author egraether / http://egraether.com/
22565  * @author WestLangley / http://github.com/WestLangley
22566  */
22567
22568 THREE.Vector3 = function ( x, y, z ) {
22569
22570     this.x = x || 0;
22571     this.y = y || 0;
22572     this.z = z || 0;
22573
22574 };
22575
22576
22577 THREE.Vector3.prototype = {
22578
22579     constructor: THREE.Vector3,
22580
22581     set: function ( x, y, z ) {
22582
22583         this.x = x;
22584         this.y = y;
22585         this.z = z;
22586
22587         return this;
22588
22589     },
22590
22591     setX: function ( x ) {
22592
22593         this.x = x;
22594
22595         return this;
22596
22597     },
22598
22599     setY: function ( y ) {
22600
22601         this.y = y;
22602
22603         return this;
22604
22605     },
22606
22607     setZ: function ( z ) {
22608
22609         this.z = z;
22610
22611         return this;
22612
22613     },
22614
22615     copy: function ( v ) {
22616
22617         this.x = v.x;
22618         this.y = v.y;
22619         this.z = v.z;
22620
22621         return this;
22622
22623     },
22624
22625     add: function ( a, b ) {
22626
22627         this.x = a.x + b.x;
22628         this.y = a.y + b.y;
22629         this.z = a.z + b.z;
22630
22631         return this;
22632
22633     },
22634
22635     addSelf: function ( v ) {
22636
22637         this.x += v.x;
22638         this.y += v.y;
22639         this.z += v.z;
22640
22641         return this;
22642
22643     },
22644
22645     addScalar: function ( s ) {
22646
22647         this.x += s;
22648         this.y += s;
22649         this.z += s;
22650
22651         return this;
22652
22653     },
22654
22655     sub: function ( a, b ) {
22656
22657         this.x = a.x - b.x;
22658         this.y = a.y - b.y;
22659         this.z = a.z - b.z;
22660
22661         return this;
22662
22663     },
22664
22665     subSelf: function ( v ) {
22666
22667         this.x -= v.x;
22668         this.y -= v.y;
22669         this.z -= v.z;
22670
22671         return this;
22672
22673     },
22674
22675     multiply: function ( a, b ) {
22676
22677         this.x = a.x * b.x;
22678         this.y = a.y * b.y;
22679         this.z = a.z * b.z;
22680
22681         return this;
22682
22683     },
22684
22685     multiplySelf: function ( v ) {
22686
22687         this.x *= v.x;
22688         this.y *= v.y;
22689         this.z *= v.z;
22690
22691         return this;
22692
22693     },
22694
22695     multiplyScalar: function ( s ) {
22696
22697         this.x *= s;
22698         this.y *= s;
22699         this.z *= s;
22700
22701         return this;
22702
22703     },
22704
22705     divideSelf: function ( v ) {
22706
22707         this.x /= v.x;
22708         this.y /= v.y;
22709         this.z /= v.z;
22710
22711         return this;
22712
22713     },
22714
22715     divideScalar: function ( s ) {
22716
22717         if ( s ) {
22718
22719             this.x /= s;
22720             this.y /= s;
22721             this.z /= s;
22722
22723         } else {
22724
22725             this.x = 0;
22726             this.y = 0;
22727             this.z = 0;
22728
22729         }
22730
22731         return this;
22732
22733     },
22734
22735
22736     negate: function() {
22737
22738         return this.multiplyScalar( - 1 );
22739
22740     },
22741
22742     dot: function ( v ) {
22743
22744         return this.x * v.x + this.y * v.y + this.z * v.z;
22745
22746     },
22747
22748     lengthSq: function () {
22749
22750         return this.x * this.x + this.y * this.y + this.z * this.z;
22751
22752     },
22753
22754     length: function () {
22755
22756         return Math.sqrt( this.lengthSq() );
22757
22758     },
22759
22760     lengthManhattan: function () {
22761
22762         return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
22763
22764     },
22765
22766     normalize: function () {
22767
22768         return this.divideScalar( this.length() );
22769
22770     },
22771
22772     setLength: function ( l ) {
22773
22774         return this.normalize().multiplyScalar( l );
22775
22776     },
22777
22778     lerpSelf: function ( v, alpha ) {
22779
22780         this.x += ( v.x - this.x ) * alpha;
22781         this.y += ( v.y - this.y ) * alpha;
22782         this.z += ( v.z - this.z ) * alpha;
22783
22784         return this;
22785
22786     },
22787
22788     cross: function ( a, b ) {
22789
22790         this.x = a.y * b.z - a.z * b.y;
22791         this.y = a.z * b.x - a.x * b.z;
22792         this.z = a.x * b.y - a.y * b.x;
22793
22794         return this;
22795
22796     },
22797
22798     crossSelf: function ( v ) {
22799
22800         var x = this.x, y = this.y, z = this.z;
22801
22802         this.x = y * v.z - z * v.y;
22803         this.y = z * v.x - x * v.z;
22804         this.z = x * v.y - y * v.x;
22805
22806         return this;
22807
22808     },
22809
22810     distanceTo: function ( v ) {
22811
22812         return Math.sqrt( this.distanceToSquared( v ) );
22813
22814     },
22815
22816     distanceToSquared: function ( v ) {
22817
22818         return new THREE.Vector3().sub( this, v ).lengthSq();
22819
22820     },
22821
22822     getPositionFromMatrix: function ( m ) {
22823
22824         this.x = m.elements[12];
22825         this.y = m.elements[13];
22826         this.z = m.elements[14];
22827
22828         return this;
22829
22830     },
22831
22832     setEulerFromRotationMatrix: function ( m, order ) {
22833
22834         // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
22835
22836         // clamp, to handle numerical problems
22837
22838         function clamp( x ) {
22839
22840             return Math.min( Math.max( x, -1 ), 1 );
22841
22842         }
22843
22844         var te = m.elements;
22845         var m11 = te[0], m12 = te[4], m13 = te[8];
22846         var m21 = te[1], m22 = te[5], m23 = te[9];
22847         var m31 = te[2], m32 = te[6], m33 = te[10];
22848
22849         if ( order === undefined || order === 'XYZ' ) {
22850
22851             this.y = Math.asin( clamp( m13 ) );
22852
22853             if ( Math.abs( m13 ) < 0.99999 ) {
22854
22855                 this.x = Math.atan2( - m23, m33 );
22856                 this.z = Math.atan2( - m12, m11 );
22857
22858             } else {
22859
22860                 this.x = Math.atan2( m32, m22 );
22861                 this.z = 0;
22862
22863             }
22864
22865         } else if ( order === 'YXZ' ) {
22866
22867             this.x = Math.asin( - clamp( m23 ) );
22868
22869             if ( Math.abs( m23 ) < 0.99999 ) {
22870
22871                 this.y = Math.atan2( m13, m33 );
22872                 this.z = Math.atan2( m21, m22 );
22873
22874             } else {
22875
22876                 this.y = Math.atan2( - m31, m11 );
22877                 this.z = 0;
22878
22879             }
22880
22881         } else if ( order === 'ZXY' ) {
22882
22883             this.x = Math.asin( clamp( m32 ) );
22884
22885             if ( Math.abs( m32 ) < 0.99999 ) {
22886
22887                 this.y = Math.atan2( - m31, m33 );
22888                 this.z = Math.atan2( - m12, m22 );
22889
22890             } else {
22891
22892                 this.y = 0;
22893                 this.z = Math.atan2( m21, m11 );
22894
22895             }
22896
22897         } else if ( order === 'ZYX' ) {
22898
22899             this.y = Math.asin( - clamp( m31 ) );
22900
22901             if ( Math.abs( m31 ) < 0.99999 ) {
22902
22903                 this.x = Math.atan2( m32, m33 );
22904                 this.z = Math.atan2( m21, m11 );
22905
22906             } else {
22907
22908                 this.x = 0;
22909                 this.z = Math.atan2( - m12, m22 );
22910
22911             }
22912
22913         } else if ( order === 'YZX' ) {
22914
22915             this.z = Math.asin( clamp( m21 ) );
22916
22917             if ( Math.abs( m21 ) < 0.99999 ) {
22918
22919                 this.x = Math.atan2( - m23, m22 );
22920                 this.y = Math.atan2( - m31, m11 );
22921
22922             } else {
22923
22924                 this.x = 0;
22925                 this.y = Math.atan2( m13, m33 );
22926
22927             }
22928
22929         } else if ( order === 'XZY' ) {
22930
22931             this.z = Math.asin( - clamp( m12 ) );
22932
22933             if ( Math.abs( m12 ) < 0.99999 ) {
22934
22935                 this.x = Math.atan2( m32, m22 );
22936                 this.y = Math.atan2( m13, m11 );
22937
22938             } else {
22939
22940                 this.x = Math.atan2( - m23, m33 );
22941                 this.y = 0;
22942
22943             }
22944
22945         }
22946
22947         return this;
22948
22949     },
22950
22951     setEulerFromQuaternion: function ( q, order ) {
22952
22953         // q is assumed to be normalized
22954
22955         // clamp, to handle numerical problems
22956
22957         function clamp( x ) {
22958
22959             return Math.min( Math.max( x, -1 ), 1 );
22960
22961         }
22962
22963         // http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m
22964
22965         var sqx = q.x * q.x;
22966         var sqy = q.y * q.y;
22967         var sqz = q.z * q.z;
22968         var sqw = q.w * q.w;
22969
22970         if ( order === undefined || order === 'XYZ' ) {
22971
22972             this.x = Math.atan2( 2 * ( q.x * q.w - q.y * q.z ), ( sqw - sqx - sqy + sqz ) );
22973             this.y = Math.asin(  clamp( 2 * ( q.x * q.z + q.y * q.w ) ) );
22974             this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw + sqx - sqy - sqz ) );
22975
22976         } else if ( order ===  'YXZ' ) {
22977
22978             this.x = Math.asin(  clamp( 2 * ( q.x * q.w - q.y * q.z ) ) );
22979             this.y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw - sqx - sqy + sqz ) );
22980             this.z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw - sqx + sqy - sqz ) );
22981
22982         } else if ( order === 'ZXY' ) {
22983
22984             this.x = Math.asin(  clamp( 2 * ( q.x * q.w + q.y * q.z ) ) );
22985             this.y = Math.atan2( 2 * ( q.y * q.w - q.z * q.x ), ( sqw - sqx - sqy + sqz ) );
22986             this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw - sqx + sqy - sqz ) );
22987
22988         } else if ( order === 'ZYX' ) {
22989
22990             this.x = Math.atan2( 2 * ( q.x * q.w + q.z * q.y ), ( sqw - sqx - sqy + sqz ) );
22991             this.y = Math.asin(  clamp( 2 * ( q.y * q.w - q.x * q.z ) ) );
22992             this.z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw + sqx - sqy - sqz ) );
22993
22994         } else if ( order === 'YZX' ) {
22995
22996             this.x = Math.atan2( 2 * ( q.x * q.w - q.z * q.y ), ( sqw - sqx + sqy - sqz ) );
22997             this.y = Math.atan2( 2 * ( q.y * q.w - q.x * q.z ), ( sqw + sqx - sqy - sqz ) );
22998             this.z = Math.asin(  clamp( 2 * ( q.x * q.y + q.z * q.w ) ) );
22999
23000         } else if ( order === 'XZY' ) {
23001
23002             this.x = Math.atan2( 2 * ( q.x * q.w + q.y * q.z ), ( sqw - sqx + sqy - sqz ) );
23003             this.y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw + sqx - sqy - sqz ) );
23004             this.z = Math.asin(  clamp( 2 * ( q.z * q.w - q.x * q.y ) ) );
23005
23006         }
23007
23008         return this;
23009
23010     },
23011
23012     getScaleFromMatrix: function ( m ) {
23013
23014         var sx = this.set( m.elements[0], m.elements[1], m.elements[2] ).length();
23015         var sy = this.set( m.elements[4], m.elements[5], m.elements[6] ).length();
23016         var sz = this.set( m.elements[8], m.elements[9], m.elements[10] ).length();
23017
23018         this.x = sx;
23019         this.y = sy;
23020         this.z = sz;
23021
23022         return this;
23023     },
23024
23025     equals: function ( v ) {
23026
23027         return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
23028
23029     },
23030
23031     isZero: function () {
23032
23033         return ( this.lengthSq() < 0.0001 /* almostZero */ );
23034
23035     },
23036
23037     clone: function () {
23038
23039         return new THREE.Vector3( this.x, this.y, this.z );
23040
23041     }
23042
23043 };
23044
23045 /**
23046  * @author supereggbert / http://www.paulbrunt.co.uk/
23047  * @author philogb / http://blog.thejit.org/
23048  * @author mikael emtinger / http://gomo.se/
23049  * @author egraether / http://egraether.com/
23050  * @author WestLangley / http://github.com/WestLangley
23051  */
23052
23053 THREE.Vector4 = function ( x, y, z, w ) {
23054
23055     this.x = x || 0;
23056     this.y = y || 0;
23057     this.z = z || 0;
23058     this.w = ( w !== undefined ) ? w : 1;
23059
23060 };
23061
23062 THREE.Vector4.prototype = {
23063
23064     constructor: THREE.Vector4,
23065
23066     set: function ( x, y, z, w ) {
23067
23068         this.x = x;
23069         this.y = y;
23070         this.z = z;
23071         this.w = w;
23072
23073         return this;
23074
23075     },
23076
23077     copy: function ( v ) {
23078
23079         this.x = v.x;
23080         this.y = v.y;
23081         this.z = v.z;
23082         this.w = ( v.w !== undefined ) ? v.w : 1;
23083
23084         return this;
23085
23086     },
23087
23088     add: function ( a, b ) {
23089
23090         this.x = a.x + b.x;
23091         this.y = a.y + b.y;
23092         this.z = a.z + b.z;
23093         this.w = a.w + b.w;
23094
23095         return this;
23096
23097     },
23098
23099     addSelf: function ( v ) {
23100
23101         this.x += v.x;
23102         this.y += v.y;
23103         this.z += v.z;
23104         this.w += v.w;
23105
23106         return this;
23107
23108     },
23109
23110     sub: function ( a, b ) {
23111
23112         this.x = a.x - b.x;
23113         this.y = a.y - b.y;
23114         this.z = a.z - b.z;
23115         this.w = a.w - b.w;
23116
23117         return this;
23118
23119     },
23120
23121     subSelf: function ( v ) {
23122
23123         this.x -= v.x;
23124         this.y -= v.y;
23125         this.z -= v.z;
23126         this.w -= v.w;
23127
23128         return this;
23129
23130     },
23131
23132     multiplyScalar: function ( s ) {
23133
23134         this.x *= s;
23135         this.y *= s;
23136         this.z *= s;
23137         this.w *= s;
23138
23139         return this;
23140
23141     },
23142
23143     divideScalar: function ( s ) {
23144
23145         if ( s ) {
23146
23147             this.x /= s;
23148             this.y /= s;
23149             this.z /= s;
23150             this.w /= s;
23151
23152         } else {
23153
23154             this.x = 0;
23155             this.y = 0;
23156             this.z = 0;
23157             this.w = 1;
23158
23159         }
23160
23161         return this;
23162
23163     },
23164
23165
23166     negate: function() {
23167
23168         return this.multiplyScalar( -1 );
23169
23170     },
23171
23172     dot: function ( v ) {
23173
23174         return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
23175
23176     },
23177
23178     lengthSq: function () {
23179
23180         return this.dot( this );
23181
23182     },
23183
23184     length: function () {
23185
23186         return Math.sqrt( this.lengthSq() );
23187
23188     },
23189
23190     lengthManhattan: function () {
23191
23192         return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
23193
23194     },
23195
23196     normalize: function () {
23197
23198         return this.divideScalar( this.length() );
23199
23200     },
23201
23202     setLength: function ( l ) {
23203
23204         return this.normalize().multiplyScalar( l );
23205
23206     },
23207
23208     lerpSelf: function ( v, alpha ) {
23209
23210         this.x += ( v.x - this.x ) * alpha;
23211         this.y += ( v.y - this.y ) * alpha;
23212         this.z += ( v.z - this.z ) * alpha;
23213         this.w += ( v.w - this.w ) * alpha;
23214
23215         return this;
23216
23217     },
23218
23219     clone: function () {
23220
23221         return new THREE.Vector4( this.x, this.y, this.z, this.w );
23222
23223     },
23224
23225     setAxisAngleFromQuaternion: function ( q ) {
23226
23227         // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
23228
23229         // q is assumed to be normalized
23230
23231         this.w = 2 * Math.acos( q.w );
23232
23233         var s = Math.sqrt( 1 - q.w * q.w );
23234
23235         if ( s < 0.0001 ) {
23236
23237              this.x = 1;
23238              this.y = 0;
23239              this.z = 0;
23240
23241         } else {
23242
23243              this.x = q.x / s;
23244              this.y = q.y / s;
23245              this.z = q.z / s;
23246
23247         }
23248
23249         return this;
23250
23251     },
23252
23253     setAxisAngleFromRotationMatrix: function ( m ) {
23254
23255         // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
23256
23257         // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
23258
23259         var angle, x, y, z,        // variables for result
23260             epsilon = 0.01,        // margin to allow for rounding errors
23261             epsilon2 = 0.1,        // margin to distinguish between 0 and 180 degrees
23262
23263             te = m.elements,
23264
23265             m11 = te[0], m12 = te[4], m13 = te[8],
23266             m21 = te[1], m22 = te[5], m23 = te[9],
23267             m31 = te[2], m32 = te[6], m33 = te[10];
23268
23269         if ( ( Math.abs( m12 - m21 ) < epsilon )
23270           && ( Math.abs( m13 - m31 ) < epsilon )
23271           && ( Math.abs( m23 - m32 ) < epsilon ) ) {
23272
23273             // singularity found
23274             // first check for identity matrix which must have +1 for all terms
23275             // in leading diagonal and zero in other terms
23276
23277             if ( ( Math.abs( m12 + m21 ) < epsilon2 )
23278               && ( Math.abs( m13 + m31 ) < epsilon2 )
23279               && ( Math.abs( m23 + m32 ) < epsilon2 )
23280               && ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
23281
23282                 // this singularity is identity matrix so angle = 0
23283
23284                 this.set( 1, 0, 0, 0 );
23285
23286                 return this; // zero angle, arbitrary axis
23287
23288             }
23289
23290             // otherwise this singularity is angle = 180
23291
23292             angle = Math.PI;
23293
23294             var xx = ( m11 + 1 ) / 2;
23295             var yy = ( m22 + 1 ) / 2;
23296             var zz = ( m33 + 1 ) / 2;
23297             var xy = ( m12 + m21 ) / 4;
23298             var xz = ( m13 + m31 ) / 4;
23299             var yz = ( m23 + m32 ) / 4;
23300
23301             if ( ( xx > yy ) && ( xx > zz ) ) { // m11 is the largest diagonal term
23302
23303                 if ( xx < epsilon ) {
23304
23305                     x = 0;
23306                     y = 0.707106781;
23307                     z = 0.707106781;
23308
23309                 } else {
23310
23311                     x = Math.sqrt( xx );
23312                     y = xy / x;
23313                     z = xz / x;
23314
23315                 }
23316
23317             } else if ( yy > zz ) { // m22 is the largest diagonal term
23318
23319                 if ( yy < epsilon ) {
23320
23321                     x = 0.707106781;
23322                     y = 0;
23323                     z = 0.707106781;
23324
23325                 } else {
23326
23327                     y = Math.sqrt( yy );
23328                     x = xy / y;
23329                     z = yz / y;
23330
23331                 }
23332
23333             } else { // m33 is the largest diagonal term so base result on this
23334
23335                 if ( zz < epsilon ) {
23336
23337                     x = 0.707106781;
23338                     y = 0.707106781;
23339                     z = 0;
23340
23341                 } else {
23342
23343                     z = Math.sqrt( zz );
23344                     x = xz / z;
23345                     y = yz / z;
23346
23347                 }
23348
23349             }
23350
23351             this.set( x, y, z, angle );
23352
23353             return this; // return 180 deg rotation
23354
23355         }
23356
23357         // as we have reached here there are no singularities so we can handle normally
23358
23359         var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 )
23360                          + ( m13 - m31 ) * ( m13 - m31 )
23361                          + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
23362
23363         if ( Math.abs( s ) < 0.001 ) s = 1;
23364
23365         // prevent divide by zero, should not happen if matrix is orthogonal and should be
23366         // caught by singularity test above, but I've left it in just in case
23367
23368         this.x = ( m32 - m23 ) / s;
23369         this.y = ( m13 - m31 ) / s;
23370         this.z = ( m21 - m12 ) / s;
23371         this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
23372
23373         return this;
23374
23375     }
23376
23377 };
23378 /**
23379  * @author alteredq / http://alteredqualia.com/
23380  */
23381
23382 THREE.Matrix3 = function () {
23383
23384     this.elements = new Float32Array(9);
23385
23386 };
23387
23388 THREE.Matrix3.prototype = {
23389
23390     constructor: THREE.Matrix3,
23391
23392     getInverse: function ( matrix ) {
23393
23394         // input: THREE.Matrix4
23395         // ( based on http://code.google.com/p/webgl-mjs/ )
23396
23397         var me = matrix.elements;
23398
23399         var a11 =   me[10] * me[5] - me[6] * me[9];
23400         var a21 = - me[10] * me[1] + me[2] * me[9];
23401         var a31 =   me[6] * me[1] - me[2] * me[5];
23402         var a12 = - me[10] * me[4] + me[6] * me[8];
23403         var a22 =   me[10] * me[0] - me[2] * me[8];
23404         var a32 = - me[6] * me[0] + me[2] * me[4];
23405         var a13 =   me[9] * me[4] - me[5] * me[8];
23406         var a23 = - me[9] * me[0] + me[1] * me[8];
23407         var a33 =   me[5] * me[0] - me[1] * me[4];
23408
23409         var det = me[0] * a11 + me[1] * a12 + me[2] * a13;
23410
23411         // no inverse
23412
23413         if ( det === 0 ) {
23414
23415             console.warn( "Matrix3.getInverse(): determinant == 0" );
23416
23417         }
23418
23419         var idet = 1.0 / det;
23420
23421         var m = this.elements;
23422
23423         m[ 0 ] = idet * a11; m[ 1 ] = idet * a21; m[ 2 ] = idet * a31;
23424         m[ 3 ] = idet * a12; m[ 4 ] = idet * a22; m[ 5 ] = idet * a32;
23425         m[ 6 ] = idet * a13; m[ 7 ] = idet * a23; m[ 8 ] = idet * a33;
23426
23427         return this;
23428
23429     },
23430
23431
23432     transpose: function () {
23433
23434         var tmp, m = this.elements;
23435
23436         tmp = m[1]; m[1] = m[3]; m[3] = tmp;
23437         tmp = m[2]; m[2] = m[6]; m[6] = tmp;
23438         tmp = m[5]; m[5] = m[7]; m[7] = tmp;
23439
23440         return this;
23441
23442     },
23443
23444
23445     transposeIntoArray: function ( r ) {
23446
23447         var m = this.m;
23448
23449         r[ 0 ] = m[ 0 ];
23450         r[ 1 ] = m[ 3 ];
23451         r[ 2 ] = m[ 6 ];
23452         r[ 3 ] = m[ 1 ];
23453         r[ 4 ] = m[ 4 ];
23454         r[ 5 ] = m[ 7 ];
23455         r[ 6 ] = m[ 2 ];
23456         r[ 7 ] = m[ 5 ];
23457         r[ 8 ] = m[ 8 ];
23458
23459         return this;
23460
23461     }
23462
23463 };
23464 /**
23465  * @author mrdoob / http://mrdoob.com/
23466  * @author supereggbert / http://www.paulbrunt.co.uk/
23467  * @author philogb / http://blog.thejit.org/
23468  * @author jordi_ros / http://plattsoft.com
23469  * @author D1plo1d / http://github.com/D1plo1d
23470  * @author alteredq / http://alteredqualia.com/
23471  * @author mikael emtinger / http://gomo.se/
23472  * @author timknip / http://www.floorplanner.com/
23473  */
23474
23475
23476 THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
23477
23478     this.elements = new Float32Array( 16 );
23479
23480     this.set(
23481
23482         ( n11 !== undefined ) ? n11 : 1, n12 || 0, n13 || 0, n14 || 0,
23483         n21 || 0, ( n22 !== undefined ) ? n22 : 1, n23 || 0, n24 || 0,
23484         n31 || 0, n32 || 0, ( n33 !== undefined ) ? n33 : 1, n34 || 0,
23485         n41 || 0, n42 || 0, n43 || 0, ( n44 !== undefined ) ? n44 : 1
23486
23487     );
23488
23489 };
23490
23491 THREE.Matrix4.prototype = {
23492
23493     constructor: THREE.Matrix4,
23494
23495     set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
23496
23497         var te = this.elements;
23498
23499         te[0] = n11; te[4] = n12; te[8] = n13; te[12] = n14;
23500         te[1] = n21; te[5] = n22; te[9] = n23; te[13] = n24;
23501         te[2] = n31; te[6] = n32; te[10] = n33; te[14] = n34;
23502         te[3] = n41; te[7] = n42; te[11] = n43; te[15] = n44;
23503
23504         return this;
23505
23506     },
23507
23508     identity: function () {
23509
23510         this.set(
23511
23512             1, 0, 0, 0,
23513             0, 1, 0, 0,
23514             0, 0, 1, 0,
23515             0, 0, 0, 1
23516
23517         );
23518
23519         return this;
23520
23521     },
23522
23523     copy: function ( m ) {
23524
23525         var me = m.elements;
23526
23527         this.set(
23528
23529             me[0], me[4], me[8], me[12],
23530             me[1], me[5], me[9], me[13],
23531             me[2], me[6], me[10], me[14],
23532             me[3], me[7], me[11], me[15]
23533
23534         );
23535
23536         return this;
23537
23538     },
23539
23540     lookAt: function ( eye, target, up ) {
23541
23542         var te = this.elements;
23543
23544         var x = THREE.Matrix4.__v1;
23545         var y = THREE.Matrix4.__v2;
23546         var z = THREE.Matrix4.__v3;
23547
23548         z.sub( eye, target ).normalize();
23549
23550         if ( z.length() === 0 ) {
23551
23552             z.z = 1;
23553
23554         }
23555
23556         x.cross( up, z ).normalize();
23557
23558         if ( x.length() === 0 ) {
23559
23560             z.x += 0.0001;
23561             x.cross( up, z ).normalize();
23562
23563         }
23564
23565         y.cross( z, x );
23566
23567
23568         te[0] = x.x; te[4] = y.x; te[8] = z.x;
23569         te[1] = x.y; te[5] = y.y; te[9] = z.y;
23570         te[2] = x.z; te[6] = y.z; te[10] = z.z;
23571
23572         return this;
23573
23574     },
23575
23576     multiply: function ( a, b ) {
23577
23578         var ae = a.elements;
23579         var be = b.elements;
23580         var te = this.elements;
23581
23582         var a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12];
23583         var a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13];
23584         var a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14];
23585         var a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15];
23586
23587         var b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12];
23588         var b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13];
23589         var b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14];
23590         var b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15];
23591
23592         te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
23593         te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
23594         te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
23595         te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
23596
23597         te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
23598         te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
23599         te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
23600         te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
23601
23602         te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
23603         te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
23604         te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
23605         te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
23606
23607         te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
23608         te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
23609         te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
23610         te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
23611
23612         return this;
23613
23614     },
23615
23616     multiplySelf: function ( m ) {
23617
23618         return this.multiply( this, m );
23619
23620     },
23621
23622     multiplyToArray: function ( a, b, r ) {
23623
23624         var te = this.elements;
23625
23626         this.multiply( a, b );
23627
23628         r[ 0 ] = te[0]; r[ 1 ] = te[1]; r[ 2 ] = te[2]; r[ 3 ] = te[3];
23629         r[ 4 ] = te[4]; r[ 5 ] = te[5]; r[ 6 ] = te[6]; r[ 7 ] = te[7];
23630         r[ 8 ]  = te[8]; r[ 9 ]  = te[9]; r[ 10 ] = te[10]; r[ 11 ] = te[11];
23631         r[ 12 ] = te[12]; r[ 13 ] = te[13]; r[ 14 ] = te[14]; r[ 15 ] = te[15];
23632
23633         return this;
23634
23635     },
23636
23637     multiplyScalar: function ( s ) {
23638
23639         var te = this.elements;
23640
23641         te[0] *= s; te[4] *= s; te[8] *= s; te[12] *= s;
23642         te[1] *= s; te[5] *= s; te[9] *= s; te[13] *= s;
23643         te[2] *= s; te[6] *= s; te[10] *= s; te[14] *= s;
23644         te[3] *= s; te[7] *= s; te[11] *= s; te[15] *= s;
23645
23646         return this;
23647
23648     },
23649
23650     multiplyVector3: function ( v ) {
23651
23652         var te = this.elements;
23653
23654         var vx = v.x, vy = v.y, vz = v.z;
23655         var d = 1 / ( te[3] * vx + te[7] * vy + te[11] * vz + te[15] );
23656
23657         v.x = ( te[0] * vx + te[4] * vy + te[8] * vz + te[12] ) * d;
23658         v.y = ( te[1] * vx + te[5] * vy + te[9] * vz + te[13] ) * d;
23659         v.z = ( te[2] * vx + te[6] * vy + te[10] * vz + te[14] ) * d;
23660
23661         return v;
23662
23663     },
23664
23665     multiplyVector4: function ( v ) {
23666
23667         var te = this.elements;
23668         var vx = v.x, vy = v.y, vz = v.z, vw = v.w;
23669
23670         v.x = te[0] * vx + te[4] * vy + te[8] * vz + te[12] * vw;
23671         v.y = te[1] * vx + te[5] * vy + te[9] * vz + te[13] * vw;
23672         v.z = te[2] * vx + te[6] * vy + te[10] * vz + te[14] * vw;
23673         v.w = te[3] * vx + te[7] * vy + te[11] * vz + te[15] * vw;
23674
23675         return v;
23676
23677     },
23678
23679     multiplyVector3Array: function ( a ) {
23680
23681         var tmp = THREE.Matrix4.__v1;
23682
23683         for ( var i = 0, il = a.length; i < il; i += 3 ) {
23684
23685             tmp.x = a[ i ];
23686             tmp.y = a[ i + 1 ];
23687             tmp.z = a[ i + 2 ];
23688
23689             this.multiplyVector3( tmp );
23690
23691             a[ i ]     = tmp.x;
23692             a[ i + 1 ] = tmp.y;
23693             a[ i + 2 ] = tmp.z;
23694
23695         }
23696
23697         return a;
23698
23699     },
23700
23701     rotateAxis: function ( v ) {
23702
23703         var te = this.elements;
23704         var vx = v.x, vy = v.y, vz = v.z;
23705
23706         v.x = vx * te[0] + vy * te[4] + vz * te[8];
23707         v.y = vx * te[1] + vy * te[5] + vz * te[9];
23708         v.z = vx * te[2] + vy * te[6] + vz * te[10];
23709
23710         v.normalize();
23711
23712         return v;
23713
23714     },
23715
23716     crossVector: function ( a ) {
23717
23718         var te = this.elements;
23719         var v = new THREE.Vector4();
23720
23721         v.x = te[0] * a.x + te[4] * a.y + te[8] * a.z + te[12] * a.w;
23722         v.y = te[1] * a.x + te[5] * a.y + te[9] * a.z + te[13] * a.w;
23723         v.z = te[2] * a.x + te[6] * a.y + te[10] * a.z + te[14] * a.w;
23724
23725         v.w = ( a.w ) ? te[3] * a.x + te[7] * a.y + te[11] * a.z + te[15] * a.w : 1;
23726
23727         return v;
23728
23729     },
23730
23731     determinant: function () {
23732
23733         var te = this.elements;
23734
23735         var n11 = te[0], n12 = te[4], n13 = te[8], n14 = te[12];
23736         var n21 = te[1], n22 = te[5], n23 = te[9], n24 = te[13];
23737         var n31 = te[2], n32 = te[6], n33 = te[10], n34 = te[14];
23738         var n41 = te[3], n42 = te[7], n43 = te[11], n44 = te[15];
23739
23740         //TODO: make this more efficient
23741         //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
23742
23743         return (
23744             n14 * n23 * n32 * n41-
23745             n13 * n24 * n32 * n41-
23746             n14 * n22 * n33 * n41+
23747             n12 * n24 * n33 * n41+
23748
23749             n13 * n22 * n34 * n41-
23750             n12 * n23 * n34 * n41-
23751             n14 * n23 * n31 * n42+
23752             n13 * n24 * n31 * n42+
23753
23754             n14 * n21 * n33 * n42-
23755             n11 * n24 * n33 * n42-
23756             n13 * n21 * n34 * n42+
23757             n11 * n23 * n34 * n42+
23758
23759             n14 * n22 * n31 * n43-
23760             n12 * n24 * n31 * n43-
23761             n14 * n21 * n32 * n43+
23762             n11 * n24 * n32 * n43+
23763
23764             n12 * n21 * n34 * n43-
23765             n11 * n22 * n34 * n43-
23766             n13 * n22 * n31 * n44+
23767             n12 * n23 * n31 * n44+
23768
23769             n13 * n21 * n32 * n44-
23770             n11 * n23 * n32 * n44-
23771             n12 * n21 * n33 * n44+
23772             n11 * n22 * n33 * n44
23773         );
23774
23775     },
23776
23777     transpose: function () {
23778
23779         var te = this.elements;
23780         var tmp;
23781
23782         tmp = te[1]; te[1] = te[4]; te[4] = tmp;
23783         tmp = te[2]; te[2] = te[8]; te[8] = tmp;
23784         tmp = te[6]; te[6] = te[9]; te[9] = tmp;
23785
23786         tmp = te[3]; te[3] = te[12]; te[12] = tmp;
23787         tmp = te[7]; te[7] = te[13]; te[13] = tmp;
23788         tmp = te[11]; te[11] = te[14]; te[14] = tmp;
23789
23790         return this;
23791
23792     },
23793
23794     flattenToArray: function ( flat ) {
23795
23796         var te = this.elements;
23797         flat[ 0 ] = te[0]; flat[ 1 ] = te[1]; flat[ 2 ] = te[2]; flat[ 3 ] = te[3];
23798         flat[ 4 ] = te[4]; flat[ 5 ] = te[5]; flat[ 6 ] = te[6]; flat[ 7 ] = te[7];
23799         flat[ 8 ]  = te[8]; flat[ 9 ]  = te[9]; flat[ 10 ] = te[10]; flat[ 11 ] = te[11];
23800         flat[ 12 ] = te[12]; flat[ 13 ] = te[13]; flat[ 14 ] = te[14]; flat[ 15 ] = te[15];
23801
23802         return flat;
23803
23804     },
23805
23806     flattenToArrayOffset: function( flat, offset ) {
23807
23808         var te = this.elements;
23809         flat[ offset ] = te[0];
23810         flat[ offset + 1 ] = te[1];
23811         flat[ offset + 2 ] = te[2];
23812         flat[ offset + 3 ] = te[3];
23813
23814         flat[ offset + 4 ] = te[4];
23815         flat[ offset + 5 ] = te[5];
23816         flat[ offset + 6 ] = te[6];
23817         flat[ offset + 7 ] = te[7];
23818
23819         flat[ offset + 8 ]  = te[8];
23820         flat[ offset + 9 ]  = te[9];
23821         flat[ offset + 10 ] = te[10];
23822         flat[ offset + 11 ] = te[11];
23823
23824         flat[ offset + 12 ] = te[12];
23825         flat[ offset + 13 ] = te[13];
23826         flat[ offset + 14 ] = te[14];
23827         flat[ offset + 15 ] = te[15];
23828
23829         return flat;
23830
23831     },
23832
23833     getPosition: function () {
23834
23835         var te = this.elements;
23836         return THREE.Matrix4.__v1.set( te[12], te[13], te[14] );
23837
23838     },
23839
23840     setPosition: function ( v ) {
23841
23842         var te = this.elements;
23843
23844         te[12] = v.x;
23845         te[13] = v.y;
23846         te[14] = v.z;
23847
23848         return this;
23849
23850     },
23851
23852     getColumnX: function () {
23853
23854         var te = this.elements;
23855         return THREE.Matrix4.__v1.set( te[0], te[1], te[2] );
23856
23857     },
23858
23859     getColumnY: function () {
23860
23861         var te = this.elements;
23862         return THREE.Matrix4.__v1.set( te[4], te[5], te[6] );
23863
23864     },
23865
23866     getColumnZ: function() {
23867
23868         var te = this.elements;
23869         return THREE.Matrix4.__v1.set( te[8], te[9], te[10] );
23870
23871     },
23872
23873     getInverse: function ( m ) {
23874
23875         // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
23876         var te = this.elements;
23877         var me = m.elements;
23878
23879         var n11 = me[0], n12 = me[4], n13 = me[8], n14 = me[12];
23880         var n21 = me[1], n22 = me[5], n23 = me[9], n24 = me[13];
23881         var n31 = me[2], n32 = me[6], n33 = me[10], n34 = me[14];
23882         var n41 = me[3], n42 = me[7], n43 = me[11], n44 = me[15];
23883
23884         te[0] = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
23885         te[4] = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
23886         te[8] = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44;
23887         te[12] = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34;
23888         te[1] = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44;
23889         te[5] = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44;
23890         te[9] = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44;
23891         te[13] = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34;
23892         te[2] = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44;
23893         te[6] = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44;
23894         te[10] = n12*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44;
23895         te[14] = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34;
23896         te[3] = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43;
23897         te[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
23898         te[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
23899         te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
23900         this.multiplyScalar( 1 / m.determinant() );
23901
23902         return this;
23903
23904     },
23905
23906     setRotationFromEuler: function ( v, order ) {
23907
23908         var te = this.elements;
23909
23910         var x = v.x, y = v.y, z = v.z;
23911         var a = Math.cos( x ), b = Math.sin( x );
23912         var c = Math.cos( y ), d = Math.sin( y );
23913         var e = Math.cos( z ), f = Math.sin( z );
23914
23915         if ( order === undefined || order === 'XYZ' ) {
23916
23917             var ae = a * e, af = a * f, be = b * e, bf = b * f;
23918
23919             te[0] = c * e;
23920             te[4] = - c * f;
23921             te[8] = d;
23922
23923             te[1] = af + be * d;
23924             te[5] = ae - bf * d;
23925             te[9] = - b * c;
23926
23927             te[2] = bf - ae * d;
23928             te[6] = be + af * d;
23929             te[10] = a * c;
23930
23931         } else if ( order === 'YXZ' ) {
23932
23933             var ce = c * e, cf = c * f, de = d * e, df = d * f;
23934
23935             te[0] = ce + df * b;
23936             te[4] = de * b - cf;
23937             te[8] = a * d;
23938
23939             te[1] = a * f;
23940             te[5] = a * e;
23941             te[9] = - b;
23942
23943             te[2] = cf * b - de;
23944             te[6] = df + ce * b;
23945             te[10] = a * c;
23946
23947         } else if ( order === 'ZXY' ) {
23948
23949             var ce = c * e, cf = c * f, de = d * e, df = d * f;
23950
23951             te[0] = ce - df * b;
23952             te[4] = - a * f;
23953             te[8] = de + cf * b;
23954
23955             te[1] = cf + de * b;
23956             te[5] = a * e;
23957             te[9] = df - ce * b;
23958
23959             te[2] = - a * d;
23960             te[6] = b;
23961             te[10] = a * c;
23962
23963         } else if ( order === 'ZYX' ) {
23964
23965             var ae = a * e, af = a * f, be = b * e, bf = b * f;
23966
23967             te[0] = c * e;
23968             te[4] = be * d - af;
23969             te[8] = ae * d + bf;
23970
23971             te[1] = c * f;
23972             te[5] = bf * d + ae;
23973             te[9] = af * d - be;
23974
23975             te[2] = - d;
23976             te[6] = b * c;
23977             te[10] = a * c;
23978
23979         } else if ( order === 'YZX' ) {
23980
23981             var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
23982
23983             te[0] = c * e;
23984             te[4] = bd - ac * f;
23985             te[8] = bc * f + ad;
23986
23987             te[1] = f;
23988             te[5] = a * e;
23989             te[9] = - b * e;
23990
23991             te[2] = - d * e;
23992             te[6] = ad * f + bc;
23993             te[10] = ac - bd * f;
23994
23995         } else if ( order === 'XZY' ) {
23996
23997             var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
23998
23999             te[0] = c * e;
24000             te[4] = - f;
24001             te[8] = d * e;
24002
24003             te[1] = ac * f + bd;
24004             te[5] = a * e;
24005             te[9] = ad * f - bc;
24006
24007             te[2] = bc * f - ad;
24008             te[6] = b * e;
24009             te[10] = bd * f + ac;
24010
24011         }
24012
24013         return this;
24014
24015     },
24016
24017
24018     setRotationFromQuaternion: function ( q ) {
24019
24020         var te = this.elements;
24021
24022         var x = q.x, y = q.y, z = q.z, w = q.w;
24023         var x2 = x + x, y2 = y + y, z2 = z + z;
24024         var xx = x * x2, xy = x * y2, xz = x * z2;
24025         var yy = y * y2, yz = y * z2, zz = z * z2;
24026         var wx = w * x2, wy = w * y2, wz = w * z2;
24027
24028         te[0] = 1 - ( yy + zz );
24029         te[4] = xy - wz;
24030         te[8] = xz + wy;
24031
24032         te[1] = xy + wz;
24033         te[5] = 1 - ( xx + zz );
24034         te[9] = yz - wx;
24035
24036         te[2] = xz - wy;
24037         te[6] = yz + wx;
24038         te[10] = 1 - ( xx + yy );
24039
24040         return this;
24041
24042     },
24043
24044     compose: function ( translation, rotation, scale ) {
24045
24046         var te = this.elements;
24047         var mRotation = THREE.Matrix4.__m1;
24048         var mScale = THREE.Matrix4.__m2;
24049
24050         mRotation.identity();
24051         mRotation.setRotationFromQuaternion( rotation );
24052
24053         mScale.makeScale( scale.x, scale.y, scale.z );
24054
24055         this.multiply( mRotation, mScale );
24056
24057         te[12] = translation.x;
24058         te[13] = translation.y;
24059         te[14] = translation.z;
24060
24061         return this;
24062
24063     },
24064
24065     decompose: function ( translation, rotation, scale ) {
24066
24067         var te = this.elements;
24068
24069         // grab the axis vectors
24070         var x = THREE.Matrix4.__v1;
24071         var y = THREE.Matrix4.__v2;
24072         var z = THREE.Matrix4.__v3;
24073
24074         x.set( te[0], te[1], te[2] );
24075         y.set( te[4], te[5], te[6] );
24076         z.set( te[8], te[9], te[10] );
24077
24078         translation = ( translation instanceof THREE.Vector3 ) ? translation : new THREE.Vector3();
24079         rotation = ( rotation instanceof THREE.Quaternion ) ? rotation : new THREE.Quaternion();
24080         scale = ( scale instanceof THREE.Vector3 ) ? scale : new THREE.Vector3();
24081
24082         scale.x = x.length();
24083         scale.y = y.length();
24084         scale.z = z.length();
24085
24086         translation.x = te[12];
24087         translation.y = te[13];
24088         translation.z = te[14];
24089
24090         // scale the rotation part
24091
24092         var matrix = THREE.Matrix4.__m1;
24093
24094         matrix.copy( this );
24095
24096         matrix.elements[0] /= scale.x;
24097         matrix.elements[1] /= scale.x;
24098         matrix.elements[2] /= scale.x;
24099
24100         matrix.elements[4] /= scale.y;
24101         matrix.elements[5] /= scale.y;
24102         matrix.elements[6] /= scale.y;
24103
24104         matrix.elements[8] /= scale.z;
24105         matrix.elements[9] /= scale.z;
24106         matrix.elements[10] /= scale.z;
24107
24108         rotation.setFromRotationMatrix( matrix );
24109
24110         return [ translation, rotation, scale ];
24111
24112     },
24113
24114     extractPosition: function ( m ) {
24115
24116         var te = this.elements;
24117         var me = m.elements;
24118
24119         te[12] = me[12];
24120         te[13] = me[13];
24121         te[14] = me[14];
24122
24123         return this;
24124
24125     },
24126
24127     extractRotation: function ( m ) {
24128
24129         var te = this.elements;
24130         var me = m.elements;
24131
24132         var vector = THREE.Matrix4.__v1;
24133
24134         var scaleX = 1 / vector.set( me[0], me[1], me[2] ).length();
24135         var scaleY = 1 / vector.set( me[4], me[5], me[6] ).length();
24136         var scaleZ = 1 / vector.set( me[8], me[9], me[10] ).length();
24137
24138         te[0] = me[0] * scaleX;
24139         te[1] = me[1] * scaleX;
24140         te[2] = me[2] * scaleX;
24141
24142         te[4] = me[4] * scaleY;
24143         te[5] = me[5] * scaleY;
24144         te[6] = me[6] * scaleY;
24145
24146         te[8] = me[8] * scaleZ;
24147         te[9] = me[9] * scaleZ;
24148         te[10] = me[10] * scaleZ;
24149
24150         return this;
24151
24152     },
24153
24154     //
24155
24156     translate: function ( v ) {
24157
24158         var te = this.elements;
24159         var x = v.x, y = v.y, z = v.z;
24160
24161         te[12] = te[0] * x + te[4] * y + te[8] * z + te[12];
24162         te[13] = te[1] * x + te[5] * y + te[9] * z + te[13];
24163         te[14] = te[2] * x + te[6] * y + te[10] * z + te[14];
24164         te[15] = te[3] * x + te[7] * y + te[11] * z + te[15];
24165
24166         return this;
24167
24168     },
24169
24170     rotateX: function ( angle ) {
24171
24172         var te = this.elements;
24173         var m12 = te[4];
24174         var m22 = te[5];
24175         var m32 = te[6];
24176         var m42 = te[7];
24177         var m13 = te[8];
24178         var m23 = te[9];
24179         var m33 = te[10];
24180         var m43 = te[11];
24181         var c = Math.cos( angle );
24182         var s = Math.sin( angle );
24183
24184         te[4] = c * m12 + s * m13;
24185         te[5] = c * m22 + s * m23;
24186         te[6] = c * m32 + s * m33;
24187         te[7] = c * m42 + s * m43;
24188
24189         te[8] = c * m13 - s * m12;
24190         te[9] = c * m23 - s * m22;
24191         te[10] = c * m33 - s * m32;
24192         te[11] = c * m43 - s * m42;
24193
24194         return this;
24195
24196     },
24197
24198     rotateY: function ( angle ) {
24199
24200         var te = this.elements;
24201         var m11 = te[0];
24202         var m21 = te[1];
24203         var m31 = te[2];
24204         var m41 = te[3];
24205         var m13 = te[8];
24206         var m23 = te[9];
24207         var m33 = te[10];
24208         var m43 = te[11];
24209         var c = Math.cos( angle );
24210         var s = Math.sin( angle );
24211
24212         te[0] = c * m11 - s * m13;
24213         te[1] = c * m21 - s * m23;
24214         te[2] = c * m31 - s * m33;
24215         te[3] = c * m41 - s * m43;
24216
24217         te[8] = c * m13 + s * m11;
24218         te[9] = c * m23 + s * m21;
24219         te[10] = c * m33 + s * m31;
24220         te[11] = c * m43 + s * m41;
24221
24222         return this;
24223
24224     },
24225
24226     rotateZ: function ( angle ) {
24227
24228         var te = this.elements;
24229         var m11 = te[0];
24230         var m21 = te[1];
24231         var m31 = te[2];
24232         var m41 = te[3];
24233         var m12 = te[4];
24234         var m22 = te[5];
24235         var m32 = te[6];
24236         var m42 = te[7];
24237         var c = Math.cos( angle );
24238         var s = Math.sin( angle );
24239
24240         te[0] = c * m11 + s * m12;
24241         te[1] = c * m21 + s * m22;
24242         te[2] = c * m31 + s * m32;
24243         te[3] = c * m41 + s * m42;
24244
24245         te[4] = c * m12 - s * m11;
24246         te[5] = c * m22 - s * m21;
24247         te[6] = c * m32 - s * m31;
24248         te[7] = c * m42 - s * m41;
24249
24250         return this;
24251
24252     },
24253
24254     rotateByAxis: function ( axis, angle ) {
24255
24256         var te = this.elements;
24257
24258         // optimize by checking axis
24259
24260         if ( axis.x === 1 && axis.y === 0 && axis.z === 0 ) {
24261
24262             return this.rotateX( angle );
24263
24264         } else if ( axis.x === 0 && axis.y === 1 && axis.z === 0 ) {
24265
24266             return this.rotateY( angle );
24267
24268         } else if ( axis.x === 0 && axis.y === 0 && axis.z === 1 ) {
24269
24270             return this.rotateZ( angle );
24271
24272         }
24273
24274         var x = axis.x, y = axis.y, z = axis.z;
24275         var n = Math.sqrt(x * x + y * y + z * z);
24276
24277         x /= n;
24278         y /= n;
24279         z /= n;
24280
24281         var xx = x * x, yy = y * y, zz = z * z;
24282         var c = Math.cos( angle );
24283         var s = Math.sin( angle );
24284         var oneMinusCosine = 1 - c;
24285         var xy = x * y * oneMinusCosine;
24286         var xz = x * z * oneMinusCosine;
24287         var yz = y * z * oneMinusCosine;
24288         var xs = x * s;
24289         var ys = y * s;
24290         var zs = z * s;
24291
24292         var r11 = xx + (1 - xx) * c;
24293         var r21 = xy + zs;
24294         var r31 = xz - ys;
24295         var r12 = xy - zs;
24296         var r22 = yy + (1 - yy) * c;
24297         var r32 = yz + xs;
24298         var r13 = xz + ys;
24299         var r23 = yz - xs;
24300         var r33 = zz + (1 - zz) * c;
24301
24302         var m11 = te[0], m21 = te[1], m31 = te[2], m41 = te[3];
24303         var m12 = te[4], m22 = te[5], m32 = te[6], m42 = te[7];
24304         var m13 = te[8], m23 = te[9], m33 = te[10], m43 = te[11];
24305         var m14 = te[12], m24 = te[13], m34 = te[14], m44 = te[15];
24306
24307         te[0] = r11 * m11 + r21 * m12 + r31 * m13;
24308         te[1] = r11 * m21 + r21 * m22 + r31 * m23;
24309         te[2] = r11 * m31 + r21 * m32 + r31 * m33;
24310         te[3] = r11 * m41 + r21 * m42 + r31 * m43;
24311
24312         te[4] = r12 * m11 + r22 * m12 + r32 * m13;
24313         te[5] = r12 * m21 + r22 * m22 + r32 * m23;
24314         te[6] = r12 * m31 + r22 * m32 + r32 * m33;
24315         te[7] = r12 * m41 + r22 * m42 + r32 * m43;
24316
24317         te[8] = r13 * m11 + r23 * m12 + r33 * m13;
24318         te[9] = r13 * m21 + r23 * m22 + r33 * m23;
24319         te[10] = r13 * m31 + r23 * m32 + r33 * m33;
24320         te[11] = r13 * m41 + r23 * m42 + r33 * m43;
24321
24322         return this;
24323
24324     },
24325
24326     scale: function ( v ) {
24327
24328         var te = this.elements;
24329         var x = v.x, y = v.y, z = v.z;
24330
24331         te[0] *= x; te[4] *= y; te[8] *= z;
24332         te[1] *= x; te[5] *= y; te[9] *= z;
24333         te[2] *= x; te[6] *= y; te[10] *= z;
24334         te[3] *= x; te[7] *= y; te[11] *= z;
24335
24336         return this;
24337
24338     },
24339
24340     getMaxScaleOnAxis: function () {
24341
24342         var te = this.elements;
24343
24344         var scaleXSq =  te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
24345         var scaleYSq =  te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
24346         var scaleZSq =  te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
24347
24348         return Math.sqrt( Math.max( scaleXSq, Math.max( scaleYSq, scaleZSq ) ) );
24349
24350     },
24351
24352     //
24353
24354     makeTranslation: function ( x, y, z ) {
24355
24356         this.set(
24357
24358             1, 0, 0, x,
24359             0, 1, 0, y,
24360             0, 0, 1, z,
24361             0, 0, 0, 1
24362
24363         );
24364
24365         return this;
24366
24367     },
24368
24369     makeRotationX: function ( theta ) {
24370
24371         var c = Math.cos( theta ), s = Math.sin( theta );
24372
24373         this.set(
24374
24375             1, 0,  0, 0,
24376             0, c, -s, 0,
24377             0, s,  c, 0,
24378             0, 0,  0, 1
24379
24380         );
24381
24382         return this;
24383
24384     },
24385
24386     makeRotationY: function ( theta ) {
24387
24388         var c = Math.cos( theta ), s = Math.sin( theta );
24389
24390         this.set(
24391
24392              c, 0, s, 0,
24393              0, 1, 0, 0,
24394             -s, 0, c, 0,
24395              0, 0, 0, 1
24396
24397         );
24398
24399         return this;
24400
24401     },
24402
24403     makeRotationZ: function ( theta ) {
24404
24405         var c = Math.cos( theta ), s = Math.sin( theta );
24406
24407         this.set(
24408
24409             c, -s, 0, 0,
24410             s,  c, 0, 0,
24411             0,  0, 1, 0,
24412             0,  0, 0, 1
24413
24414         );
24415
24416         return this;
24417
24418     },
24419
24420     makeRotationAxis: function ( axis, angle ) {
24421
24422         // Based on http://www.gamedev.net/reference/articles/article1199.asp
24423
24424         var c = Math.cos( angle );
24425         var s = Math.sin( angle );
24426         var t = 1 - c;
24427         var x = axis.x, y = axis.y, z = axis.z;
24428         var tx = t * x, ty = t * y;
24429
24430         this.set(
24431
24432             tx * x + c, tx * y - s * z, tx * z + s * y, 0,
24433             tx * y + s * z, ty * y + c, ty * z - s * x, 0,
24434             tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
24435             0, 0, 0, 1
24436
24437         );
24438
24439          return this;
24440
24441     },
24442
24443     makeScale: function ( x, y, z ) {
24444
24445         this.set(
24446
24447             x, 0, 0, 0,
24448             0, y, 0, 0,
24449             0, 0, z, 0,
24450             0, 0, 0, 1
24451
24452         );
24453
24454         return this;
24455
24456     },
24457
24458     makeFrustum: function ( left, right, bottom, top, near, far ) {
24459
24460         var te = this.elements;
24461         var x = 2 * near / ( right - left );
24462         var y = 2 * near / ( top - bottom );
24463
24464         var a = ( right + left ) / ( right - left );
24465         var b = ( top + bottom ) / ( top - bottom );
24466         var c = - ( far + near ) / ( far - near );
24467         var d = - 2 * far * near / ( far - near );
24468
24469         te[0] = x;  te[4] = 0;  te[8] = a;   te[12] = 0;
24470         te[1] = 0;  te[5] = y;  te[9] = b;   te[13] = 0;
24471         te[2] = 0;  te[6] = 0;  te[10] = c;   te[14] = d;
24472         te[3] = 0;  te[7] = 0;  te[11] = - 1; te[15] = 0;
24473
24474         return this;
24475
24476     },
24477
24478     makePerspective: function ( fov, aspect, near, far ) {
24479
24480         var ymax = near * Math.tan( fov * Math.PI / 360 );
24481         var ymin = - ymax;
24482         var xmin = ymin * aspect;
24483         var xmax = ymax * aspect;
24484
24485         return this.makeFrustum( xmin, xmax, ymin, ymax, near, far );
24486
24487     },
24488
24489     makeOrthographic: function ( left, right, top, bottom, near, far ) {
24490
24491         var te = this.elements;
24492         var w = right - left;
24493         var h = top - bottom;
24494         var p = far - near;
24495
24496         var x = ( right + left ) / w;
24497         var y = ( top + bottom ) / h;
24498         var z = ( far + near ) / p;
24499
24500         te[0] = 2 / w; te[4] = 0;     te[8] = 0;      te[12] = -x;
24501         te[1] = 0;     te[5] = 2 / h; te[9] = 0;      te[13] = -y;
24502         te[2] = 0;     te[6] = 0;     te[10] = -2 / p; te[14] = -z;
24503         te[3] = 0;     te[7] = 0;     te[11] = 0;      te[15] = 1;
24504
24505         return this;
24506
24507     },
24508
24509
24510     clone: function () {
24511
24512         var te = this.elements;
24513
24514         return new THREE.Matrix4(
24515
24516             te[0], te[4], te[8], te[12],
24517             te[1], te[5], te[9], te[13],
24518             te[2], te[6], te[10], te[14],
24519             te[3], te[7], te[11], te[15]
24520
24521         );
24522
24523     }
24524
24525 };
24526
24527 THREE.Matrix4.__v1 = new THREE.Vector3();
24528 THREE.Matrix4.__v2 = new THREE.Vector3();
24529 THREE.Matrix4.__v3 = new THREE.Vector3();
24530
24531 THREE.Matrix4.__m1 = new THREE.Matrix4();
24532 THREE.Matrix4.__m2 = new THREE.Matrix4();
24533 /**
24534  * https://github.com/mrdoob/eventtarget.js/
24535  */
24536
24537 THREE.EventTarget = function () {
24538
24539     var listeners = {};
24540
24541     this.addEventListener = function ( type, listener ) {
24542
24543         if ( listeners[ type ] === undefined ) {
24544
24545             listeners[ type ] = [];
24546
24547         }
24548
24549         if ( listeners[ type ].indexOf( listener ) === - 1 ) {
24550
24551             listeners[ type ].push( listener );
24552
24553         }
24554
24555     };
24556
24557     this.dispatchEvent = function ( event ) {
24558
24559         for ( var listener in listeners[ event.type ] ) {
24560
24561             listeners[ event.type ][ listener ]( event );
24562
24563         }
24564
24565     };
24566
24567     this.removeEventListener = function ( type, listener ) {
24568
24569         var index = listeners[ type ].indexOf( listener );
24570
24571         if ( index !== - 1 ) {
24572
24573             listeners[ type ].splice( index, 1 );
24574
24575         }
24576
24577     };
24578
24579 };
24580 /**
24581  * @author mrdoob / http://mrdoob.com/
24582  * @author alteredq / http://alteredqualia.com/
24583  */
24584
24585 THREE.Frustum = function ( ) {
24586
24587     this.planes = [
24588
24589         new THREE.Vector4(),
24590         new THREE.Vector4(),
24591         new THREE.Vector4(),
24592         new THREE.Vector4(),
24593         new THREE.Vector4(),
24594         new THREE.Vector4()
24595
24596     ];
24597
24598 };
24599
24600 THREE.Frustum.prototype.setFromMatrix = function ( m ) {
24601
24602     var plane;
24603     var planes = this.planes;
24604
24605     var me = m.elements;
24606     var me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3];
24607     var me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7];
24608     var me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11];
24609     var me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15];
24610
24611     planes[ 0 ].set( me3 - me0, me7 - me4, me11 - me8, me15 - me12 );
24612     planes[ 1 ].set( me3 + me0, me7 + me4, me11 + me8, me15 + me12 );
24613     planes[ 2 ].set( me3 + me1, me7 + me5, me11 + me9, me15 + me13 );
24614     planes[ 3 ].set( me3 - me1, me7 - me5, me11 - me9, me15 - me13 );
24615     planes[ 4 ].set( me3 - me2, me7 - me6, me11 - me10, me15 - me14 );
24616     planes[ 5 ].set( me3 + me2, me7 + me6, me11 + me10, me15 + me14 );
24617
24618     for ( var i = 0; i < 6; i ++ ) {
24619
24620         plane = planes[ i ];
24621         plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );
24622
24623     }
24624
24625 };
24626
24627 THREE.Frustum.prototype.contains = function ( object ) {
24628
24629     var distance = 0.0;
24630     var planes = this.planes;
24631     var matrix = object.matrixWorld;
24632     var me = matrix.elements;
24633     var radius = - object.geometry.boundingSphere.radius * matrix.getMaxScaleOnAxis();
24634
24635     for ( var i = 0; i < 6; i ++ ) {
24636
24637         distance = planes[ i ].x * me[12] + planes[ i ].y * me[13] + planes[ i ].z * me[14] + planes[ i ].w;
24638         if ( distance <= radius ) return false;
24639
24640     }
24641
24642     return true;
24643
24644 };
24645
24646 THREE.Frustum.__v1 = new THREE.Vector3();
24647 /**
24648  * @author mrdoob / http://mrdoob.com/
24649  */
24650
24651 ( function ( THREE ) {
24652
24653     THREE.Ray = function ( origin, direction, near, far ) {
24654
24655         this.origin = origin || new THREE.Vector3();
24656         this.direction = direction || new THREE.Vector3();
24657         this.near = near || 0;
24658         this.far = far || Infinity;
24659
24660     };
24661
24662     var originCopy = new THREE.Vector3();
24663
24664     var localOriginCopy = new THREE.Vector3();
24665     var localDirectionCopy = new THREE.Vector3();
24666
24667     var vector = new THREE.Vector3();
24668     var normal = new THREE.Vector3();
24669     var intersectPoint = new THREE.Vector3();
24670
24671     var inverseMatrix = new THREE.Matrix4();
24672
24673     var descSort = function ( a, b ) {
24674
24675         return a.distance - b.distance;
24676
24677     };
24678
24679     var v0 = new THREE.Vector3(), v1 = new THREE.Vector3(), v2 = new THREE.Vector3();
24680
24681     var distanceFromIntersection = function ( origin, direction, position ) {
24682
24683         v0.sub( position, origin );
24684
24685         var dot = v0.dot( direction );
24686
24687         var intersect = v1.add( origin, v2.copy( direction ).multiplyScalar( dot ) );
24688         var distance = position.distanceTo( intersect );
24689
24690         return distance;
24691
24692     };
24693
24694     // http://www.blackpawn.com/texts/pointinpoly/default.html
24695
24696     var pointInFace3 = function ( p, a, b, c ) {
24697
24698         v0.sub( c, a );
24699         v1.sub( b, a );
24700         v2.sub( p, a );
24701
24702         var dot00 = v0.dot( v0 );
24703         var dot01 = v0.dot( v1 );
24704         var dot02 = v0.dot( v2 );
24705         var dot11 = v1.dot( v1 );
24706         var dot12 = v1.dot( v2 );
24707
24708         var invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
24709         var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
24710         var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
24711
24712         return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );
24713
24714     };
24715
24716     var intersectObject = function ( object, ray, intersects ) {
24717
24718         var distance,intersect;
24719
24720         if ( object instanceof THREE.Particle ) {
24721
24722             distance = distanceFromIntersection( ray.origin, ray.direction, object.matrixWorld.getPosition() );
24723
24724             if ( distance > object.scale.x ) {
24725
24726                 return intersects;
24727
24728             }
24729
24730             intersect = {
24731
24732                 distance: distance,
24733                 point: object.position,
24734                 face: null,
24735                 object: object
24736
24737             };
24738
24739             intersects.push( intersect );
24740
24741         } else if ( object instanceof THREE.Mesh ) {
24742
24743             // Checking boundingSphere
24744
24745             var scaledRadius = object.geometry.boundingSphere.radius * object.matrixWorld.getMaxScaleOnAxis();
24746
24747             // Checking distance to ray
24748
24749             distance = distanceFromIntersection( ray.origin, ray.direction, object.matrixWorld.getPosition() );
24750
24751             if ( distance > scaledRadius) {
24752
24753                 return intersects;
24754
24755             }
24756
24757             // Checking faces
24758
24759             var f, fl, face, dot, scalar,
24760             geometry = object.geometry,
24761             vertices = geometry.vertices,
24762             objMatrix, geometryMaterials,
24763             isFaceMaterial, material, side, point;
24764
24765             geometryMaterials = object.geometry.materials;
24766             isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
24767             side = object.material.side;
24768
24769             var a, b, c, d;
24770             var precision = ray.precision;
24771
24772             object.matrixRotationWorld.extractRotation( object.matrixWorld );
24773
24774             originCopy.copy( ray.origin );
24775
24776             objMatrix = object.matrixWorld;
24777             inverseMatrix.getInverse( objMatrix );
24778
24779             localOriginCopy.copy( originCopy );
24780             inverseMatrix.multiplyVector3( localOriginCopy );
24781
24782             localDirectionCopy.copy( ray.direction );
24783             inverseMatrix.rotateAxis( localDirectionCopy ).normalize();
24784
24785             for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
24786
24787                 face = geometry.faces[ f ];
24788
24789                 material = isFaceMaterial === true ? geometryMaterials[ face.materialIndex ] : object.material;
24790                 if ( material === undefined ) continue;
24791                 side = material.side;
24792
24793                 vector.sub( face.centroid, localOriginCopy );
24794                 normal = face.normal;
24795                 dot = localDirectionCopy.dot( normal );
24796
24797                 // bail if ray and plane are parallel
24798
24799                 if ( Math.abs( dot ) < precision ) continue;
24800
24801                 // calc distance to plane
24802
24803                 scalar = normal.dot( vector ) / dot;
24804
24805                 // if negative distance, then plane is behind ray
24806
24807                 if ( scalar < 0 ) continue;
24808
24809                 if ( side === THREE.DoubleSide || ( side === THREE.FrontSide ? dot < 0 : dot > 0 ) ) {
24810
24811                     intersectPoint.add( localOriginCopy, localDirectionCopy.multiplyScalar( scalar ) );
24812
24813                     if ( face instanceof THREE.Face3 ) {
24814
24815                         a = vertices[ face.a ];
24816                         b = vertices[ face.b ];
24817                         c = vertices[ face.c ];
24818
24819                         if ( pointInFace3( intersectPoint, a, b, c ) ) {
24820
24821                             point = object.matrixWorld.multiplyVector3( intersectPoint.clone() );
24822                             distance = originCopy.distanceTo( point );
24823
24824                             if ( distance < ray.near || distance > ray.far ) continue;
24825
24826                             intersect = {
24827
24828                                 distance: distance,
24829                                 point: point,
24830                                 face: face,
24831                                 faceIndex: f,
24832                                 object: object
24833
24834                             };
24835
24836                             intersects.push( intersect );
24837
24838                         }
24839
24840                     } else if ( face instanceof THREE.Face4 ) {
24841
24842                         a = vertices[ face.a ];
24843                         b = vertices[ face.b ];
24844                         c = vertices[ face.c ];
24845                         d = vertices[ face.d ];
24846
24847                         if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {
24848
24849                             point = object.matrixWorld.multiplyVector3( intersectPoint.clone() );
24850                             distance = originCopy.distanceTo( point );
24851
24852                             if ( distance < ray.near || distance > ray.far ) continue;
24853
24854                             intersect = {
24855
24856                                 distance: distance,
24857                                 point: point,
24858                                 face: face,
24859                                 faceIndex: f,
24860                                 object: object
24861
24862                             };
24863
24864                             intersects.push( intersect );
24865
24866                         }
24867
24868                     }
24869
24870                 }
24871
24872             }
24873
24874         }
24875
24876     };
24877
24878     var intersectDescendants = function ( object, ray, intersects ) {
24879
24880         var descendants = object.getDescendants();
24881
24882         for ( var i = 0, l = descendants.length; i < l; i ++ ) {
24883
24884             intersectObject( descendants[ i ], ray, intersects );
24885
24886         }
24887     };
24888
24889     //
24890
24891     THREE.Ray.prototype.precision = 0.0001;
24892
24893     THREE.Ray.prototype.set = function ( origin, direction ) {
24894
24895         this.origin = origin;
24896         this.direction = direction;
24897
24898     };
24899
24900     THREE.Ray.prototype.intersectObject = function ( object, recursive ) {
24901
24902         var intersects = [];
24903
24904         if ( recursive === true ) {
24905
24906             intersectDescendants( object, this, intersects );
24907
24908         }
24909
24910         intersectObject( object, this, intersects );
24911
24912         intersects.sort( descSort );
24913
24914         return intersects;
24915
24916     };
24917
24918     THREE.Ray.prototype.intersectObjects = function ( objects, recursive ) {
24919
24920         var intersects = [];
24921
24922         for ( var i = 0, l = objects.length; i < l; i ++ ) {
24923
24924             intersectObject( objects[ i ], this, intersects );
24925
24926             if ( recursive === true ) {
24927
24928                 intersectDescendants( objects[ i ], this, intersects );
24929
24930             }
24931         }
24932
24933         intersects.sort( descSort );
24934
24935         return intersects;
24936
24937     };
24938
24939 }( THREE ) );
24940 /**
24941  * @author mrdoob / http://mrdoob.com/
24942  */
24943
24944 THREE.Rectangle = function () {
24945
24946     var _left = 0;
24947     var _top = 0;
24948     var _right = 0;
24949     var _bottom = 0;
24950     var _width = 0;
24951     var _height = 0;
24952     var _isEmpty = true;
24953
24954     function resize() {
24955
24956         _width = _right - _left;
24957         _height = _bottom - _top;
24958
24959     }
24960
24961     this.getX = function () {
24962
24963         return _left;
24964
24965     };
24966
24967     this.getY = function () {
24968
24969         return _top;
24970
24971     };
24972
24973     this.getWidth = function () {
24974
24975         return _width;
24976
24977     };
24978
24979     this.getHeight = function () {
24980
24981         return _height;
24982
24983     };
24984
24985     this.getLeft = function() {
24986
24987         return _left;
24988
24989     };
24990
24991     this.getTop = function() {
24992
24993         return _top;
24994
24995     };
24996
24997     this.getRight = function() {
24998
24999         return _right;
25000
25001     };
25002
25003     this.getBottom = function() {
25004
25005         return _bottom;
25006
25007     };
25008
25009     this.set = function ( left, top, right, bottom ) {
25010
25011         _isEmpty = false;
25012
25013         _left = left; _top = top;
25014         _right = right; _bottom = bottom;
25015
25016         resize();
25017
25018     };
25019
25020     this.addPoint = function ( x, y ) {
25021
25022         if ( _isEmpty === true ) {
25023
25024             _isEmpty = false;
25025             _left = x; _top = y;
25026             _right = x; _bottom = y;
25027
25028             resize();
25029
25030         } else {
25031
25032             _left = _left < x ? _left : x; // Math.min( _left, x );
25033             _top = _top < y ? _top : y; // Math.min( _top, y );
25034             _right = _right > x ? _right : x; // Math.max( _right, x );
25035             _bottom = _bottom > y ? _bottom : y; // Math.max( _bottom, y );
25036
25037             resize();
25038         }
25039
25040     };
25041
25042     this.add3Points = function ( x1, y1, x2, y2, x3, y3 ) {
25043
25044         if ( _isEmpty === true ) {
25045
25046             _isEmpty = false;
25047             _left = x1 < x2 ? ( x1 < x3 ? x1 : x3 ) : ( x2 < x3 ? x2 : x3 );
25048             _top = y1 < y2 ? ( y1 < y3 ? y1 : y3 ) : ( y2 < y3 ? y2 : y3 );
25049             _right = x1 > x2 ? ( x1 > x3 ? x1 : x3 ) : ( x2 > x3 ? x2 : x3 );
25050             _bottom = y1 > y2 ? ( y1 > y3 ? y1 : y3 ) : ( y2 > y3 ? y2 : y3 );
25051
25052             resize();
25053
25054         } else {
25055
25056             _left = x1 < x2 ? ( x1 < x3 ? ( x1 < _left ? x1 : _left ) : ( x3 < _left ? x3 : _left ) ) : ( x2 < x3 ? ( x2 < _left ? x2 : _left ) : ( x3 < _left ? x3 : _left ) );
25057             _top = y1 < y2 ? ( y1 < y3 ? ( y1 < _top ? y1 : _top ) : ( y3 < _top ? y3 : _top ) ) : ( y2 < y3 ? ( y2 < _top ? y2 : _top ) : ( y3 < _top ? y3 : _top ) );
25058             _right = x1 > x2 ? ( x1 > x3 ? ( x1 > _right ? x1 : _right ) : ( x3 > _right ? x3 : _right ) ) : ( x2 > x3 ? ( x2 > _right ? x2 : _right ) : ( x3 > _right ? x3 : _right ) );
25059             _bottom = y1 > y2 ? ( y1 > y3 ? ( y1 > _bottom ? y1 : _bottom ) : ( y3 > _bottom ? y3 : _bottom ) ) : ( y2 > y3 ? ( y2 > _bottom ? y2 : _bottom ) : ( y3 > _bottom ? y3 : _bottom ) );
25060
25061             resize();
25062
25063         };
25064
25065     };
25066
25067     this.addRectangle = function ( r ) {
25068
25069         if ( _isEmpty === true ) {
25070
25071             _isEmpty = false;
25072             _left = r.getLeft(); _top = r.getTop();
25073             _right = r.getRight(); _bottom = r.getBottom();
25074
25075             resize();
25076
25077         } else {
25078
25079             _left = _left < r.getLeft() ? _left : r.getLeft(); // Math.min(_left, r.getLeft() );
25080             _top = _top < r.getTop() ? _top : r.getTop(); // Math.min(_top, r.getTop() );
25081             _right = _right > r.getRight() ? _right : r.getRight(); // Math.max(_right, r.getRight() );
25082             _bottom = _bottom > r.getBottom() ? _bottom : r.getBottom(); // Math.max(_bottom, r.getBottom() );
25083
25084             resize();
25085
25086         }
25087
25088     };
25089
25090     this.inflate = function ( v ) {
25091
25092         _left -= v; _top -= v;
25093         _right += v; _bottom += v;
25094
25095         resize();
25096
25097     };
25098
25099     this.minSelf = function ( r ) {
25100
25101         _left = _left > r.getLeft() ? _left : r.getLeft(); // Math.max( _left, r.getLeft() );
25102         _top = _top > r.getTop() ? _top : r.getTop(); // Math.max( _top, r.getTop() );
25103         _right = _right < r.getRight() ? _right : r.getRight(); // Math.min( _right, r.getRight() );
25104         _bottom = _bottom < r.getBottom() ? _bottom : r.getBottom(); // Math.min( _bottom, r.getBottom() );
25105
25106         resize();
25107
25108     };
25109
25110     this.intersects = function ( r ) {
25111
25112         // http://gamemath.com/2011/09/detecting-whether-two-boxes-overlap/
25113
25114         if ( _right < r.getLeft() ) return false;
25115         if ( _left > r.getRight() ) return false;
25116         if ( _bottom < r.getTop() ) return false;
25117         if ( _top > r.getBottom() ) return false;
25118
25119         return true;
25120
25121     };
25122
25123     this.empty = function () {
25124
25125         _isEmpty = true;
25126
25127         _left = 0; _top = 0;
25128         _right = 0; _bottom = 0;
25129
25130         resize();
25131
25132     };
25133
25134     this.isEmpty = function () {
25135
25136         return _isEmpty;
25137
25138     };
25139
25140 };
25141 /**
25142  * @author alteredq / http://alteredqualia.com/
25143  */
25144
25145 THREE.Math = {
25146
25147     // Clamp value to range <a, b>
25148
25149     clamp: function ( x, a, b ) {
25150
25151         return ( x < a ) ? a : ( ( x > b ) ? b : x );
25152
25153     },
25154
25155     // Clamp value to range <a, inf)
25156
25157     clampBottom: function ( x, a ) {
25158
25159         return x < a ? a : x;
25160
25161     },
25162
25163     // Linear mapping from range <a1, a2> to range <b1, b2>
25164
25165     mapLinear: function ( x, a1, a2, b1, b2 ) {
25166
25167         return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
25168
25169     },
25170
25171     // Random float from <0, 1> with 16 bits of randomness
25172     // (standard Math.random() creates repetitive patterns when applied over larger space)
25173
25174     random16: function () {
25175
25176         return ( 65280 * Math.random() + 255 * Math.random() ) / 65535;
25177
25178     },
25179
25180     // Random integer from <low, high> interval
25181
25182     randInt: function ( low, high ) {
25183
25184         return low + Math.floor( Math.random() * ( high - low + 1 ) );
25185
25186     },
25187
25188     // Random float from <low, high> interval
25189
25190     randFloat: function ( low, high ) {
25191
25192         return low + Math.random() * ( high - low );
25193
25194     },
25195
25196     // Random float from <-range/2, range/2> interval
25197
25198     randFloatSpread: function ( range ) {
25199
25200         return range * ( 0.5 - Math.random() );
25201
25202     },
25203
25204     sign: function ( x ) {
25205
25206         return ( x < 0 ) ? -1 : ( ( x > 0 ) ? 1 : 0 );
25207
25208     }
25209
25210 };
25211 /**
25212  * @author mrdoob / http://mrdoob.com/
25213  * @author mikael emtinger / http://gomo.se/
25214  * @author alteredq / http://alteredqualia.com/
25215  */
25216
25217 THREE.Object3D = function () {
25218
25219     this.id = THREE.Object3DCount ++;
25220
25221     this.name = '';
25222     this.properties = {};
25223
25224     this.parent = undefined;
25225     this.children = [];
25226
25227     this.up = new THREE.Vector3( 0, 1, 0 );
25228
25229     this.position = new THREE.Vector3();
25230     this.rotation = new THREE.Vector3();
25231     this.eulerOrder = 'XYZ';
25232     this.scale = new THREE.Vector3( 1, 1, 1 );
25233
25234     this.renderDepth = null;
25235
25236     this.rotationAutoUpdate = true;
25237
25238     this.matrix = new THREE.Matrix4();
25239     this.matrixWorld = new THREE.Matrix4();
25240     this.matrixRotationWorld = new THREE.Matrix4();
25241
25242     this.matrixAutoUpdate = true;
25243     this.matrixWorldNeedsUpdate = true;
25244
25245     this.quaternion = new THREE.Quaternion();
25246     this.useQuaternion = false;
25247
25248     this.boundRadius = 0.0;
25249     this.boundRadiusScale = 1.0;
25250
25251     this.visible = true;
25252
25253     this.castShadow = false;
25254     this.receiveShadow = false;
25255
25256     this.frustumCulled = true;
25257
25258     this._vector = new THREE.Vector3();
25259
25260 };
25261
25262
25263 THREE.Object3D.prototype = {
25264
25265     constructor: THREE.Object3D,
25266
25267     applyMatrix: function ( matrix ) {
25268
25269         this.matrix.multiply( matrix, this.matrix );
25270
25271         this.scale.getScaleFromMatrix( this.matrix );
25272
25273         var mat = new THREE.Matrix4().extractRotation( this.matrix );
25274         this.rotation.setEulerFromRotationMatrix( mat, this.eulerOrder );
25275
25276         this.position.getPositionFromMatrix( this.matrix );
25277
25278     },
25279
25280     translate: function ( distance, axis ) {
25281
25282         this.matrix.rotateAxis( axis );
25283         this.position.addSelf( axis.multiplyScalar( distance ) );
25284
25285     },
25286
25287     translateX: function ( distance ) {
25288
25289         this.translate( distance, this._vector.set( 1, 0, 0 ) );
25290
25291     },
25292
25293     translateY: function ( distance ) {
25294
25295         this.translate( distance, this._vector.set( 0, 1, 0 ) );
25296
25297     },
25298
25299     translateZ: function ( distance ) {
25300
25301         this.translate( distance, this._vector.set( 0, 0, 1 ) );
25302
25303     },
25304
25305     localToWorld: function ( vector ) {
25306
25307         return this.matrixWorld.multiplyVector3( vector );
25308
25309     },
25310
25311     worldToLocal: function ( vector ) {
25312
25313         return THREE.Object3D.__m1.getInverse( this.matrixWorld ).multiplyVector3( vector );
25314
25315     },
25316
25317     lookAt: function ( vector ) {
25318
25319         // TODO: Add hierarchy support.
25320
25321         this.matrix.lookAt( vector, this.position, this.up );
25322
25323         if ( this.rotationAutoUpdate ) {
25324
25325             this.rotation.setEulerFromRotationMatrix( this.matrix, this.eulerOrder );
25326
25327         }
25328
25329     },
25330
25331     add: function ( object ) {
25332
25333         if ( object === this ) {
25334
25335             console.warn( 'THREE.Object3D.add: An object can\'t be added as a child of itself.' );
25336             return;
25337
25338         }
25339
25340         if ( object instanceof THREE.Object3D ) {
25341
25342             if ( object.parent !== undefined ) {
25343
25344                 object.parent.remove( object );
25345
25346             }
25347
25348             object.parent = this;
25349             this.children.push( object );
25350
25351             // add to scene
25352
25353             var scene = this;
25354
25355             while ( scene.parent !== undefined ) {
25356
25357                 scene = scene.parent;
25358
25359             }
25360
25361             if ( scene !== undefined && scene instanceof THREE.Scene )  {
25362
25363                 scene.__addObject( object );
25364
25365             }
25366
25367         }
25368
25369     },
25370
25371     remove: function ( object ) {
25372
25373         var index = this.children.indexOf( object );
25374
25375         if ( index !== - 1 ) {
25376
25377             object.parent = undefined;
25378             this.children.splice( index, 1 );
25379
25380             // remove from scene
25381
25382             var scene = this;
25383
25384             while ( scene.parent !== undefined ) {
25385
25386                 scene = scene.parent;
25387
25388             }
25389
25390             if ( scene !== undefined && scene instanceof THREE.Scene ) {
25391
25392                 scene.__removeObject( object );
25393
25394             }
25395
25396         }
25397
25398     },
25399
25400     getChildByName: function ( name, recursive ) {
25401
25402         var c, cl, child;
25403
25404         for ( c = 0, cl = this.children.length; c < cl; c ++ ) {
25405
25406             child = this.children[ c ];
25407
25408             if ( child.name === name ) {
25409
25410                 return child;
25411
25412             }
25413
25414             if ( recursive ) {
25415
25416                 child = child.getChildByName( name, recursive );
25417
25418                 if ( child !== undefined ) {
25419
25420                     return child;
25421
25422                 }
25423
25424             }
25425
25426         }
25427
25428         return undefined;
25429
25430     },
25431
25432     getDescendants: function ( array ) {
25433
25434         if ( array === undefined ) array = [];
25435
25436         Array.prototype.push.apply( array, this.children );
25437
25438         for ( var i = 0, l = this.children.length; i < l; i ++ ) {
25439
25440             this.children[ i ].getDescendants( array );
25441
25442         };
25443
25444         return array;
25445
25446     },
25447
25448     updateMatrix: function () {
25449
25450         this.matrix.setPosition( this.position );
25451
25452         if ( this.useQuaternion === false )  {
25453
25454             this.matrix.setRotationFromEuler( this.rotation, this.eulerOrder );
25455
25456         } else {
25457
25458             this.matrix.setRotationFromQuaternion( this.quaternion );
25459
25460         }
25461
25462         if ( this.scale.x !== 1 || this.scale.y !== 1 || this.scale.z !== 1 ) {
25463
25464             this.matrix.scale( this.scale );
25465             this.boundRadiusScale = Math.max( this.scale.x, Math.max( this.scale.y, this.scale.z ) );
25466
25467         }
25468
25469         this.matrixWorldNeedsUpdate = true;
25470
25471     },
25472
25473     updateMatrixWorld: function ( force ) {
25474
25475         if ( this.matrixAutoUpdate === true ) this.updateMatrix();
25476
25477         if ( this.matrixWorldNeedsUpdate === true || force === true ) {
25478
25479             if ( this.parent === undefined ) {
25480
25481                 this.matrixWorld.copy( this.matrix );
25482
25483             } else {
25484
25485                 this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
25486
25487             }
25488
25489             this.matrixWorldNeedsUpdate = false;
25490
25491             force = true;
25492
25493         }
25494
25495         // update children
25496
25497         for ( var i = 0, l = this.children.length; i < l; i ++ ) {
25498
25499             this.children[ i ].updateMatrixWorld( force );
25500
25501         }
25502
25503     },
25504
25505     clone: function () {
25506
25507         // TODO
25508
25509     }
25510
25511 };
25512
25513 THREE.Object3D.__m1 = new THREE.Matrix4();
25514
25515 THREE.Object3DCount = 0;
25516 /**
25517  * @author mrdoob / http://mrdoob.com/
25518  * @author supereggbert / http://www.paulbrunt.co.uk/
25519  * @author julianwa / https://github.com/julianwa
25520  */
25521
25522 THREE.Projector = function() {
25523
25524     var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
25525     _vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,
25526     _face, _face3Count, _face3Pool = [], _face3PoolLength = 0,
25527     _face4Count, _face4Pool = [], _face4PoolLength = 0,
25528     _line, _lineCount, _linePool = [], _linePoolLength = 0,
25529     _particle, _particleCount, _particlePool = [], _particlePoolLength = 0,
25530
25531     _renderData = { objects: [], sprites: [], lights: [], elements: [] },
25532
25533     _vector3 = new THREE.Vector3(),
25534     _vector4 = new THREE.Vector4(),
25535
25536     _viewProjectionMatrix = new THREE.Matrix4(),
25537     _modelViewProjectionMatrix = new THREE.Matrix4(),
25538
25539     _frustum = new THREE.Frustum(),
25540
25541     _clippedVertex1PositionScreen = new THREE.Vector4(),
25542     _clippedVertex2PositionScreen = new THREE.Vector4(),
25543
25544     _face3VertexNormals;
25545
25546     this.projectVector = function ( vector, camera ) {
25547
25548         camera.matrixWorldInverse.getInverse( camera.matrixWorld );
25549
25550         _viewProjectionMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
25551         _viewProjectionMatrix.multiplyVector3( vector );
25552
25553         return vector;
25554
25555     };
25556
25557     this.unprojectVector = function ( vector, camera ) {
25558
25559         camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
25560
25561         _viewProjectionMatrix.multiply( camera.matrixWorld, camera.projectionMatrixInverse );
25562         _viewProjectionMatrix.multiplyVector3( vector );
25563
25564         return vector;
25565
25566     };
25567
25568     this.pickingRay = function ( vector, camera ) {
25569
25570         var end, ray, t;
25571
25572         // set two vectors with opposing z values
25573         vector.z = -1.0;
25574         end = new THREE.Vector3( vector.x, vector.y, 1.0 );
25575
25576         this.unprojectVector( vector, camera );
25577         this.unprojectVector( end, camera );
25578
25579         // find direction from vector to end
25580         end.subSelf( vector ).normalize();
25581
25582         return new THREE.Ray( vector, end );
25583
25584     };
25585
25586     var projectGraph = function ( root, sortObjects ) {
25587
25588         _objectCount = 0;
25589
25590         _renderData.objects.length = 0;
25591         _renderData.sprites.length = 0;
25592         _renderData.lights.length = 0;
25593
25594         var projectObject = function ( parent ) {
25595
25596             for ( var c = 0, cl = parent.children.length; c < cl; c ++ ) {
25597
25598                 var object = parent.children[ c ];
25599
25600                 if ( object.visible === false ) continue;
25601
25602                 if ( object instanceof THREE.Light ) {
25603
25604                     _renderData.lights.push( object );
25605
25606                 } else if ( object instanceof THREE.Mesh || object instanceof THREE.Line ) {
25607
25608                     if ( object.frustumCulled === false || _frustum.contains( object ) === true ) {
25609
25610                         _object = getNextObjectInPool();
25611                         _object.object = object;
25612
25613                         if ( object.renderDepth !== null ) {
25614
25615                             _object.z = object.renderDepth;
25616
25617                         } else {
25618
25619                             _vector3.copy( object.matrixWorld.getPosition() );
25620                             _viewProjectionMatrix.multiplyVector3( _vector3 );
25621                             _object.z = _vector3.z;
25622
25623                         }
25624
25625                         _renderData.objects.push( _object );
25626
25627                     }
25628
25629                 } else if ( object instanceof THREE.Sprite || object instanceof THREE.Particle ) {
25630
25631                     _object = getNextObjectInPool();
25632                     _object.object = object;
25633
25634                     // TODO: Find an elegant and performant solution and remove this dupe code.
25635
25636                     if ( object.renderDepth !== null ) {
25637
25638                         _object.z = object.renderDepth;
25639
25640                     } else {
25641
25642                         _vector3.copy( object.matrixWorld.getPosition() );
25643                         _viewProjectionMatrix.multiplyVector3( _vector3 );
25644                         _object.z = _vector3.z;
25645
25646                     }
25647
25648                     _renderData.sprites.push( _object );
25649
25650                 } else {
25651
25652                     _object = getNextObjectInPool();
25653                     _object.object = object;
25654
25655                     if ( object.renderDepth !== null ) {
25656
25657                         _object.z = object.renderDepth;
25658
25659                     } else {
25660
25661                         _vector3.copy( object.matrixWorld.getPosition() );
25662                         _viewProjectionMatrix.multiplyVector3( _vector3 );
25663                         _object.z = _vector3.z;
25664
25665                     }
25666
25667                     _renderData.objects.push( _object );
25668
25669                 }
25670
25671                 projectObject( object );
25672
25673             }
25674
25675         };
25676
25677         projectObject( root );
25678
25679         if ( sortObjects === true ) _renderData.objects.sort( painterSort );
25680
25681         return _renderData;
25682
25683     };
25684
25685     this.projectScene = function ( scene, camera, sortObjects, sortElements ) {
25686
25687         var near = camera.near, far = camera.far, visible = false,
25688         o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, object,
25689         modelMatrix, rotationMatrix,
25690         geometry, geometryMaterials, vertices, vertex, vertexPositionScreen,
25691         faces, face, faceVertexNormals, normal, faceVertexUvs, uvs,
25692         v1, v2, v3, v4, isFaceMaterial, material, side;
25693
25694         _face3Count = 0;
25695         _face4Count = 0;
25696         _lineCount = 0;
25697         _particleCount = 0;
25698
25699         _renderData.elements.length = 0;
25700
25701         scene.updateMatrixWorld();
25702
25703         if ( camera.parent === undefined ) camera.updateMatrixWorld();
25704
25705         camera.matrixWorldInverse.getInverse( camera.matrixWorld );
25706
25707         _viewProjectionMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
25708
25709         _frustum.setFromMatrix( _viewProjectionMatrix );
25710
25711         _renderData = projectGraph( scene, sortObjects );
25712
25713         for ( o = 0, ol = _renderData.objects.length; o < ol; o++ ) {
25714
25715             object = _renderData.objects[ o ].object;
25716
25717             modelMatrix = object.matrixWorld;
25718
25719             _vertexCount = 0;
25720
25721             if ( object instanceof THREE.Mesh ) {
25722
25723                 geometry = object.geometry;
25724                 geometryMaterials = object.geometry.materials;
25725                 vertices = geometry.vertices;
25726                 faces = geometry.faces;
25727                 faceVertexUvs = geometry.faceVertexUvs;
25728
25729                 rotationMatrix = object.matrixRotationWorld.extractRotation( modelMatrix );
25730
25731                 isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
25732                 side = object.material.side;
25733
25734                 for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
25735
25736                     _vertex = getNextVertexInPool();
25737                     _vertex.positionWorld.copy( vertices[ v ] );
25738
25739                     modelMatrix.multiplyVector3( _vertex.positionWorld );
25740
25741                     _vertex.positionScreen.copy( _vertex.positionWorld );
25742                     _viewProjectionMatrix.multiplyVector4( _vertex.positionScreen );
25743
25744                     _vertex.positionScreen.x /= _vertex.positionScreen.w;
25745                     _vertex.positionScreen.y /= _vertex.positionScreen.w;
25746
25747                     _vertex.visible = _vertex.positionScreen.z > near && _vertex.positionScreen.z < far;
25748
25749                 }
25750
25751                 for ( f = 0, fl = faces.length; f < fl; f ++ ) {
25752
25753                     face = faces[ f ];
25754
25755                     material = isFaceMaterial === true ? geometryMaterials[ face.materialIndex ] : object.material;
25756
25757                     if ( material === undefined ) continue;
25758
25759                     side = material.side;
25760
25761                     if ( face instanceof THREE.Face3 ) {
25762
25763                         v1 = _vertexPool[ face.a ];
25764                         v2 = _vertexPool[ face.b ];
25765                         v3 = _vertexPool[ face.c ];
25766
25767                         if ( v1.visible === true && v2.visible === true && v3.visible === true ) {
25768
25769                             visible = ( ( v3.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
25770                                 ( v3.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) ) < 0;
25771
25772                             if ( side === THREE.DoubleSide || visible === ( side === THREE.FrontSide ) ) {
25773
25774                                 _face = getNextFace3InPool();
25775
25776                                 _face.v1.copy( v1 );
25777                                 _face.v2.copy( v2 );
25778                                 _face.v3.copy( v3 );
25779
25780                             } else {
25781
25782                                 continue;
25783
25784                             }
25785
25786                         } else {
25787
25788                             continue;
25789
25790                         }
25791
25792                     } else if ( face instanceof THREE.Face4 ) {
25793
25794                         v1 = _vertexPool[ face.a ];
25795                         v2 = _vertexPool[ face.b ];
25796                         v3 = _vertexPool[ face.c ];
25797                         v4 = _vertexPool[ face.d ];
25798
25799                         if ( v1.visible === true && v2.visible === true && v3.visible === true && v4.visible === true ) {
25800
25801                             visible = ( v4.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
25802                                 ( v4.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ||
25803                                 ( v2.positionScreen.x - v3.positionScreen.x ) * ( v4.positionScreen.y - v3.positionScreen.y ) -
25804                                 ( v2.positionScreen.y - v3.positionScreen.y ) * ( v4.positionScreen.x - v3.positionScreen.x ) < 0;
25805
25806
25807                             if ( side === THREE.DoubleSide || visible === ( side === THREE.FrontSide ) ) {
25808
25809                                 _face = getNextFace4InPool();
25810
25811                                 _face.v1.copy( v1 );
25812                                 _face.v2.copy( v2 );
25813                                 _face.v3.copy( v3 );
25814                                 _face.v4.copy( v4 );
25815
25816                             } else {
25817
25818                                 continue;
25819
25820                             }
25821
25822                         } else {
25823
25824                             continue;
25825
25826                         }
25827
25828                     }
25829
25830                     _face.normalWorld.copy( face.normal );
25831
25832                     if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) _face.normalWorld.negate();
25833                     rotationMatrix.multiplyVector3( _face.normalWorld );
25834
25835                     _face.centroidWorld.copy( face.centroid );
25836                     modelMatrix.multiplyVector3( _face.centroidWorld );
25837
25838                     _face.centroidScreen.copy( _face.centroidWorld );
25839                     _viewProjectionMatrix.multiplyVector3( _face.centroidScreen );
25840
25841                     faceVertexNormals = face.vertexNormals;
25842
25843                     for ( n = 0, nl = faceVertexNormals.length; n < nl; n ++ ) {
25844
25845                         normal = _face.vertexNormalsWorld[ n ];
25846                         normal.copy( faceVertexNormals[ n ] );
25847
25848                         if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) normal.negate();
25849
25850                         rotationMatrix.multiplyVector3( normal );
25851
25852                     }
25853
25854                     _face.vertexNormalsLength = faceVertexNormals.length;
25855
25856                     for ( c = 0, cl = faceVertexUvs.length; c < cl; c ++ ) {
25857
25858                         uvs = faceVertexUvs[ c ][ f ];
25859
25860                         if ( uvs === undefined ) continue;
25861
25862                         for ( u = 0, ul = uvs.length; u < ul; u ++ ) {
25863
25864                             _face.uvs[ c ][ u ] = uvs[ u ];
25865
25866                         }
25867
25868                     }
25869
25870                     _face.material = material;
25871
25872                     _face.z = _face.centroidScreen.z;
25873
25874                     _renderData.elements.push( _face );
25875
25876                 }
25877
25878             } else if ( object instanceof THREE.Line ) {
25879
25880                 _modelViewProjectionMatrix.multiply( _viewProjectionMatrix, modelMatrix );
25881
25882                 vertices = object.geometry.vertices;
25883
25884                 v1 = getNextVertexInPool();
25885                 v1.positionScreen.copy( vertices[ 0 ] );
25886                 _modelViewProjectionMatrix.multiplyVector4( v1.positionScreen );
25887
25888                 // Handle LineStrip and LinePieces
25889                 var step = object.type === THREE.LinePieces ? 2 : 1;
25890
25891                 for ( v = 1, vl = vertices.length; v < vl; v ++ ) {
25892
25893                     v1 = getNextVertexInPool();
25894                     v1.positionScreen.copy( vertices[ v ] );
25895                     _modelViewProjectionMatrix.multiplyVector4( v1.positionScreen );
25896
25897                     if ( ( v + 1 ) % step > 0 ) continue;
25898
25899                     v2 = _vertexPool[ _vertexCount - 2 ];
25900
25901                     _clippedVertex1PositionScreen.copy( v1.positionScreen );
25902                     _clippedVertex2PositionScreen.copy( v2.positionScreen );
25903
25904                     if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) === true ) {
25905
25906                         // Perform the perspective divide
25907                         _clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w );
25908                         _clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w );
25909
25910                         _line = getNextLineInPool();
25911                         _line.v1.positionScreen.copy( _clippedVertex1PositionScreen );
25912                         _line.v2.positionScreen.copy( _clippedVertex2PositionScreen );
25913
25914                         _line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z );
25915
25916                         _line.material = object.material;
25917
25918                         _renderData.elements.push( _line );
25919
25920                     }
25921
25922                 }
25923
25924             }
25925
25926         }
25927
25928         for ( o = 0, ol = _renderData.sprites.length; o < ol; o++ ) {
25929
25930             object = _renderData.sprites[ o ].object;
25931
25932             modelMatrix = object.matrixWorld;
25933
25934             if ( object instanceof THREE.Particle ) {
25935
25936                 _vector4.set( modelMatrix.elements[12], modelMatrix.elements[13], modelMatrix.elements[14], 1 );
25937                 _viewProjectionMatrix.multiplyVector4( _vector4 );
25938
25939                 _vector4.z /= _vector4.w;
25940
25941                 if ( _vector4.z > 0 && _vector4.z < 1 ) {
25942
25943                     _particle = getNextParticleInPool();
25944                     _particle.object = object;
25945                     _particle.x = _vector4.x / _vector4.w;
25946                     _particle.y = _vector4.y / _vector4.w;
25947                     _particle.z = _vector4.z;
25948
25949                     _particle.rotation = object.rotation.z;
25950
25951                     _particle.scale.x = object.scale.x * Math.abs( _particle.x - ( _vector4.x + camera.projectionMatrix.elements[0] ) / ( _vector4.w + camera.projectionMatrix.elements[12] ) );
25952                     _particle.scale.y = object.scale.y * Math.abs( _particle.y - ( _vector4.y + camera.projectionMatrix.elements[5] ) / ( _vector4.w + camera.projectionMatrix.elements[13] ) );
25953
25954                     _particle.material = object.material;
25955
25956                     _renderData.elements.push( _particle );
25957
25958                 }
25959
25960             }
25961
25962         }
25963
25964         if ( sortElements === true ) _renderData.elements.sort( painterSort );
25965
25966         return _renderData;
25967
25968     };
25969
25970     // Pools
25971
25972     function getNextObjectInPool() {
25973
25974         if ( _objectCount === _objectPoolLength ) {
25975
25976             var object = new THREE.RenderableObject();
25977             _objectPool.push( object );
25978             _objectPoolLength ++;
25979             _objectCount ++;
25980             return object;
25981
25982         }
25983
25984         return _objectPool[ _objectCount ++ ];
25985
25986     }
25987
25988     function getNextVertexInPool() {
25989
25990         if ( _vertexCount === _vertexPoolLength ) {
25991
25992             var vertex = new THREE.RenderableVertex();
25993             _vertexPool.push( vertex );
25994             _vertexPoolLength ++;
25995             _vertexCount ++;
25996             return vertex;
25997
25998         }
25999
26000         return _vertexPool[ _vertexCount ++ ];
26001
26002     }
26003
26004     function getNextFace3InPool() {
26005
26006         if ( _face3Count === _face3PoolLength ) {
26007
26008             var face = new THREE.RenderableFace3();
26009             _face3Pool.push( face );
26010             _face3PoolLength ++;
26011             _face3Count ++;
26012             return face;
26013
26014         }
26015
26016         return _face3Pool[ _face3Count ++ ];
26017
26018
26019     }
26020
26021     function getNextFace4InPool() {
26022
26023         if ( _face4Count === _face4PoolLength ) {
26024
26025             var face = new THREE.RenderableFace4();
26026             _face4Pool.push( face );
26027             _face4PoolLength ++;
26028             _face4Count ++;
26029             return face;
26030
26031         }
26032
26033         return _face4Pool[ _face4Count ++ ];
26034
26035     }
26036
26037     function getNextLineInPool() {
26038
26039         if ( _lineCount === _linePoolLength ) {
26040
26041             var line = new THREE.RenderableLine();
26042             _linePool.push( line );
26043             _linePoolLength ++;
26044             _lineCount ++
26045             return line;
26046
26047         }
26048
26049         return _linePool[ _lineCount ++ ];
26050
26051     }
26052
26053     function getNextParticleInPool() {
26054
26055         if ( _particleCount === _particlePoolLength ) {
26056
26057             var particle = new THREE.RenderableParticle();
26058             _particlePool.push( particle );
26059             _particlePoolLength ++;
26060             _particleCount ++
26061             return particle;
26062
26063         }
26064
26065         return _particlePool[ _particleCount ++ ];
26066
26067     }
26068
26069     //
26070
26071     function painterSort( a, b ) {
26072
26073         return b.z - a.z;
26074
26075     }
26076
26077     function clipLine( s1, s2 ) {
26078
26079         var alpha1 = 0, alpha2 = 1,
26080
26081         // Calculate the boundary coordinate of each vertex for the near and far clip planes,
26082         // Z = -1 and Z = +1, respectively.
26083         bc1near =  s1.z + s1.w,
26084         bc2near =  s2.z + s2.w,
26085         bc1far =  - s1.z + s1.w,
26086         bc2far =  - s2.z + s2.w;
26087
26088         if ( bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) {
26089
26090             // Both vertices lie entirely within all clip planes.
26091             return true;
26092
26093         } else if ( ( bc1near < 0 && bc2near < 0) || (bc1far < 0 && bc2far < 0 ) ) {
26094
26095             // Both vertices lie entirely outside one of the clip planes.
26096             return false;
26097
26098         } else {
26099
26100             // The line segment spans at least one clip plane.
26101
26102             if ( bc1near < 0 ) {
26103
26104                 // v1 lies outside the near plane, v2 inside
26105                 alpha1 = Math.max( alpha1, bc1near / ( bc1near - bc2near ) );
26106
26107             } else if ( bc2near < 0 ) {
26108
26109                 // v2 lies outside the near plane, v1 inside
26110                 alpha2 = Math.min( alpha2, bc1near / ( bc1near - bc2near ) );
26111
26112             }
26113
26114             if ( bc1far < 0 ) {
26115
26116                 // v1 lies outside the far plane, v2 inside
26117                 alpha1 = Math.max( alpha1, bc1far / ( bc1far - bc2far ) );
26118
26119             } else if ( bc2far < 0 ) {
26120
26121                 // v2 lies outside the far plane, v2 inside
26122                 alpha2 = Math.min( alpha2, bc1far / ( bc1far - bc2far ) );
26123
26124             }
26125
26126             if ( alpha2 < alpha1 ) {
26127
26128                 // The line segment spans two boundaries, but is outside both of them.
26129                 // (This can't happen when we're only clipping against just near/far but good
26130                 //  to leave the check here for future usage if other clip planes are added.)
26131                 return false;
26132
26133             } else {
26134
26135                 // Update the s1 and s2 vertices to match the clipped line segment.
26136                 s1.lerpSelf( s2, alpha1 );
26137                 s2.lerpSelf( s1, 1 - alpha2 );
26138
26139                 return true;
26140
26141             }
26142
26143         }
26144
26145     }
26146
26147 };
26148 /**
26149  * @author mikael emtinger / http://gomo.se/
26150  * @author alteredq / http://alteredqualia.com/
26151  * @author WestLangley / http://github.com/WestLangley
26152  */
26153
26154 THREE.Quaternion = function( x, y, z, w ) {
26155
26156     this.x = x || 0;
26157     this.y = y || 0;
26158     this.z = z || 0;
26159     this.w = ( w !== undefined ) ? w : 1;
26160
26161 };
26162
26163 THREE.Quaternion.prototype = {
26164
26165     constructor: THREE.Quaternion,
26166
26167     set: function ( x, y, z, w ) {
26168
26169         this.x = x;
26170         this.y = y;
26171         this.z = z;
26172         this.w = w;
26173
26174         return this;
26175
26176     },
26177
26178     copy: function ( q ) {
26179
26180         this.x = q.x;
26181         this.y = q.y;
26182         this.z = q.z;
26183         this.w = q.w;
26184
26185         return this;
26186
26187     },
26188
26189     setFromEuler: function ( v, order ) {
26190
26191         // http://www.mathworks.com/matlabcentral/fileexchange/
26192         //     20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
26193         //    content/SpinCalc.m
26194
26195         var c1 = Math.cos( v.x / 2 );
26196         var c2 = Math.cos( v.y / 2 );
26197         var c3 = Math.cos( v.z / 2 );
26198         var s1 = Math.sin( v.x / 2 );
26199         var s2 = Math.sin( v.y / 2 );
26200         var s3 = Math.sin( v.z / 2 );
26201
26202         if ( order === undefined || order === 'XYZ' ) {
26203
26204             this.x = s1 * c2 * c3 + c1 * s2 * s3;
26205             this.y = c1 * s2 * c3 - s1 * c2 * s3;
26206             this.z = c1 * c2 * s3 + s1 * s2 * c3;
26207             this.w = c1 * c2 * c3 - s1 * s2 * s3;
26208
26209         } else if ( order === 'YXZ' ) {
26210
26211             this.x = s1 * c2 * c3 + c1 * s2 * s3;
26212             this.y = c1 * s2 * c3 - s1 * c2 * s3;
26213             this.z = c1 * c2 * s3 - s1 * s2 * c3;
26214             this.w = c1 * c2 * c3 + s1 * s2 * s3;
26215
26216         } else if ( order === 'ZXY' ) {
26217
26218             this.x = s1 * c2 * c3 - c1 * s2 * s3;
26219             this.y = c1 * s2 * c3 + s1 * c2 * s3;
26220             this.z = c1 * c2 * s3 + s1 * s2 * c3;
26221             this.w = c1 * c2 * c3 - s1 * s2 * s3;
26222
26223         } else if ( order === 'ZYX' ) {
26224
26225             this.x = s1 * c2 * c3 - c1 * s2 * s3;
26226             this.y = c1 * s2 * c3 + s1 * c2 * s3;
26227             this.z = c1 * c2 * s3 - s1 * s2 * c3;
26228             this.w = c1 * c2 * c3 + s1 * s2 * s3;
26229
26230         } else if ( order === 'YZX' ) {
26231
26232             this.x = s1 * c2 * c3 + c1 * s2 * s3;
26233             this.y = c1 * s2 * c3 + s1 * c2 * s3;
26234             this.z = c1 * c2 * s3 - s1 * s2 * c3;
26235             this.w = c1 * c2 * c3 - s1 * s2 * s3;
26236
26237         } else if ( order === 'XZY' ) {
26238
26239             this.x = s1 * c2 * c3 - c1 * s2 * s3;
26240             this.y = c1 * s2 * c3 - s1 * c2 * s3;
26241             this.z = c1 * c2 * s3 + s1 * s2 * c3;
26242             this.w = c1 * c2 * c3 + s1 * s2 * s3;
26243
26244         }
26245
26246         return this;
26247
26248     },
26249
26250     setFromAxisAngle: function ( axis, angle ) {
26251
26252         // from http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
26253         // axis have to be normalized
26254
26255         var halfAngle = angle / 2,
26256             s = Math.sin( halfAngle );
26257
26258         this.x = axis.x * s;
26259         this.y = axis.y * s;
26260         this.z = axis.z * s;
26261         this.w = Math.cos( halfAngle );
26262
26263         return this;
26264
26265     },
26266
26267     setFromRotationMatrix: function ( m ) {
26268
26269         // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
26270
26271         // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
26272
26273         var te = m.elements,
26274
26275             m11 = te[0], m12 = te[4], m13 = te[8],
26276             m21 = te[1], m22 = te[5], m23 = te[9],
26277             m31 = te[2], m32 = te[6], m33 = te[10],
26278
26279             trace = m11 + m22 + m33,
26280             s;
26281
26282         if( trace > 0 ) {
26283
26284             s = 0.5 / Math.sqrt( trace + 1.0 );
26285
26286             this.w = 0.25 / s;
26287             this.x = ( m32 - m23 ) * s;
26288             this.y = ( m13 - m31 ) * s;
26289             this.z = ( m21 - m12 ) * s;
26290
26291         } else if ( m11 > m22 && m11 > m33 ) {
26292
26293             s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
26294
26295             this.w = (m32 - m23 ) / s;
26296             this.x = 0.25 * s;
26297             this.y = (m12 + m21 ) / s;
26298             this.z = (m13 + m31 ) / s;
26299
26300         } else if (m22 > m33) {
26301
26302             s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
26303
26304             this.w = (m13 - m31 ) / s;
26305             this.x = (m12 + m21 ) / s;
26306             this.y = 0.25 * s;
26307             this.z = (m23 + m32 ) / s;
26308
26309         } else {
26310
26311             s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
26312
26313             this.w = ( m21 - m12 ) / s;
26314             this.x = ( m13 + m31 ) / s;
26315             this.y = ( m23 + m32 ) / s;
26316             this.z = 0.25 * s;
26317
26318         }
26319
26320         return this;
26321
26322     },
26323
26324     calculateW : function () {
26325
26326         this.w = - Math.sqrt( Math.abs( 1.0 - this.x * this.x - this.y * this.y - this.z * this.z ) );
26327
26328         return this;
26329
26330     },
26331
26332     inverse: function () {
26333
26334         this.x *= -1;
26335         this.y *= -1;
26336         this.z *= -1;
26337
26338         return this;
26339
26340     },
26341
26342     length: function () {
26343
26344         return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
26345
26346     },
26347
26348     normalize: function () {
26349
26350         var l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
26351
26352         if ( l === 0 ) {
26353
26354             this.x = 0;
26355             this.y = 0;
26356             this.z = 0;
26357             this.w = 0;
26358
26359         } else {
26360
26361             l = 1 / l;
26362
26363             this.x = this.x * l;
26364             this.y = this.y * l;
26365             this.z = this.z * l;
26366             this.w = this.w * l;
26367
26368         }
26369
26370         return this;
26371
26372     },
26373
26374     multiply: function ( a, b ) {
26375
26376         // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
26377         var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w,
26378         qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
26379
26380         this.x =  qax * qbw + qay * qbz - qaz * qby + qaw * qbx;
26381         this.y = -qax * qbz + qay * qbw + qaz * qbx + qaw * qby;
26382         this.z =  qax * qby - qay * qbx + qaz * qbw + qaw * qbz;
26383         this.w = -qax * qbx - qay * qby - qaz * qbz + qaw * qbw;
26384
26385         return this;
26386
26387     },
26388
26389     multiplySelf: function ( b ) {
26390
26391         var qax = this.x, qay = this.y, qaz = this.z, qaw = this.w,
26392         qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
26393
26394         this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
26395         this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
26396         this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
26397         this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
26398
26399         return this;
26400
26401     },
26402
26403     multiplyVector3: function ( vector, dest ) {
26404
26405         if ( !dest ) { dest = vector; }
26406
26407         var x    = vector.x,  y  = vector.y,  z  = vector.z,
26408             qx   = this.x, qy = this.y, qz = this.z, qw = this.w;
26409
26410         // calculate quat * vector
26411
26412         var ix =  qw * x + qy * z - qz * y,
26413             iy =  qw * y + qz * x - qx * z,
26414             iz =  qw * z + qx * y - qy * x,
26415             iw = -qx * x - qy * y - qz * z;
26416
26417         // calculate result * inverse quat
26418
26419         dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
26420         dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
26421         dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
26422
26423         return dest;
26424
26425     },
26426
26427     slerpSelf: function ( qb, t ) {
26428
26429         var x = this.x, y = this.y, z = this.z, w = this.w;
26430
26431         // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
26432
26433         var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;
26434
26435         if ( cosHalfTheta < 0 ) {
26436
26437             this.w = -qb.w;
26438             this.x = -qb.x;
26439             this.y = -qb.y;
26440             this.z = -qb.z;
26441
26442             cosHalfTheta = -cosHalfTheta;
26443
26444         } else {
26445
26446             this.copy( qb );
26447
26448         }
26449
26450         if ( cosHalfTheta >= 1.0 ) {
26451
26452             this.w = w;
26453             this.x = x;
26454             this.y = y;
26455             this.z = z;
26456
26457             return this;
26458
26459         }
26460
26461         var halfTheta = Math.acos( cosHalfTheta );
26462         var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
26463
26464         if ( Math.abs( sinHalfTheta ) < 0.001 ) {
26465
26466             this.w = 0.5 * ( w + this.w );
26467             this.x = 0.5 * ( x + this.x );
26468             this.y = 0.5 * ( y + this.y );
26469             this.z = 0.5 * ( z + this.z );
26470
26471             return this;
26472
26473         }
26474
26475         var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
26476         ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
26477
26478         this.w = ( w * ratioA + this.w * ratioB );
26479         this.x = ( x * ratioA + this.x * ratioB );
26480         this.y = ( y * ratioA + this.y * ratioB );
26481         this.z = ( z * ratioA + this.z * ratioB );
26482
26483         return this;
26484
26485     },
26486
26487     clone: function () {
26488
26489         return new THREE.Quaternion( this.x, this.y, this.z, this.w );
26490
26491     }
26492
26493 }
26494
26495 THREE.Quaternion.slerp = function ( qa, qb, qm, t ) {
26496
26497     // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
26498
26499     var cosHalfTheta = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z;
26500
26501     if ( cosHalfTheta < 0 ) {
26502
26503         qm.w = -qb.w;
26504         qm.x = -qb.x;
26505         qm.y = -qb.y;
26506         qm.z = -qb.z;
26507
26508         cosHalfTheta = -cosHalfTheta;
26509
26510     } else {
26511
26512         qm.copy( qb );
26513
26514     }
26515
26516     if ( Math.abs( cosHalfTheta ) >= 1.0 ) {
26517
26518         qm.w = qa.w;
26519         qm.x = qa.x;
26520         qm.y = qa.y;
26521         qm.z = qa.z;
26522
26523         return qm;
26524
26525     }
26526
26527     var halfTheta = Math.acos( cosHalfTheta );
26528     var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
26529
26530     if ( Math.abs( sinHalfTheta ) < 0.001 ) {
26531
26532         qm.w = 0.5 * ( qa.w + qm.w );
26533         qm.x = 0.5 * ( qa.x + qm.x );
26534         qm.y = 0.5 * ( qa.y + qm.y );
26535         qm.z = 0.5 * ( qa.z + qm.z );
26536
26537         return qm;
26538
26539     }
26540
26541     var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;
26542     var ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
26543
26544     qm.w = ( qa.w * ratioA + qm.w * ratioB );
26545     qm.x = ( qa.x * ratioA + qm.x * ratioB );
26546     qm.y = ( qa.y * ratioA + qm.y * ratioB );
26547     qm.z = ( qa.z * ratioA + qm.z * ratioB );
26548
26549     return qm;
26550
26551 }
26552 /**
26553  * @author mrdoob / http://mrdoob.com/
26554  */
26555
26556 THREE.Vertex = function ( v ) {
26557
26558     console.warn( 'THREE.Vertex has been DEPRECATED. Use THREE.Vector3 instead.')
26559     return v;
26560
26561 };
26562 /**
26563  * @author mrdoob / http://mrdoob.com/
26564  * @author alteredq / http://alteredqualia.com/
26565  */
26566
26567 THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
26568
26569     this.a = a;
26570     this.b = b;
26571     this.c = c;
26572
26573     this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
26574     this.vertexNormals = normal instanceof Array ? normal : [ ];
26575
26576     this.color = color instanceof THREE.Color ? color : new THREE.Color();
26577     this.vertexColors = color instanceof Array ? color : [];
26578
26579     this.vertexTangents = [];
26580
26581     this.materialIndex = materialIndex;
26582
26583     this.centroid = new THREE.Vector3();
26584
26585 };
26586
26587 THREE.Face3.prototype = {
26588
26589     constructor: THREE.Face3,
26590
26591     clone: function () {
26592
26593         var face = new THREE.Face3( this.a, this.b, this.c );
26594
26595         face.normal.copy( this.normal );
26596         face.color.copy( this.color );
26597         face.centroid.copy( this.centroid );
26598
26599         face.materialIndex = this.materialIndex;
26600
26601         var i, il;
26602         for ( i = 0, il = this.vertexNormals.length; i < il; i ++ ) face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
26603         for ( i = 0, il = this.vertexColors.length; i < il; i ++ ) face.vertexColors[ i ] = this.vertexColors[ i ].clone();
26604         for ( i = 0, il = this.vertexTangents.length; i < il; i ++ ) face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
26605
26606         return face;
26607
26608     }
26609
26610 };
26611 /**
26612  * @author mrdoob / http://mrdoob.com/
26613  * @author alteredq / http://alteredqualia.com/
26614  */
26615
26616 THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) {
26617
26618     this.a = a;
26619     this.b = b;
26620     this.c = c;
26621     this.d = d;
26622
26623     this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
26624     this.vertexNormals = normal instanceof Array ? normal : [ ];
26625
26626     this.color = color instanceof THREE.Color ? color : new THREE.Color();
26627     this.vertexColors = color instanceof Array ? color : [];
26628
26629     this.vertexTangents = [];
26630
26631     this.materialIndex = materialIndex;
26632
26633     this.centroid = new THREE.Vector3();
26634
26635 };
26636
26637 THREE.Face4.prototype = {
26638
26639     constructor: THREE.Face4,
26640
26641     clone: function () {
26642
26643         var face = new THREE.Face4( this.a, this.b, this.c, this.d );
26644
26645         face.normal.copy( this.normal );
26646         face.color.copy( this.color );
26647         face.centroid.copy( this.centroid );
26648
26649         face.materialIndex = this.materialIndex;
26650
26651         var i, il;
26652         for ( i = 0, il = this.vertexNormals.length; i < il; i ++ ) face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
26653         for ( i = 0, il = this.vertexColors.length; i < il; i ++ ) face.vertexColors[ i ] = this.vertexColors[ i ].clone();
26654         for ( i = 0, il = this.vertexTangents.length; i < il; i ++ ) face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
26655
26656         return face;
26657
26658     }
26659
26660 };
26661 /**
26662  * @author mrdoob / http://mrdoob.com/
26663  */
26664
26665 THREE.UV = function ( u, v ) {
26666
26667     this.u = u || 0;
26668     this.v = v || 0;
26669
26670 };
26671
26672 THREE.UV.prototype = {
26673
26674     constructor: THREE.UV,
26675
26676     set: function ( u, v ) {
26677
26678         this.u = u;
26679         this.v = v;
26680
26681         return this;
26682
26683     },
26684
26685     copy: function ( uv ) {
26686
26687         this.u = uv.u;
26688         this.v = uv.v;
26689
26690         return this;
26691
26692     },
26693
26694     lerpSelf: function ( uv, alpha ) {
26695
26696         this.u += ( uv.u - this.u ) * alpha;
26697         this.v += ( uv.v - this.v ) * alpha;
26698
26699         return this;
26700
26701     },
26702
26703     clone: function () {
26704
26705         return new THREE.UV( this.u, this.v );
26706
26707     }
26708
26709 };
26710 /**
26711  * @author mrdoob / http://mrdoob.com/
26712  * @author kile / http://kile.stravaganza.org/
26713  * @author alteredq / http://alteredqualia.com/
26714  * @author mikael emtinger / http://gomo.se/
26715  * @author zz85 / http://www.lab4games.net/zz85/blog
26716  */
26717
26718 THREE.Geometry = function () {
26719
26720     this.id = THREE.GeometryCount ++;
26721
26722     this.name = '';
26723
26724     this.vertices = [];
26725     this.colors = []; // one-to-one vertex colors, used in ParticleSystem, Line and Ribbon
26726
26727     this.materials = [];
26728
26729     this.faces = [];
26730
26731     this.faceUvs = [[]];
26732     this.faceVertexUvs = [[]];
26733
26734     this.morphTargets = [];
26735     this.morphColors = [];
26736     this.morphNormals = [];
26737
26738     this.skinWeights = [];
26739     this.skinIndices = [];
26740
26741     this.boundingBox = null;
26742     this.boundingSphere = null;
26743
26744     this.hasTangents = false;
26745
26746     this.dynamic = true; // the intermediate typearrays will be deleted when set to false
26747
26748 };
26749
26750 THREE.Geometry.prototype = {
26751
26752     constructor : THREE.Geometry,
26753
26754     applyMatrix: function ( matrix ) {
26755
26756         var matrixRotation = new THREE.Matrix4();
26757         matrixRotation.extractRotation( matrix );
26758
26759         for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
26760
26761             var vertex = this.vertices[ i ];
26762
26763             matrix.multiplyVector3( vertex );
26764
26765         }
26766
26767         for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
26768
26769             var face = this.faces[ i ];
26770
26771             matrixRotation.multiplyVector3( face.normal );
26772
26773             for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
26774
26775                 matrixRotation.multiplyVector3( face.vertexNormals[ j ] );
26776
26777             }
26778
26779             matrix.multiplyVector3( face.centroid );
26780
26781         }
26782
26783     },
26784
26785     computeCentroids: function () {
26786
26787         var f, fl, face;
26788
26789         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26790
26791             face = this.faces[ f ];
26792             face.centroid.set( 0, 0, 0 );
26793
26794             if ( face instanceof THREE.Face3 ) {
26795
26796                 face.centroid.addSelf( this.vertices[ face.a ] );
26797                 face.centroid.addSelf( this.vertices[ face.b ] );
26798                 face.centroid.addSelf( this.vertices[ face.c ] );
26799                 face.centroid.divideScalar( 3 );
26800
26801             } else if ( face instanceof THREE.Face4 ) {
26802
26803                 face.centroid.addSelf( this.vertices[ face.a ] );
26804                 face.centroid.addSelf( this.vertices[ face.b ] );
26805                 face.centroid.addSelf( this.vertices[ face.c ] );
26806                 face.centroid.addSelf( this.vertices[ face.d ] );
26807                 face.centroid.divideScalar( 4 );
26808
26809             }
26810
26811         }
26812
26813     },
26814
26815     computeFaceNormals: function () {
26816
26817         var n, nl, v, vl, vertex, f, fl, face, vA, vB, vC,
26818         cb = new THREE.Vector3(), ab = new THREE.Vector3();
26819
26820         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26821
26822             face = this.faces[ f ];
26823
26824             vA = this.vertices[ face.a ];
26825             vB = this.vertices[ face.b ];
26826             vC = this.vertices[ face.c ];
26827
26828             cb.sub( vC, vB );
26829             ab.sub( vA, vB );
26830             cb.crossSelf( ab );
26831
26832             if ( !cb.isZero() ) {
26833
26834                 cb.normalize();
26835
26836             }
26837
26838             face.normal.copy( cb );
26839
26840         }
26841
26842     },
26843
26844     computeVertexNormals: function () {
26845
26846         var v, vl, f, fl, face, vertices;
26847
26848         // create internal buffers for reuse when calling this method repeatedly
26849         // (otherwise memory allocation / deallocation every frame is big resource hog)
26850
26851         if ( this.__tmpVertices === undefined ) {
26852
26853             this.__tmpVertices = new Array( this.vertices.length );
26854             vertices = this.__tmpVertices;
26855
26856             for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
26857
26858                 vertices[ v ] = new THREE.Vector3();
26859
26860             }
26861
26862             for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26863
26864                 face = this.faces[ f ];
26865
26866                 if ( face instanceof THREE.Face3 ) {
26867
26868                     face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
26869
26870                 } else if ( face instanceof THREE.Face4 ) {
26871
26872                     face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
26873
26874                 }
26875
26876             }
26877
26878         } else {
26879
26880             vertices = this.__tmpVertices;
26881
26882             for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
26883
26884                 vertices[ v ].set( 0, 0, 0 );
26885
26886             }
26887
26888         }
26889
26890         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26891
26892             face = this.faces[ f ];
26893
26894             if ( face instanceof THREE.Face3 ) {
26895
26896                 vertices[ face.a ].addSelf( face.normal );
26897                 vertices[ face.b ].addSelf( face.normal );
26898                 vertices[ face.c ].addSelf( face.normal );
26899
26900             } else if ( face instanceof THREE.Face4 ) {
26901
26902                 vertices[ face.a ].addSelf( face.normal );
26903                 vertices[ face.b ].addSelf( face.normal );
26904                 vertices[ face.c ].addSelf( face.normal );
26905                 vertices[ face.d ].addSelf( face.normal );
26906
26907             }
26908
26909         }
26910
26911         for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
26912
26913             vertices[ v ].normalize();
26914
26915         }
26916
26917         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26918
26919             face = this.faces[ f ];
26920
26921             if ( face instanceof THREE.Face3 ) {
26922
26923                 face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
26924                 face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
26925                 face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
26926
26927             } else if ( face instanceof THREE.Face4 ) {
26928
26929                 face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
26930                 face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
26931                 face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
26932                 face.vertexNormals[ 3 ].copy( vertices[ face.d ] );
26933
26934             }
26935
26936         }
26937
26938     },
26939
26940     computeMorphNormals: function () {
26941
26942         var i, il, f, fl, face;
26943
26944         // save original normals
26945         // - create temp variables on first access
26946         //   otherwise just copy (for faster repeated calls)
26947
26948         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26949
26950             face = this.faces[ f ];
26951
26952             if ( ! face.__originalFaceNormal ) {
26953
26954                 face.__originalFaceNormal = face.normal.clone();
26955
26956             } else {
26957
26958                 face.__originalFaceNormal.copy( face.normal );
26959
26960             }
26961
26962             if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
26963
26964             for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
26965
26966                 if ( ! face.__originalVertexNormals[ i ] ) {
26967
26968                     face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
26969
26970                 } else {
26971
26972                     face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
26973
26974                 }
26975
26976             }
26977
26978         }
26979
26980         // use temp geometry to compute face and vertex normals for each morph
26981
26982         var tmpGeo = new THREE.Geometry();
26983         tmpGeo.faces = this.faces;
26984
26985         for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {
26986
26987             // create on first access
26988
26989             if ( ! this.morphNormals[ i ] ) {
26990
26991                 this.morphNormals[ i ] = {};
26992                 this.morphNormals[ i ].faceNormals = [];
26993                 this.morphNormals[ i ].vertexNormals = [];
26994
26995                 var dstNormalsFace = this.morphNormals[ i ].faceNormals;
26996                 var dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
26997
26998                 var faceNormal, vertexNormals;
26999
27000                 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
27001
27002                     face = this.faces[ f ];
27003
27004                     faceNormal = new THREE.Vector3();
27005
27006                     if ( face instanceof THREE.Face3 ) {
27007
27008                         vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3() };
27009
27010                     } else {
27011
27012                         vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3(), d: new THREE.Vector3() };
27013
27014                     }
27015
27016                     dstNormalsFace.push( faceNormal );
27017                     dstNormalsVertex.push( vertexNormals );
27018
27019                 }
27020
27021             }
27022
27023             var morphNormals = this.morphNormals[ i ];
27024
27025             // set vertices to morph target
27026
27027             tmpGeo.vertices = this.morphTargets[ i ].vertices;
27028
27029             // compute morph normals
27030
27031             tmpGeo.computeFaceNormals();
27032             tmpGeo.computeVertexNormals();
27033
27034             // store morph normals
27035
27036             var faceNormal, vertexNormals;
27037
27038             for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
27039
27040                 face = this.faces[ f ];
27041
27042                 faceNormal = morphNormals.faceNormals[ f ];
27043                 vertexNormals = morphNormals.vertexNormals[ f ];
27044
27045                 faceNormal.copy( face.normal );
27046
27047                 if ( face instanceof THREE.Face3 ) {
27048
27049                     vertexNormals.a.copy( face.vertexNormals[ 0 ] );
27050                     vertexNormals.b.copy( face.vertexNormals[ 1 ] );
27051                     vertexNormals.c.copy( face.vertexNormals[ 2 ] );
27052
27053                 } else {
27054
27055                     vertexNormals.a.copy( face.vertexNormals[ 0 ] );
27056                     vertexNormals.b.copy( face.vertexNormals[ 1 ] );
27057                     vertexNormals.c.copy( face.vertexNormals[ 2 ] );
27058                     vertexNormals.d.copy( face.vertexNormals[ 3 ] );
27059
27060                 }
27061
27062             }
27063
27064         }
27065
27066         // restore original normals
27067
27068         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
27069
27070             face = this.faces[ f ];
27071
27072             face.normal = face.__originalFaceNormal;
27073             face.vertexNormals = face.__originalVertexNormals;
27074
27075         }
27076
27077     },
27078
27079     computeTangents: function () {
27080
27081         // based on http://www.terathon.com/code/tangent.html
27082         // tangents go to vertices
27083
27084         var f, fl, v, vl, i, il, vertexIndex,
27085             face, uv, vA, vB, vC, uvA, uvB, uvC,
27086             x1, x2, y1, y2, z1, z2,
27087             s1, s2, t1, t2, r, t, test,
27088             tan1 = [], tan2 = [],
27089             sdir = new THREE.Vector3(), tdir = new THREE.Vector3(),
27090             tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(),
27091             n = new THREE.Vector3(), w;
27092
27093         for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
27094
27095             tan1[ v ] = new THREE.Vector3();
27096             tan2[ v ] = new THREE.Vector3();
27097
27098         }
27099
27100         function handleTriangle( context, a, b, c, ua, ub, uc ) {
27101
27102             vA = context.vertices[ a ];
27103             vB = context.vertices[ b ];
27104             vC = context.vertices[ c ];
27105
27106             uvA = uv[ ua ];
27107             uvB = uv[ ub ];
27108             uvC = uv[ uc ];
27109
27110             x1 = vB.x - vA.x;
27111             x2 = vC.x - vA.x;
27112             y1 = vB.y - vA.y;
27113             y2 = vC.y - vA.y;
27114             z1 = vB.z - vA.z;
27115             z2 = vC.z - vA.z;
27116
27117             s1 = uvB.u - uvA.u;
27118             s2 = uvC.u - uvA.u;
27119             t1 = uvB.v - uvA.v;
27120             t2 = uvC.v - uvA.v;
27121
27122             r = 1.0 / ( s1 * t2 - s2 * t1 );
27123             sdir.set( ( t2 * x1 - t1 * x2 ) * r,
27124                       ( t2 * y1 - t1 * y2 ) * r,
27125                       ( t2 * z1 - t1 * z2 ) * r );
27126             tdir.set( ( s1 * x2 - s2 * x1 ) * r,
27127                       ( s1 * y2 - s2 * y1 ) * r,
27128                       ( s1 * z2 - s2 * z1 ) * r );
27129
27130             tan1[ a ].addSelf( sdir );
27131             tan1[ b ].addSelf( sdir );
27132             tan1[ c ].addSelf( sdir );
27133
27134             tan2[ a ].addSelf( tdir );
27135             tan2[ b ].addSelf( tdir );
27136             tan2[ c ].addSelf( tdir );
27137
27138         }
27139
27140         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
27141
27142             face = this.faces[ f ];
27143             uv = this.faceVertexUvs[ 0 ][ f ]; // use UV layer 0 for tangents
27144
27145             if ( face instanceof THREE.Face3 ) {
27146
27147                 handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
27148
27149             } else if ( face instanceof THREE.Face4 ) {
27150
27151                 handleTriangle( this, face.a, face.b, face.d, 0, 1, 3 );
27152                 handleTriangle( this, face.b, face.c, face.d, 1, 2, 3 );
27153
27154             }
27155
27156         }
27157
27158         var faceIndex = [ 'a', 'b', 'c', 'd' ];
27159
27160         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
27161
27162             face = this.faces[ f ];
27163
27164             for ( i = 0; i < face.vertexNormals.length; i++ ) {
27165
27166                 n.copy( face.vertexNormals[ i ] );
27167
27168                 vertexIndex = face[ faceIndex[ i ] ];
27169
27170                 t = tan1[ vertexIndex ];
27171
27172                 // Gram-Schmidt orthogonalize
27173
27174                 tmp.copy( t );
27175                 tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
27176
27177                 // Calculate handedness
27178
27179                 tmp2.cross( face.vertexNormals[ i ], t );
27180                 test = tmp2.dot( tan2[ vertexIndex ] );
27181                 w = (test < 0.0) ? -1.0 : 1.0;
27182
27183                 face.vertexTangents[ i ] = new THREE.Vector4( tmp.x, tmp.y, tmp.z, w );
27184
27185             }
27186
27187         }
27188
27189         this.hasTangents = true;
27190
27191     },
27192
27193     computeBoundingBox: function () {
27194
27195         if ( ! this.boundingBox ) {
27196
27197             this.boundingBox = { min: new THREE.Vector3(), max: new THREE.Vector3() };
27198
27199         }
27200
27201         if ( this.vertices.length > 0 ) {
27202
27203             var position, firstPosition = this.vertices[ 0 ];
27204
27205             this.boundingBox.min.copy( firstPosition );
27206             this.boundingBox.max.copy( firstPosition );
27207
27208             var min = this.boundingBox.min,
27209                 max = this.boundingBox.max;
27210
27211             for ( var v = 1, vl = this.vertices.length; v < vl; v ++ ) {
27212
27213                 position = this.vertices[ v ];
27214
27215                 if ( position.x < min.x ) {
27216
27217                     min.x = position.x;
27218
27219                 } else if ( position.x > max.x ) {
27220
27221                     max.x = position.x;
27222
27223                 }
27224
27225                 if ( position.y < min.y ) {
27226
27227                     min.y = position.y;
27228
27229                 } else if ( position.y > max.y ) {
27230
27231                     max.y = position.y;
27232
27233                 }
27234
27235                 if ( position.z < min.z ) {
27236
27237                     min.z = position.z;
27238
27239                 } else if ( position.z > max.z ) {
27240
27241                     max.z = position.z;
27242
27243                 }
27244
27245             }
27246
27247         } else {
27248
27249             this.boundingBox.min.set( 0, 0, 0 );
27250             this.boundingBox.max.set( 0, 0, 0 );
27251
27252         }
27253
27254     },
27255
27256     computeBoundingSphere: function () {
27257
27258         var maxRadiusSq = 0;
27259
27260         if ( this.boundingSphere === null ) this.boundingSphere = { radius: 0 };
27261
27262         for ( var i = 0, l = this.vertices.length; i < l; i ++ ) {
27263
27264             var radiusSq = this.vertices[ i ].lengthSq();
27265             if ( radiusSq > maxRadiusSq ) maxRadiusSq = radiusSq;
27266
27267         }
27268
27269         this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
27270
27271     },
27272
27273     /*
27274      * Checks for duplicate vertices with hashmap.
27275      * Duplicated vertices are removed
27276      * and faces' vertices are updated.
27277      */
27278
27279     mergeVertices: function () {
27280
27281         var verticesMap = {}; // Hashmap for looking up vertice by position coordinates (and making sure they are unique)
27282         var unique = [], changes = [];
27283
27284         var v, key;
27285         var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001
27286         var precision = Math.pow( 10, precisionPoints );
27287         var i,il, face;
27288         var abcd = 'abcd', o, k, j, jl, u;
27289
27290         for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
27291
27292             v = this.vertices[ i ];
27293             key = [ Math.round( v.x * precision ), Math.round( v.y * precision ), Math.round( v.z * precision ) ].join( '_' );
27294
27295             if ( verticesMap[ key ] === undefined ) {
27296
27297                 verticesMap[ key ] = i;
27298                 unique.push( this.vertices[ i ] );
27299                 changes[ i ] = unique.length - 1;
27300
27301             } else {
27302
27303                 //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
27304                 changes[ i ] = changes[ verticesMap[ key ] ];
27305
27306             }
27307
27308         };
27309
27310
27311         // Start to patch face indices
27312
27313         for( i = 0, il = this.faces.length; i < il; i ++ ) {
27314
27315             face = this.faces[ i ];
27316
27317             if ( face instanceof THREE.Face3 ) {
27318
27319                 face.a = changes[ face.a ];
27320                 face.b = changes[ face.b ];
27321                 face.c = changes[ face.c ];
27322
27323             } else if ( face instanceof THREE.Face4 ) {
27324
27325                 face.a = changes[ face.a ];
27326                 face.b = changes[ face.b ];
27327                 face.c = changes[ face.c ];
27328                 face.d = changes[ face.d ];
27329
27330                 // check dups in (a, b, c, d) and convert to -> face3
27331
27332                 o = [ face.a, face.b, face.c, face.d ];
27333
27334                 for ( k = 3; k > 0; k -- ) {
27335
27336                     if ( o.indexOf( face[ abcd[ k ] ] ) !== k ) {
27337
27338                         // console.log('faces', face.a, face.b, face.c, face.d, 'dup at', k);
27339
27340                         o.splice( k, 1 );
27341
27342                         this.faces[ i ] = new THREE.Face3( o[0], o[1], o[2], face.normal, face.color, face.materialIndex );
27343
27344                         for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
27345
27346                             u = this.faceVertexUvs[ j ][ i ];
27347                             if ( u ) u.splice( k, 1 );
27348
27349                         }
27350
27351                         this.faces[ i ].vertexColors = face.vertexColors;
27352
27353                         break;
27354                     }
27355
27356                 }
27357
27358             }
27359
27360         }
27361
27362         // Use unique set of vertices
27363
27364         var diff = this.vertices.length - unique.length;
27365         this.vertices = unique;
27366         return diff;
27367
27368     },
27369
27370     clone: function () {
27371
27372         // TODO
27373
27374     }
27375
27376 };
27377
27378 THREE.GeometryCount = 0;
27379 /**
27380  * @author alteredq / http://alteredqualia.com/
27381  */
27382
27383 THREE.BufferGeometry = function () {
27384
27385     this.id = THREE.GeometryCount ++;
27386
27387     // attributes
27388
27389     this.attributes = {};
27390
27391     // attributes typed arrays are kept only if dynamic flag is set
27392
27393     this.dynamic = false;
27394
27395     // boundings
27396
27397     this.boundingBox = null;
27398     this.boundingSphere = null;
27399
27400     this.hasTangents = false;
27401
27402     // for compatibility
27403
27404     this.morphTargets = [];
27405
27406 };
27407
27408 THREE.BufferGeometry.prototype = {
27409
27410     constructor : THREE.BufferGeometry,
27411
27412     applyMatrix: function ( matrix ) {
27413
27414         var positionArray;
27415         var normalArray;
27416
27417         if ( this.attributes[ "position" ] ) positionArray = this.attributes[ "position" ].array;
27418         if ( this.attributes[ "normal" ] ) normalArray = this.attributes[ "normal" ].array;
27419
27420         if ( positionArray !== undefined ) {
27421
27422             matrix.multiplyVector3Array( positionArray );
27423             this.verticesNeedUpdate = true;
27424
27425         }
27426
27427         if ( normalArray !== undefined ) {
27428
27429             var matrixRotation = new THREE.Matrix4();
27430             matrixRotation.extractRotation( matrix );
27431
27432             matrixRotation.multiplyVector3Array( normalArray );
27433             this.normalsNeedUpdate = true;
27434
27435         }
27436
27437     },
27438
27439     computeBoundingBox: function () {
27440
27441         if ( ! this.boundingBox ) {
27442
27443             this.boundingBox = {
27444
27445                 min: new THREE.Vector3( Infinity, Infinity, Infinity ),
27446                 max: new THREE.Vector3( -Infinity, -Infinity, -Infinity )
27447
27448             };
27449
27450         }
27451
27452         var positions = this.attributes[ "position" ].array;
27453
27454         if ( positions ) {
27455
27456             var bb = this.boundingBox;
27457             var x, y, z;
27458
27459             for ( var i = 0, il = positions.length; i < il; i += 3 ) {
27460
27461                 x = positions[ i ];
27462                 y = positions[ i + 1 ];
27463                 z = positions[ i + 2 ];
27464
27465                 // bounding box
27466
27467                 if ( x < bb.min.x ) {
27468
27469                     bb.min.x = x;
27470
27471                 } else if ( x > bb.max.x ) {
27472
27473                     bb.max.x = x;
27474
27475                 }
27476
27477                 if ( y < bb.min.y ) {
27478
27479                     bb.min.y = y;
27480
27481                 } else if ( y > bb.max.y ) {
27482
27483                     bb.max.y = y;
27484
27485                 }
27486
27487                 if ( z < bb.min.z ) {
27488
27489                     bb.min.z = z;
27490
27491                 } else if ( z > bb.max.z ) {
27492
27493                     bb.max.z = z;
27494
27495                 }
27496
27497             }
27498
27499         }
27500
27501         if ( positions === undefined || positions.length === 0 ) {
27502
27503             this.boundingBox.min.set( 0, 0, 0 );
27504             this.boundingBox.max.set( 0, 0, 0 );
27505
27506         }
27507
27508     },
27509
27510     computeBoundingSphere: function () {
27511
27512         if ( ! this.boundingSphere ) this.boundingSphere = { radius: 0 };
27513
27514         var positions = this.attributes[ "position" ].array;
27515
27516         if ( positions ) {
27517
27518             var radiusSq, maxRadiusSq = 0;
27519             var x, y, z;
27520
27521             for ( var i = 0, il = positions.length; i < il; i += 3 ) {
27522
27523                 x = positions[ i ];
27524                 y = positions[ i + 1 ];
27525                 z = positions[ i + 2 ];
27526
27527                 radiusSq =  x * x + y * y + z * z;
27528                 if ( radiusSq > maxRadiusSq ) maxRadiusSq = radiusSq;
27529
27530             }
27531
27532             this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
27533
27534         }
27535
27536     },
27537
27538     computeVertexNormals: function () {
27539
27540         if ( this.attributes[ "position" ] && this.attributes[ "index" ] ) {
27541
27542             var i, il;
27543             var j, jl;
27544
27545             var nVertexElements = this.attributes[ "position" ].array.length;
27546
27547             if ( this.attributes[ "normal" ] === undefined ) {
27548
27549                 this.attributes[ "normal" ] = {
27550
27551                     itemSize: 3,
27552                     array: new Float32Array( nVertexElements ),
27553                     numItems: nVertexElements
27554
27555                 };
27556
27557             } else {
27558
27559                 // reset existing normals to zero
27560
27561                 for ( i = 0, il = this.attributes[ "normal" ].array.length; i < il; i ++ ) {
27562
27563                     this.attributes[ "normal" ].array[ i ] = 0;
27564
27565                 }
27566
27567             }
27568
27569             var offsets = this.offsets;
27570
27571             var indices = this.attributes[ "index" ].array;
27572             var positions = this.attributes[ "position" ].array;
27573             var normals = this.attributes[ "normal" ].array;
27574
27575             var vA, vB, vC, x, y, z,
27576
27577             pA = new THREE.Vector3(),
27578             pB = new THREE.Vector3(),
27579             pC = new THREE.Vector3(),
27580
27581             cb = new THREE.Vector3(),
27582             ab = new THREE.Vector3();
27583
27584             for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
27585
27586                 var start = offsets[ j ].start;
27587                 var count = offsets[ j ].count;
27588                 var index = offsets[ j ].index;
27589
27590                 for ( i = start, il = start + count; i < il; i += 3 ) {
27591
27592                     vA = index + indices[ i ];
27593                     vB = index + indices[ i + 1 ];
27594                     vC = index + indices[ i + 2 ];
27595
27596                     x = positions[ vA * 3 ];
27597                     y = positions[ vA * 3 + 1 ];
27598                     z = positions[ vA * 3 + 2 ];
27599                     pA.set( x, y, z );
27600
27601                     x = positions[ vB * 3 ];
27602                     y = positions[ vB * 3 + 1 ];
27603                     z = positions[ vB * 3 + 2 ];
27604                     pB.set( x, y, z );
27605
27606                     x = positions[ vC * 3 ];
27607                     y = positions[ vC * 3 + 1 ];
27608                     z = positions[ vC * 3 + 2 ];
27609                     pC.set( x, y, z );
27610
27611                     cb.sub( pC, pB );
27612                     ab.sub( pA, pB );
27613                     cb.crossSelf( ab );
27614
27615                     normals[ vA * 3 ] += cb.x;
27616                     normals[ vA * 3 + 1 ] += cb.y;
27617                     normals[ vA * 3 + 2 ] += cb.z;
27618
27619                     normals[ vB * 3 ] += cb.x;
27620                     normals[ vB * 3 + 1 ] += cb.y;
27621                     normals[ vB * 3 + 2 ] += cb.z;
27622
27623                     normals[ vC * 3 ] += cb.x;
27624                     normals[ vC * 3 + 1 ] += cb.y;
27625                     normals[ vC * 3 + 2 ] += cb.z;
27626
27627                 }
27628
27629             }
27630
27631             // normalize normals
27632
27633             for ( i = 0, il = normals.length; i < il; i += 3 ) {
27634
27635                 x = normals[ i ];
27636                 y = normals[ i + 1 ];
27637                 z = normals[ i + 2 ];
27638
27639                 var n = 1.0 / Math.sqrt( x * x + y * y + z * z );
27640
27641                 normals[ i ] *= n;
27642                 normals[ i + 1 ] *= n;
27643                 normals[ i + 2 ] *= n;
27644
27645             }
27646
27647             this.normalsNeedUpdate = true;
27648
27649         }
27650
27651     },
27652
27653     computeTangents: function () {
27654
27655         // based on http://www.terathon.com/code/tangent.html
27656         // (per vertex tangents)
27657
27658         if ( this.attributes[ "index" ] === undefined ||
27659              this.attributes[ "position" ] === undefined ||
27660              this.attributes[ "normal" ] === undefined ||
27661              this.attributes[ "uv" ] === undefined ) {
27662
27663             console.warn( "Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()" );
27664             return;
27665
27666         }
27667
27668         var indices = this.attributes[ "index" ].array;
27669         var positions = this.attributes[ "position" ].array;
27670         var normals = this.attributes[ "normal" ].array;
27671         var uvs = this.attributes[ "uv" ].array;
27672
27673         var nVertices = positions.length / 3;
27674
27675         if ( this.attributes[ "tangent" ] === undefined ) {
27676
27677             var nTangentElements = 4 * nVertices;
27678
27679             this.attributes[ "tangent" ] = {
27680
27681                 itemSize: 4,
27682                 array: new Float32Array( nTangentElements ),
27683                 numItems: nTangentElements
27684
27685             };
27686
27687         }
27688
27689         var tangents = this.attributes[ "tangent" ].array;
27690
27691         var tan1 = [], tan2 = [];
27692
27693         for ( var k = 0; k < nVertices; k ++ ) {
27694
27695             tan1[ k ] = new THREE.Vector3();
27696             tan2[ k ] = new THREE.Vector3();
27697
27698         }
27699
27700         var xA, yA, zA,
27701             xB, yB, zB,
27702             xC, yC, zC,
27703
27704             uA, vA,
27705             uB, vB,
27706             uC, vC,
27707
27708             x1, x2, y1, y2, z1, z2,
27709             s1, s2, t1, t2, r;
27710
27711         var sdir = new THREE.Vector3(), tdir = new THREE.Vector3();
27712
27713         function handleTriangle( a, b, c ) {
27714
27715             xA = positions[ a * 3 ];
27716             yA = positions[ a * 3 + 1 ];
27717             zA = positions[ a * 3 + 2 ];
27718
27719             xB = positions[ b * 3 ];
27720             yB = positions[ b * 3 + 1 ];
27721             zB = positions[ b * 3 + 2 ];
27722
27723             xC = positions[ c * 3 ];
27724             yC = positions[ c * 3 + 1 ];
27725             zC = positions[ c * 3 + 2 ];
27726
27727             uA = uvs[ a * 2 ];
27728             vA = uvs[ a * 2 + 1 ];
27729
27730             uB = uvs[ b * 2 ];
27731             vB = uvs[ b * 2 + 1 ];
27732
27733             uC = uvs[ c * 2 ];
27734             vC = uvs[ c * 2 + 1 ];
27735
27736             x1 = xB - xA;
27737             x2 = xC - xA;
27738
27739             y1 = yB - yA;
27740             y2 = yC - yA;
27741
27742             z1 = zB - zA;
27743             z2 = zC - zA;
27744
27745             s1 = uB - uA;
27746             s2 = uC - uA;
27747
27748             t1 = vB - vA;
27749             t2 = vC - vA;
27750
27751             r = 1.0 / ( s1 * t2 - s2 * t1 );
27752
27753             sdir.set(
27754                 ( t2 * x1 - t1 * x2 ) * r,
27755                 ( t2 * y1 - t1 * y2 ) * r,
27756                 ( t2 * z1 - t1 * z2 ) * r
27757             );
27758
27759             tdir.set(
27760                 ( s1 * x2 - s2 * x1 ) * r,
27761                 ( s1 * y2 - s2 * y1 ) * r,
27762                 ( s1 * z2 - s2 * z1 ) * r
27763             );
27764
27765             tan1[ a ].addSelf( sdir );
27766             tan1[ b ].addSelf( sdir );
27767             tan1[ c ].addSelf( sdir );
27768
27769             tan2[ a ].addSelf( tdir );
27770             tan2[ b ].addSelf( tdir );
27771             tan2[ c ].addSelf( tdir );
27772
27773         }
27774
27775         var i, il;
27776         var j, jl;
27777         var iA, iB, iC;
27778
27779         var offsets = this.offsets;
27780
27781         for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
27782
27783             var start = offsets[ j ].start;
27784             var count = offsets[ j ].count;
27785             var index = offsets[ j ].index;
27786
27787             for ( i = start, il = start + count; i < il; i += 3 ) {
27788
27789                 iA = index + indices[ i ];
27790                 iB = index + indices[ i + 1 ];
27791                 iC = index + indices[ i + 2 ];
27792
27793                 handleTriangle( iA, iB, iC );
27794
27795             }
27796
27797         }
27798
27799         var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
27800         var n = new THREE.Vector3(), n2 = new THREE.Vector3();
27801         var w, t, test;
27802         var nx, ny, nz;
27803
27804         function handleVertex( v ) {
27805
27806             n.x = normals[ v * 3 ];
27807             n.y = normals[ v * 3 + 1 ];
27808             n.z = normals[ v * 3 + 2 ];
27809
27810             n2.copy( n );
27811
27812             t = tan1[ v ];
27813
27814             // Gram-Schmidt orthogonalize
27815
27816             tmp.copy( t );
27817             tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
27818
27819             // Calculate handedness
27820
27821             tmp2.cross( n2, t );
27822             test = tmp2.dot( tan2[ v ] );
27823             w = ( test < 0.0 ) ? -1.0 : 1.0;
27824
27825             tangents[ v * 4 ]       = tmp.x;
27826             tangents[ v * 4 + 1 ] = tmp.y;
27827             tangents[ v * 4 + 2 ] = tmp.z;
27828             tangents[ v * 4 + 3 ] = w;
27829
27830         }
27831
27832         for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
27833
27834             var start = offsets[ j ].start;
27835             var count = offsets[ j ].count;
27836             var index = offsets[ j ].index;
27837
27838             for ( i = start, il = start + count; i < il; i += 3 ) {
27839
27840                 iA = index + indices[ i ];
27841                 iB = index + indices[ i + 1 ];
27842                 iC = index + indices[ i + 2 ];
27843
27844                 handleVertex( iA );
27845                 handleVertex( iB );
27846                 handleVertex( iC );
27847
27848             }
27849
27850         }
27851
27852         this.hasTangents = true;
27853         this.tangentsNeedUpdate = true;
27854
27855     }
27856
27857 };
27858
27859 /**
27860  * Spline from Tween.js, slightly optimized (and trashed)
27861  * http://sole.github.com/tween.js/examples/05_spline.html
27862  *
27863  * @author mrdoob / http://mrdoob.com/
27864  * @author alteredq / http://alteredqualia.com/
27865  */
27866
27867 THREE.Spline = function ( points ) {
27868
27869     this.points = points;
27870
27871     var c = [], v3 = { x: 0, y: 0, z: 0 },
27872     point, intPoint, weight, w2, w3,
27873     pa, pb, pc, pd;
27874
27875     this.initFromArray = function( a ) {
27876
27877         this.points = [];
27878
27879         for ( var i = 0; i < a.length; i++ ) {
27880
27881             this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };
27882
27883         }
27884
27885     };
27886
27887     this.getPoint = function ( k ) {
27888
27889         point = ( this.points.length - 1 ) * k;
27890         intPoint = Math.floor( point );
27891         weight = point - intPoint;
27892
27893         c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
27894         c[ 1 ] = intPoint;
27895         c[ 2 ] = intPoint  > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;
27896         c[ 3 ] = intPoint  > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;
27897
27898         pa = this.points[ c[ 0 ] ];
27899         pb = this.points[ c[ 1 ] ];
27900         pc = this.points[ c[ 2 ] ];
27901         pd = this.points[ c[ 3 ] ];
27902
27903         w2 = weight * weight;
27904         w3 = weight * w2;
27905
27906         v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );
27907         v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );
27908         v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );
27909
27910         return v3;
27911
27912     };
27913
27914     this.getControlPointsArray = function () {
27915
27916         var i, p, l = this.points.length,
27917             coords = [];
27918
27919         for ( i = 0; i < l; i ++ ) {
27920
27921             p = this.points[ i ];
27922             coords[ i ] = [ p.x, p.y, p.z ];
27923
27924         }
27925
27926         return coords;
27927
27928     };
27929
27930     // approximate length by summing linear segments
27931
27932     this.getLength = function ( nSubDivisions ) {
27933
27934         var i, index, nSamples, position,
27935             point = 0, intPoint = 0, oldIntPoint = 0,
27936             oldPosition = new THREE.Vector3(),
27937             tmpVec = new THREE.Vector3(),
27938             chunkLengths = [],
27939             totalLength = 0;
27940
27941         // first point has 0 length
27942
27943         chunkLengths[ 0 ] = 0;
27944
27945         if ( !nSubDivisions ) nSubDivisions = 100;
27946
27947         nSamples = this.points.length * nSubDivisions;
27948
27949         oldPosition.copy( this.points[ 0 ] );
27950
27951         for ( i = 1; i < nSamples; i ++ ) {
27952
27953             index = i / nSamples;
27954
27955             position = this.getPoint( index );
27956             tmpVec.copy( position );
27957
27958             totalLength += tmpVec.distanceTo( oldPosition );
27959
27960             oldPosition.copy( position );
27961
27962             point = ( this.points.length - 1 ) * index;
27963             intPoint = Math.floor( point );
27964
27965             if ( intPoint != oldIntPoint ) {
27966
27967                 chunkLengths[ intPoint ] = totalLength;
27968                 oldIntPoint = intPoint;
27969
27970             }
27971
27972         }
27973
27974         // last point ends with total length
27975
27976         chunkLengths[ chunkLengths.length ] = totalLength;
27977
27978         return { chunks: chunkLengths, total: totalLength };
27979
27980     };
27981
27982     this.reparametrizeByArcLength = function ( samplingCoef ) {
27983
27984         var i, j,
27985             index, indexCurrent, indexNext,
27986             linearDistance, realDistance,
27987             sampling, position,
27988             newpoints = [],
27989             tmpVec = new THREE.Vector3(),
27990             sl = this.getLength();
27991
27992         newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );
27993
27994         for ( i = 1; i < this.points.length; i++ ) {
27995
27996             //tmpVec.copy( this.points[ i - 1 ] );
27997             //linearDistance = tmpVec.distanceTo( this.points[ i ] );
27998
27999             realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];
28000
28001             sampling = Math.ceil( samplingCoef * realDistance / sl.total );
28002
28003             indexCurrent = ( i - 1 ) / ( this.points.length - 1 );
28004             indexNext = i / ( this.points.length - 1 );
28005
28006             for ( j = 1; j < sampling - 1; j++ ) {
28007
28008                 index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );
28009
28010                 position = this.getPoint( index );
28011                 newpoints.push( tmpVec.copy( position ).clone() );
28012
28013             }
28014
28015             newpoints.push( tmpVec.copy( this.points[ i ] ).clone() );
28016
28017         }
28018
28019         this.points = newpoints;
28020
28021     };
28022
28023     // Catmull-Rom
28024
28025     function interpolate( p0, p1, p2, p3, t, t2, t3 ) {
28026
28027         var v0 = ( p2 - p0 ) * 0.5,
28028             v1 = ( p3 - p1 ) * 0.5;
28029
28030         return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
28031
28032     };
28033
28034 };
28035 /**
28036  * @author mrdoob / http://mrdoob.com/
28037  * @author mikael emtinger / http://gomo.se/
28038  */
28039
28040 THREE.Camera = function () {
28041
28042     THREE.Object3D.call( this );
28043
28044     this.matrixWorldInverse = new THREE.Matrix4();
28045
28046     this.projectionMatrix = new THREE.Matrix4();
28047     this.projectionMatrixInverse = new THREE.Matrix4();
28048
28049 };
28050
28051 THREE.Camera.prototype = Object.create( THREE.Object3D.prototype );
28052
28053 THREE.Camera.prototype.lookAt = function ( vector ) {
28054
28055     // TODO: Add hierarchy support.
28056
28057     this.matrix.lookAt( this.position, vector, this.up );
28058
28059     if ( this.rotationAutoUpdate === true ) {
28060
28061         this.rotation.setEulerFromRotationMatrix( this.matrix, this.eulerOrder );
28062
28063     }
28064
28065 };
28066 /**
28067  * @author alteredq / http://alteredqualia.com/
28068  */
28069
28070 THREE.OrthographicCamera = function ( left, right, top, bottom, near, far ) {
28071
28072     THREE.Camera.call( this );
28073
28074     this.left = left;
28075     this.right = right;
28076     this.top = top;
28077     this.bottom = bottom;
28078
28079     this.near = ( near !== undefined ) ? near : 0.1;
28080     this.far = ( far !== undefined ) ? far : 2000;
28081
28082     this.updateProjectionMatrix();
28083
28084 };
28085
28086 THREE.OrthographicCamera.prototype = Object.create( THREE.Camera.prototype );
28087
28088 THREE.OrthographicCamera.prototype.updateProjectionMatrix = function () {
28089
28090     this.projectionMatrix.makeOrthographic( this.left, this.right, this.top, this.bottom, this.near, this.far );
28091
28092 };
28093 /**
28094  * @author mrdoob / http://mrdoob.com/
28095  * @author greggman / http://games.greggman.com/
28096  * @author zz85 / http://www.lab4games.net/zz85/blog
28097  */
28098
28099 THREE.PerspectiveCamera = function ( fov, aspect, near, far ) {
28100
28101     THREE.Camera.call( this );
28102
28103     this.fov = fov !== undefined ? fov : 50;
28104     this.aspect = aspect !== undefined ? aspect : 1;
28105     this.near = near !== undefined ? near : 0.1;
28106     this.far = far !== undefined ? far : 2000;
28107
28108     this.updateProjectionMatrix();
28109
28110 };
28111
28112 THREE.PerspectiveCamera.prototype = Object.create( THREE.Camera.prototype );
28113
28114
28115 /**
28116  * Uses Focal Length (in mm) to estimate and set FOV
28117  * 35mm (fullframe) camera is used if frame size is not specified;
28118  * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
28119  */
28120
28121 THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) {
28122
28123     if ( frameHeight === undefined ) frameHeight = 24;
28124
28125     this.fov = 2 * Math.atan( frameHeight / ( focalLength * 2 ) ) * ( 180 / Math.PI );
28126     this.updateProjectionMatrix();
28127
28128 }
28129
28130
28131 /**
28132  * Sets an offset in a larger frustum. This is useful for multi-window or
28133  * multi-monitor/multi-machine setups.
28134  *
28135  * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
28136  * the monitors are in grid like this
28137  *
28138  *   +---+---+---+
28139  *   | A | B | C |
28140  *   +---+---+---+
28141  *   | D | E | F |
28142  *   +---+---+---+
28143  *
28144  * then for each monitor you would call it like this
28145  *
28146  *   var w = 1920;
28147  *   var h = 1080;
28148  *   var fullWidth = w * 3;
28149  *   var fullHeight = h * 2;
28150  *
28151  *   --A--
28152  *   camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
28153  *   --B--
28154  *   camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
28155  *   --C--
28156  *   camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
28157  *   --D--
28158  *   camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
28159  *   --E--
28160  *   camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
28161  *   --F--
28162  *   camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
28163  *
28164  *   Note there is no reason monitors have to be the same size or in a grid.
28165  */
28166
28167 THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) {
28168
28169     this.fullWidth = fullWidth;
28170     this.fullHeight = fullHeight;
28171     this.x = x;
28172     this.y = y;
28173     this.width = width;
28174     this.height = height;
28175
28176     this.updateProjectionMatrix();
28177
28178 };
28179
28180
28181 THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () {
28182
28183     if ( this.fullWidth ) {
28184
28185         var aspect = this.fullWidth / this.fullHeight;
28186         var top = Math.tan( this.fov * Math.PI / 360 ) * this.near;
28187         var bottom = -top;
28188         var left = aspect * bottom;
28189         var right = aspect * top;
28190         var width = Math.abs( right - left );
28191         var height = Math.abs( top - bottom );
28192
28193         this.projectionMatrix.makeFrustum(
28194             left + this.x * width / this.fullWidth,
28195             left + ( this.x + this.width ) * width / this.fullWidth,
28196             top - ( this.y + this.height ) * height / this.fullHeight,
28197             top - this.y * height / this.fullHeight,
28198             this.near,
28199             this.far
28200         );
28201
28202     } else {
28203
28204         this.projectionMatrix.makePerspective( this.fov, this.aspect, this.near, this.far );
28205
28206     }
28207
28208 };
28209 /**
28210  * @author mrdoob / http://mrdoob.com/
28211  * @author alteredq / http://alteredqualia.com/
28212  */
28213
28214 THREE.Light = function ( hex ) {
28215
28216     THREE.Object3D.call( this );
28217
28218     this.color = new THREE.Color( hex );
28219
28220 };
28221
28222 THREE.Light.prototype = Object.create( THREE.Object3D.prototype );
28223 /**
28224  * @author mrdoob / http://mrdoob.com/
28225  */
28226
28227 THREE.AmbientLight = function ( hex ) {
28228
28229     THREE.Light.call( this, hex );
28230
28231 };
28232
28233 THREE.AmbientLight.prototype = Object.create( THREE.Light.prototype );
28234 /**
28235  * @author mrdoob / http://mrdoob.com/
28236  * @author alteredq / http://alteredqualia.com/
28237  */
28238
28239 THREE.DirectionalLight = function ( hex, intensity, distance ) {
28240
28241     THREE.Light.call( this, hex );
28242
28243     this.position = new THREE.Vector3( 0, 1, 0 );
28244     this.target = new THREE.Object3D();
28245
28246     this.intensity = ( intensity !== undefined ) ? intensity : 1;
28247     this.distance = ( distance !== undefined ) ? distance : 0;
28248
28249     this.castShadow = false;
28250     this.onlyShadow = false;
28251
28252     //
28253
28254     this.shadowCameraNear = 50;
28255     this.shadowCameraFar = 5000;
28256
28257     this.shadowCameraLeft = -500;
28258     this.shadowCameraRight = 500;
28259     this.shadowCameraTop = 500;
28260     this.shadowCameraBottom = -500;
28261
28262     this.shadowCameraVisible = false;
28263
28264     this.shadowBias = 0;
28265     this.shadowDarkness = 0.5;
28266
28267     this.shadowMapWidth = 512;
28268     this.shadowMapHeight = 512;
28269
28270     //
28271
28272     this.shadowCascade = false;
28273
28274     this.shadowCascadeOffset = new THREE.Vector3( 0, 0, -1000 );
28275     this.shadowCascadeCount = 2;
28276
28277     this.shadowCascadeBias = [ 0, 0, 0 ];
28278     this.shadowCascadeWidth = [ 512, 512, 512 ];
28279     this.shadowCascadeHeight = [ 512, 512, 512 ];
28280
28281     this.shadowCascadeNearZ = [ -1.000, 0.990, 0.998 ];
28282     this.shadowCascadeFarZ  = [  0.990, 0.998, 1.000 ];
28283
28284     this.shadowCascadeArray = [];
28285
28286     //
28287
28288     this.shadowMap = null;
28289     this.shadowMapSize = null;
28290     this.shadowCamera = null;
28291     this.shadowMatrix = null;
28292
28293 };
28294
28295 THREE.DirectionalLight.prototype = Object.create( THREE.Light.prototype );
28296 /**
28297  * @author alteredq / http://alteredqualia.com/
28298  */
28299
28300 THREE.HemisphereLight = function ( skyColorHex, groundColorHex, intensity ) {
28301
28302     THREE.Light.call( this, skyColorHex );
28303
28304     this.groundColor = new THREE.Color( groundColorHex );
28305
28306     this.position = new THREE.Vector3( 0, 100, 0 );
28307
28308     this.intensity = ( intensity !== undefined ) ? intensity : 1;
28309
28310 };
28311
28312 THREE.HemisphereLight.prototype = Object.create( THREE.Light.prototype );
28313 /**
28314  * @author mrdoob / http://mrdoob.com/
28315  */
28316
28317 THREE.PointLight = function ( hex, intensity, distance ) {
28318
28319     THREE.Light.call( this, hex );
28320
28321     this.position = new THREE.Vector3( 0, 0, 0 );
28322     this.intensity = ( intensity !== undefined ) ? intensity : 1;
28323     this.distance = ( distance !== undefined ) ? distance : 0;
28324
28325 };
28326
28327 THREE.PointLight.prototype = Object.create( THREE.Light.prototype );
28328 /**
28329  * @author alteredq / http://alteredqualia.com/
28330  */
28331
28332 THREE.SpotLight = function ( hex, intensity, distance, angle, exponent ) {
28333
28334     THREE.Light.call( this, hex );
28335
28336     this.position = new THREE.Vector3( 0, 1, 0 );
28337     this.target = new THREE.Object3D();
28338
28339     this.intensity = ( intensity !== undefined ) ? intensity : 1;
28340     this.distance = ( distance !== undefined ) ? distance : 0;
28341     this.angle = ( angle !== undefined ) ? angle : Math.PI / 2;
28342     this.exponent = ( exponent !== undefined ) ? exponent : 10;
28343
28344     this.castShadow = false;
28345     this.onlyShadow = false;
28346
28347     //
28348
28349     this.shadowCameraNear = 50;
28350     this.shadowCameraFar = 5000;
28351     this.shadowCameraFov = 50;
28352
28353     this.shadowCameraVisible = false;
28354
28355     this.shadowBias = 0;
28356     this.shadowDarkness = 0.5;
28357
28358     this.shadowMapWidth = 512;
28359     this.shadowMapHeight = 512;
28360
28361     //
28362
28363     this.shadowMap = null;
28364     this.shadowMapSize = null;
28365     this.shadowCamera = null;
28366     this.shadowMatrix = null;
28367
28368 };
28369
28370 THREE.SpotLight.prototype = Object.create( THREE.Light.prototype );
28371 /**
28372  * @author alteredq / http://alteredqualia.com/
28373  */
28374
28375 THREE.Loader = function ( showStatus ) {
28376
28377     this.showStatus = showStatus;
28378     this.statusDomElement = showStatus ? THREE.Loader.prototype.addStatusElement() : null;
28379
28380     this.onLoadStart = function () {};
28381     this.onLoadProgress = function () {};
28382     this.onLoadComplete = function () {};
28383
28384 };
28385
28386 THREE.Loader.prototype = {
28387
28388     constructor: THREE.Loader,
28389
28390     crossOrigin: 'anonymous',
28391
28392     addStatusElement: function () {
28393
28394         var e = document.createElement( "div" );
28395
28396         e.style.position = "absolute";
28397         e.style.right = "0px";
28398         e.style.top = "0px";
28399         e.style.fontSize = "0.8em";
28400         e.style.textAlign = "left";
28401         e.style.background = "rgba(0,0,0,0.25)";
28402         e.style.color = "#fff";
28403         e.style.width = "120px";
28404         e.style.padding = "0.5em 0.5em 0.5em 0.5em";
28405         e.style.zIndex = 1000;
28406
28407         e.innerHTML = "Loading ...";
28408
28409         return e;
28410
28411     },
28412
28413     updateProgress: function ( progress ) {
28414
28415         var message = "Loaded ";
28416
28417         if ( progress.total ) {
28418
28419             message += ( 100 * progress.loaded / progress.total ).toFixed(0) + "%";
28420
28421
28422         } else {
28423
28424             message += ( progress.loaded / 1000 ).toFixed(2) + " KB";
28425
28426         }
28427
28428         this.statusDomElement.innerHTML = message;
28429
28430     },
28431
28432     extractUrlBase: function ( url ) {
28433
28434         var parts = url.split( '/' );
28435         parts.pop();
28436         return ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
28437
28438     },
28439
28440     initMaterials: function ( scope, materials, texturePath ) {
28441
28442         scope.materials = [];
28443
28444         for ( var i = 0; i < materials.length; ++ i ) {
28445
28446             scope.materials[ i ] = THREE.Loader.prototype.createMaterial( materials[ i ], texturePath );
28447
28448         }
28449
28450     },
28451
28452     hasNormals: function ( scope ) {
28453
28454         var m, i, il = scope.materials.length;
28455
28456         for( i = 0; i < il; i ++ ) {
28457
28458             m = scope.materials[ i ];
28459
28460             if ( m instanceof THREE.ShaderMaterial ) return true;
28461
28462         }
28463
28464         return false;
28465
28466     },
28467
28468     createMaterial: function ( m, texturePath ) {
28469
28470         var _this = this;
28471
28472         function is_pow2( n ) {
28473
28474             var l = Math.log( n ) / Math.LN2;
28475             return Math.floor( l ) == l;
28476
28477         }
28478
28479         function nearest_pow2( n ) {
28480
28481             var l = Math.log( n ) / Math.LN2;
28482             return Math.pow( 2, Math.round(  l ) );
28483
28484         }
28485
28486         function load_image( where, url ) {
28487
28488             var image = new Image();
28489
28490             image.onload = function () {
28491
28492                 if ( !is_pow2( this.width ) || !is_pow2( this.height ) ) {
28493
28494                     var width = nearest_pow2( this.width );
28495                     var height = nearest_pow2( this.height );
28496
28497                     where.image.width = width;
28498                     where.image.height = height;
28499                     where.image.getContext( '2d' ).drawImage( this, 0, 0, width, height );
28500
28501                 } else {
28502
28503                     where.image = this;
28504
28505                 }
28506
28507                 where.needsUpdate = true;
28508
28509             };
28510
28511             image.crossOrigin = _this.crossOrigin;
28512             image.src = url;
28513
28514         }
28515
28516         function create_texture( where, name, sourceFile, repeat, offset, wrap, anisotropy ) {
28517
28518             var isCompressed = sourceFile.toLowerCase().endsWith( ".dds" );
28519             var fullPath = texturePath + "/" + sourceFile;
28520
28521             if ( isCompressed ) {
28522
28523                 var texture = THREE.ImageUtils.loadCompressedTexture( fullPath );
28524
28525                 where[ name ] = texture;
28526
28527             } else {
28528
28529                 var texture = document.createElement( 'canvas' );
28530
28531                 where[ name ] = new THREE.Texture( texture );
28532
28533             }
28534
28535             where[ name ].sourceFile = sourceFile;
28536
28537             if( repeat ) {
28538
28539                 where[ name ].repeat.set( repeat[ 0 ], repeat[ 1 ] );
28540
28541                 if ( repeat[ 0 ] !== 1 ) where[ name ].wrapS = THREE.RepeatWrapping;
28542                 if ( repeat[ 1 ] !== 1 ) where[ name ].wrapT = THREE.RepeatWrapping;
28543
28544             }
28545
28546             if ( offset ) {
28547
28548                 where[ name ].offset.set( offset[ 0 ], offset[ 1 ] );
28549
28550             }
28551
28552             if ( wrap ) {
28553
28554                 var wrapMap = {
28555                     "repeat": THREE.RepeatWrapping,
28556                     "mirror": THREE.MirroredRepeatWrapping
28557                 }
28558
28559                 if ( wrapMap[ wrap[ 0 ] ] !== undefined ) where[ name ].wrapS = wrapMap[ wrap[ 0 ] ];
28560                 if ( wrapMap[ wrap[ 1 ] ] !== undefined ) where[ name ].wrapT = wrapMap[ wrap[ 1 ] ];
28561
28562             }
28563
28564             if ( anisotropy ) {
28565
28566                 where[ name ].anisotropy = anisotropy;
28567
28568             }
28569
28570             if ( ! isCompressed ) {
28571
28572                 load_image( where[ name ], fullPath );
28573
28574             }
28575
28576         }
28577
28578         function rgb2hex( rgb ) {
28579
28580             return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255;
28581
28582         }
28583
28584         // defaults
28585
28586         var mtype = "MeshLambertMaterial";
28587         var mpars = { color: 0xeeeeee, opacity: 1.0, map: null, lightMap: null, normalMap: null, bumpMap: null, wireframe: false };
28588
28589         // parameters from model file
28590
28591         if ( m.shading ) {
28592
28593             var shading = m.shading.toLowerCase();
28594
28595             if ( shading === "phong" ) mtype = "MeshPhongMaterial";
28596             else if ( shading === "basic" ) mtype = "MeshBasicMaterial";
28597
28598         }
28599
28600         if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) {
28601
28602             mpars.blending = THREE[ m.blending ];
28603
28604         }
28605
28606         if ( m.transparent !== undefined || m.opacity < 1.0 ) {
28607
28608             mpars.transparent = m.transparent;
28609
28610         }
28611
28612         if ( m.depthTest !== undefined ) {
28613
28614             mpars.depthTest = m.depthTest;
28615
28616         }
28617
28618         if ( m.depthWrite !== undefined ) {
28619
28620             mpars.depthWrite = m.depthWrite;
28621
28622         }
28623
28624         if ( m.visible !== undefined ) {
28625
28626             mpars.visible = m.visible;
28627
28628         }
28629
28630         if ( m.flipSided !== undefined ) {
28631
28632             mpars.side = THREE.BackSide;
28633
28634         }
28635
28636         if ( m.doubleSided !== undefined ) {
28637
28638             mpars.side = THREE.DoubleSide;
28639
28640         }
28641
28642         if ( m.wireframe !== undefined ) {
28643
28644             mpars.wireframe = m.wireframe;
28645
28646         }
28647
28648         if ( m.vertexColors !== undefined ) {
28649
28650             if ( m.vertexColors === "face" ) {
28651
28652                 mpars.vertexColors = THREE.FaceColors;
28653
28654             } else if ( m.vertexColors ) {
28655
28656                 mpars.vertexColors = THREE.VertexColors;
28657
28658             }
28659
28660         }
28661
28662         // colors
28663
28664         if ( m.colorDiffuse ) {
28665
28666             mpars.color = rgb2hex( m.colorDiffuse );
28667
28668         } else if ( m.DbgColor ) {
28669
28670             mpars.color = m.DbgColor;
28671
28672         }
28673
28674         if ( m.colorSpecular ) {
28675
28676             mpars.specular = rgb2hex( m.colorSpecular );
28677
28678         }
28679
28680         if ( m.colorAmbient ) {
28681
28682             mpars.ambient = rgb2hex( m.colorAmbient );
28683
28684         }
28685
28686         // modifiers
28687
28688         if ( m.transparency ) {
28689
28690             mpars.opacity = m.transparency;
28691
28692         }
28693
28694         if ( m.specularCoef ) {
28695
28696             mpars.shininess = m.specularCoef;
28697
28698         }
28699
28700         // textures
28701
28702         if ( m.mapDiffuse && texturePath ) {
28703
28704             create_texture( mpars, "map", m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );
28705
28706         }
28707
28708         if ( m.mapLight && texturePath ) {
28709
28710             create_texture( mpars, "lightMap", m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );
28711
28712         }
28713
28714         if ( m.mapBump && texturePath ) {
28715
28716             create_texture( mpars, "bumpMap", m.mapBump, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );
28717
28718         }
28719
28720         if ( m.mapNormal && texturePath ) {
28721
28722             create_texture( mpars, "normalMap", m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );
28723
28724         }
28725
28726         if ( m.mapSpecular && texturePath ) {
28727
28728             create_texture( mpars, "specularMap", m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );
28729
28730         }
28731
28732         //
28733
28734         if ( m.mapBumpScale ) {
28735
28736             mpars.bumpScale = m.mapBumpScale;
28737
28738         }
28739
28740         // special case for normal mapped material
28741
28742         if ( m.mapNormal ) {
28743
28744             var shader = THREE.ShaderUtils.lib[ "normal" ];
28745             var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
28746
28747             uniforms[ "tNormal" ].value = mpars.normalMap;
28748
28749             if ( m.mapNormalFactor ) {
28750
28751                 uniforms[ "uNormalScale" ].value.set( m.mapNormalFactor, m.mapNormalFactor );
28752
28753             }
28754
28755             if ( mpars.map ) {
28756
28757                 uniforms[ "tDiffuse" ].value = mpars.map;
28758                 uniforms[ "enableDiffuse" ].value = true;
28759
28760             }
28761
28762             if ( mpars.specularMap ) {
28763
28764                 uniforms[ "tSpecular" ].value = mpars.specularMap;
28765                 uniforms[ "enableSpecular" ].value = true;
28766
28767             }
28768
28769             if ( mpars.lightMap ) {
28770
28771                 uniforms[ "tAO" ].value = mpars.lightMap;
28772                 uniforms[ "enableAO" ].value = true;
28773
28774             }
28775
28776             // for the moment don't handle displacement texture
28777
28778             uniforms[ "uDiffuseColor" ].value.setHex( mpars.color );
28779             uniforms[ "uSpecularColor" ].value.setHex( mpars.specular );
28780             uniforms[ "uAmbientColor" ].value.setHex( mpars.ambient );
28781
28782             uniforms[ "uShininess" ].value = mpars.shininess;
28783
28784             if ( mpars.opacity !== undefined ) {
28785
28786                 uniforms[ "uOpacity" ].value = mpars.opacity;
28787
28788             }
28789
28790             var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
28791             var material = new THREE.ShaderMaterial( parameters );
28792
28793         } else {
28794
28795             var material = new THREE[ mtype ]( mpars );
28796
28797         }
28798
28799         if ( m.DbgName !== undefined ) material.name = m.DbgName;
28800
28801         return material;
28802
28803     }
28804
28805 };
28806 /**
28807  * @author alteredq / http://alteredqualia.com/
28808  */
28809
28810 THREE.BinaryLoader = function ( showStatus ) {
28811
28812     THREE.Loader.call( this, showStatus );
28813
28814 };
28815
28816 THREE.BinaryLoader.prototype = Object.create( THREE.Loader.prototype );
28817
28818 // Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
28819 //  - binary models consist of two files: JS and BIN
28820 //  - parameters
28821 //        - url (required)
28822 //        - callback (required)
28823 //        - texturePath (optional: if not specified, textures will be assumed to be in the same folder as JS model file)
28824 //        - binaryPath (optional: if not specified, binary file will be assumed to be in the same folder as JS model file)
28825
28826 THREE.BinaryLoader.prototype.load = function( url, callback, texturePath, binaryPath ) {
28827
28828     texturePath = texturePath ? texturePath : this.extractUrlBase( url );
28829     binaryPath = binaryPath ? binaryPath : this.extractUrlBase( url );
28830
28831     var callbackProgress = this.showProgress ? THREE.Loader.prototype.updateProgress : null;
28832
28833     this.onLoadStart();
28834
28835     // #1 load JS part via web worker
28836
28837     this.loadAjaxJSON( this, url, callback, texturePath, binaryPath, callbackProgress );
28838
28839 };
28840
28841 THREE.BinaryLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, binaryPath, callbackProgress ) {
28842
28843     var xhr = new XMLHttpRequest();
28844
28845     xhr.onreadystatechange = function () {
28846
28847         if ( xhr.readyState == 4 ) {
28848
28849             if ( xhr.status == 200 || xhr.status == 0 ) {
28850
28851                 var json = JSON.parse( xhr.responseText );
28852                 context.loadAjaxBuffers( json, callback, binaryPath, texturePath, callbackProgress );
28853
28854             } else {
28855
28856                 console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
28857
28858             }
28859
28860         }
28861
28862     };
28863
28864     xhr.open( "GET", url, true );
28865     xhr.send( null );
28866
28867 };
28868
28869 THREE.BinaryLoader.prototype.loadAjaxBuffers = function ( json, callback, binaryPath, texturePath, callbackProgress ) {
28870
28871     var xhr = new XMLHttpRequest(),
28872         url = binaryPath + "/" + json.buffers;
28873
28874     var length = 0;
28875
28876     xhr.onreadystatechange = function () {
28877
28878         if ( xhr.readyState == 4 ) {
28879
28880             if ( xhr.status == 200 || xhr.status == 0 ) {
28881
28882                 var buffer = xhr.response;
28883                 if ( buffer === undefined ) buffer = ( new Uint8Array( xhr.responseBody ) ).buffer; // IEWEBGL needs this
28884                 THREE.BinaryLoader.prototype.createBinModel( buffer, callback, texturePath, json.materials );
28885
28886             } else {
28887
28888                 console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
28889
28890             }
28891
28892         } else if ( xhr.readyState == 3 ) {
28893
28894             if ( callbackProgress ) {
28895
28896                 if ( length == 0 ) {
28897
28898                     length = xhr.getResponseHeader( "Content-Length" );
28899
28900                 }
28901
28902                 callbackProgress( { total: length, loaded: xhr.responseText.length } );
28903
28904             }
28905
28906         } else if ( xhr.readyState == 2 ) {
28907
28908             length = xhr.getResponseHeader( "Content-Length" );
28909
28910         }
28911
28912     };
28913
28914     xhr.open( "GET", url, true );
28915     xhr.responseType = "arraybuffer";
28916     xhr.send( null );
28917
28918 };
28919
28920 // Binary AJAX parser
28921
28922 THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texturePath, materials ) {
28923
28924     var Model = function ( texturePath ) {
28925
28926         var scope = this,
28927             currentOffset = 0,
28928             md,
28929             normals = [],
28930             uvs = [],
28931             start_tri_flat, start_tri_smooth, start_tri_flat_uv, start_tri_smooth_uv,
28932             start_quad_flat, start_quad_smooth, start_quad_flat_uv, start_quad_smooth_uv,
28933             tri_size, quad_size,
28934             len_tri_flat, len_tri_smooth, len_tri_flat_uv, len_tri_smooth_uv,
28935             len_quad_flat, len_quad_smooth, len_quad_flat_uv, len_quad_smooth_uv;
28936
28937
28938         THREE.Geometry.call( this );
28939
28940         THREE.Loader.prototype.initMaterials( scope, materials, texturePath );
28941
28942         md = parseMetaData( data, currentOffset );
28943
28944         currentOffset += md.header_bytes;
28945 /*
28946         md.vertex_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
28947         md.material_index_bytes = Uint16Array.BYTES_PER_ELEMENT;
28948         md.normal_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
28949         md.uv_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
28950 */
28951         // buffers sizes
28952
28953         tri_size =  md.vertex_index_bytes * 3 + md.material_index_bytes;
28954         quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes;
28955
28956         len_tri_flat      = md.ntri_flat      * ( tri_size );
28957         len_tri_smooth    = md.ntri_smooth    * ( tri_size + md.normal_index_bytes * 3 );
28958         len_tri_flat_uv   = md.ntri_flat_uv   * ( tri_size + md.uv_index_bytes * 3 );
28959         len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 );
28960
28961         len_quad_flat      = md.nquad_flat      * ( quad_size );
28962         len_quad_smooth    = md.nquad_smooth    * ( quad_size + md.normal_index_bytes * 4 );
28963         len_quad_flat_uv   = md.nquad_flat_uv   * ( quad_size + md.uv_index_bytes * 4 );
28964         len_quad_smooth_uv = md.nquad_smooth_uv * ( quad_size + md.normal_index_bytes * 4 + md.uv_index_bytes * 4 );
28965
28966         // read buffers
28967
28968         currentOffset += init_vertices( currentOffset );
28969
28970         currentOffset += init_normals( currentOffset );
28971         currentOffset += handlePadding( md.nnormals * 3 );
28972
28973         currentOffset += init_uvs( currentOffset );
28974
28975         start_tri_flat         = currentOffset;
28976         start_tri_smooth    = start_tri_flat    + len_tri_flat    + handlePadding( md.ntri_flat * 2 );
28977         start_tri_flat_uv   = start_tri_smooth  + len_tri_smooth  + handlePadding( md.ntri_smooth * 2 );
28978         start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 );
28979
28980         start_quad_flat     = start_tri_smooth_uv + len_tri_smooth_uv  + handlePadding( md.ntri_smooth_uv * 2 );
28981         start_quad_smooth   = start_quad_flat     + len_quad_flat       + handlePadding( md.nquad_flat * 2 );
28982         start_quad_flat_uv  = start_quad_smooth   + len_quad_smooth    + handlePadding( md.nquad_smooth * 2 );
28983         start_quad_smooth_uv= start_quad_flat_uv  + len_quad_flat_uv   + handlePadding( md.nquad_flat_uv * 2 );
28984
28985         // have to first process faces with uvs
28986         // so that face and uv indices match
28987
28988         init_triangles_flat_uv( start_tri_flat_uv );
28989         init_triangles_smooth_uv( start_tri_smooth_uv );
28990
28991         init_quads_flat_uv( start_quad_flat_uv );
28992         init_quads_smooth_uv( start_quad_smooth_uv );
28993
28994         // now we can process untextured faces
28995
28996         init_triangles_flat( start_tri_flat );
28997         init_triangles_smooth( start_tri_smooth );
28998
28999         init_quads_flat( start_quad_flat );
29000         init_quads_smooth( start_quad_smooth );
29001
29002         this.computeCentroids();
29003         this.computeFaceNormals();
29004
29005         if ( THREE.Loader.prototype.hasNormals( this ) ) this.computeTangents();
29006
29007         function handlePadding( n ) {
29008
29009             return ( n % 4 ) ? ( 4 - n % 4 ) : 0;
29010
29011         };
29012
29013         function parseMetaData( data, offset ) {
29014
29015             var metaData = {
29016
29017                 'signature'               :parseString( data, offset,  12 ),
29018                 'header_bytes'            :parseUChar8( data, offset + 12 ),
29019
29020                 'vertex_coordinate_bytes' :parseUChar8( data, offset + 13 ),
29021                 'normal_coordinate_bytes' :parseUChar8( data, offset + 14 ),
29022                 'uv_coordinate_bytes'     :parseUChar8( data, offset + 15 ),
29023
29024                 'vertex_index_bytes'      :parseUChar8( data, offset + 16 ),
29025                 'normal_index_bytes'      :parseUChar8( data, offset + 17 ),
29026                 'uv_index_bytes'          :parseUChar8( data, offset + 18 ),
29027                 'material_index_bytes'    :parseUChar8( data, offset + 19 ),
29028
29029                 'nvertices'    :parseUInt32( data, offset + 20 ),
29030                 'nnormals'     :parseUInt32( data, offset + 20 + 4*1 ),
29031                 'nuvs'         :parseUInt32( data, offset + 20 + 4*2 ),
29032
29033                 'ntri_flat'      :parseUInt32( data, offset + 20 + 4*3 ),
29034                 'ntri_smooth'    :parseUInt32( data, offset + 20 + 4*4 ),
29035                 'ntri_flat_uv'   :parseUInt32( data, offset + 20 + 4*5 ),
29036                 'ntri_smooth_uv' :parseUInt32( data, offset + 20 + 4*6 ),
29037
29038                 'nquad_flat'      :parseUInt32( data, offset + 20 + 4*7 ),
29039                 'nquad_smooth'    :parseUInt32( data, offset + 20 + 4*8 ),
29040                 'nquad_flat_uv'   :parseUInt32( data, offset + 20 + 4*9 ),
29041                 'nquad_smooth_uv' :parseUInt32( data, offset + 20 + 4*10 )
29042
29043             };
29044 /*
29045             console.log( "signature: " + metaData.signature );
29046
29047             console.log( "header_bytes: " + metaData.header_bytes );
29048             console.log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes );
29049             console.log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
29050             console.log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
29051
29052             console.log( "vertex_index_bytes: " + metaData.vertex_index_bytes );
29053             console.log( "normal_index_bytes: " + metaData.normal_index_bytes );
29054             console.log( "uv_index_bytes: " + metaData.uv_index_bytes );
29055             console.log( "material_index_bytes: " + metaData.material_index_bytes );
29056
29057             console.log( "nvertices: " + metaData.nvertices );
29058             console.log( "nnormals: " + metaData.nnormals );
29059             console.log( "nuvs: " + metaData.nuvs );
29060
29061             console.log( "ntri_flat: " + metaData.ntri_flat );
29062             console.log( "ntri_smooth: " + metaData.ntri_smooth );
29063             console.log( "ntri_flat_uv: " + metaData.ntri_flat_uv );
29064             console.log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv );
29065
29066             console.log( "nquad_flat: " + metaData.nquad_flat );
29067             console.log( "nquad_smooth: " + metaData.nquad_smooth );
29068             console.log( "nquad_flat_uv: " + metaData.nquad_flat_uv );
29069             console.log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv );
29070
29071             var total = metaData.header_bytes
29072                       + metaData.nvertices * metaData.vertex_coordinate_bytes * 3
29073                       + metaData.nnormals * metaData.normal_coordinate_bytes * 3
29074                       + metaData.nuvs * metaData.uv_coordinate_bytes * 2
29075                       + metaData.ntri_flat * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes )
29076                       + metaData.ntri_smooth * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 )
29077                       + metaData.ntri_flat_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.uv_index_bytes*3 )
29078                       + metaData.ntri_smooth_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 + metaData.uv_index_bytes*3 )
29079                       + metaData.nquad_flat * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes )
29080                       + metaData.nquad_smooth * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 )
29081                       + metaData.nquad_flat_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.uv_index_bytes*4 )
29082                       + metaData.nquad_smooth_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 + metaData.uv_index_bytes*4 );
29083             console.log( "total bytes: " + total );
29084 */
29085
29086             return metaData;
29087
29088         };
29089
29090         function parseString( data, offset, length ) {
29091
29092             var charArray = new Uint8Array( data, offset, length );
29093
29094             var text = "";
29095
29096             for ( var i = 0; i < length; i ++ ) {
29097
29098                 text += String.fromCharCode( charArray[ offset + i ] );
29099
29100             }
29101
29102             return text;
29103
29104         };
29105
29106         function parseUChar8( data, offset ) {
29107
29108             var charArray = new Uint8Array( data, offset, 1 );
29109
29110             return charArray[ 0 ];
29111
29112         };
29113
29114         function parseUInt32( data, offset ) {
29115
29116             var intArray = new Uint32Array( data, offset, 1 );
29117
29118             return intArray[ 0 ];
29119
29120         };
29121
29122         function init_vertices( start ) {
29123
29124             var nElements = md.nvertices;
29125
29126             var coordArray = new Float32Array( data, start, nElements * 3 );
29127
29128             var i, x, y, z;
29129
29130             for( i = 0; i < nElements; i ++ ) {
29131
29132                 x = coordArray[ i * 3 ];
29133                 y = coordArray[ i * 3 + 1 ];
29134                 z = coordArray[ i * 3 + 2 ];
29135
29136                 vertex( scope, x, y, z );
29137
29138             }
29139
29140             return nElements * 3 * Float32Array.BYTES_PER_ELEMENT;
29141
29142         };
29143
29144         function init_normals( start ) {
29145
29146             var nElements = md.nnormals;
29147
29148             if ( nElements ) {
29149
29150                 var normalArray = new Int8Array( data, start, nElements * 3 );
29151
29152                 var i, x, y, z;
29153
29154                 for( i = 0; i < nElements; i ++ ) {
29155
29156                     x = normalArray[ i * 3 ];
29157                     y = normalArray[ i * 3 + 1 ];
29158                     z = normalArray[ i * 3 + 2 ];
29159
29160                     normals.push( x/127, y/127, z/127 );
29161
29162                 }
29163
29164             }
29165
29166             return nElements * 3 * Int8Array.BYTES_PER_ELEMENT;
29167
29168         };
29169
29170         function init_uvs( start ) {
29171
29172             var nElements = md.nuvs;
29173
29174             if ( nElements ) {
29175
29176                 var uvArray = new Float32Array( data, start, nElements * 2 );
29177
29178                 var i, u, v;
29179
29180                 for( i = 0; i < nElements; i ++ ) {
29181
29182                     u = uvArray[ i * 2 ];
29183                     v = uvArray[ i * 2 + 1 ];
29184
29185                     uvs.push( u, v );
29186
29187                 }
29188
29189             }
29190
29191             return nElements * 2 * Float32Array.BYTES_PER_ELEMENT;
29192
29193         };
29194
29195         function init_uvs3( nElements, offset ) {
29196
29197             var i, uva, uvb, uvc, u1, u2, u3, v1, v2, v3;
29198
29199             var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements );
29200
29201             for( i = 0; i < nElements; i ++ ) {
29202
29203                 uva = uvIndexBuffer[ i * 3 ];
29204                 uvb = uvIndexBuffer[ i * 3 + 1 ];
29205                 uvc = uvIndexBuffer[ i * 3 + 2 ];
29206
29207                 u1 = uvs[ uva*2 ];
29208                 v1 = uvs[ uva*2 + 1 ];
29209
29210                 u2 = uvs[ uvb*2 ];
29211                 v2 = uvs[ uvb*2 + 1 ];
29212
29213                 u3 = uvs[ uvc*2 ];
29214                 v3 = uvs[ uvc*2 + 1 ];
29215
29216                 uv3( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3 );
29217
29218             }
29219
29220         };
29221
29222         function init_uvs4( nElements, offset ) {
29223
29224             var i, uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4;
29225
29226             var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements );
29227
29228             for( i = 0; i < nElements; i ++ ) {
29229
29230                 uva = uvIndexBuffer[ i * 4 ];
29231                 uvb = uvIndexBuffer[ i * 4 + 1 ];
29232                 uvc = uvIndexBuffer[ i * 4 + 2 ];
29233                 uvd = uvIndexBuffer[ i * 4 + 3 ];
29234
29235                 u1 = uvs[ uva*2 ];
29236                 v1 = uvs[ uva*2 + 1 ];
29237
29238                 u2 = uvs[ uvb*2 ];
29239                 v2 = uvs[ uvb*2 + 1 ];
29240
29241                 u3 = uvs[ uvc*2 ];
29242                 v3 = uvs[ uvc*2 + 1 ];
29243
29244                 u4 = uvs[ uvd*2 ];
29245                 v4 = uvs[ uvd*2 + 1 ];
29246
29247                 uv4( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3, u4, v4 );
29248
29249             }
29250
29251         };
29252
29253         function init_faces3_flat( nElements, offsetVertices, offsetMaterials ) {
29254
29255             var i, a, b, c, m;
29256
29257             var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
29258             var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
29259
29260             for( i = 0; i < nElements; i ++ ) {
29261
29262                 a = vertexIndexBuffer[ i * 3 ];
29263                 b = vertexIndexBuffer[ i * 3 + 1 ];
29264                 c = vertexIndexBuffer[ i * 3 + 2 ];
29265
29266                 m = materialIndexBuffer[ i ];
29267
29268                 f3( scope, a, b, c, m );
29269
29270             }
29271
29272         };
29273
29274         function init_faces4_flat( nElements, offsetVertices, offsetMaterials ) {
29275
29276             var i, a, b, c, d, m;
29277
29278             var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
29279             var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
29280
29281             for( i = 0; i < nElements; i ++ ) {
29282
29283                 a = vertexIndexBuffer[ i * 4 ];
29284                 b = vertexIndexBuffer[ i * 4 + 1 ];
29285                 c = vertexIndexBuffer[ i * 4 + 2 ];
29286                 d = vertexIndexBuffer[ i * 4 + 3 ];
29287
29288                 m = materialIndexBuffer[ i ];
29289
29290                 f4( scope, a, b, c, d, m );
29291
29292             }
29293
29294         };
29295
29296         function init_faces3_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
29297
29298             var i, a, b, c, m;
29299             var na, nb, nc;
29300
29301             var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
29302             var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements );
29303             var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
29304
29305             for( i = 0; i < nElements; i ++ ) {
29306
29307                 a = vertexIndexBuffer[ i * 3 ];
29308                 b = vertexIndexBuffer[ i * 3 + 1 ];
29309                 c = vertexIndexBuffer[ i * 3 + 2 ];
29310
29311                 na = normalIndexBuffer[ i * 3 ];
29312                 nb = normalIndexBuffer[ i * 3 + 1 ];
29313                 nc = normalIndexBuffer[ i * 3 + 2 ];
29314
29315                 m = materialIndexBuffer[ i ];
29316
29317                 f3n( scope, normals, a, b, c, m, na, nb, nc );
29318
29319             }
29320
29321         };
29322
29323         function init_faces4_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
29324
29325             var i, a, b, c, d, m;
29326             var na, nb, nc, nd;
29327
29328             var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
29329             var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements );
29330             var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
29331
29332             for( i = 0; i < nElements; i ++ ) {
29333
29334                 a = vertexIndexBuffer[ i * 4 ];
29335                 b = vertexIndexBuffer[ i * 4 + 1 ];
29336                 c = vertexIndexBuffer[ i * 4 + 2 ];
29337                 d = vertexIndexBuffer[ i * 4 + 3 ];
29338
29339                 na = normalIndexBuffer[ i * 4 ];
29340                 nb = normalIndexBuffer[ i * 4 + 1 ];
29341                 nc = normalIndexBuffer[ i * 4 + 2 ];
29342                 nd = normalIndexBuffer[ i * 4 + 3 ];
29343
29344                 m = materialIndexBuffer[ i ];
29345
29346                 f4n( scope, normals, a, b, c, d, m, na, nb, nc, nd );
29347
29348             }
29349
29350         };
29351
29352         function init_triangles_flat( start ) {
29353
29354             var nElements = md.ntri_flat;
29355
29356             if ( nElements ) {
29357
29358                 var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29359                 init_faces3_flat( nElements, start, offsetMaterials );
29360
29361             }
29362
29363         };
29364
29365         function init_triangles_flat_uv( start ) {
29366
29367             var nElements = md.ntri_flat_uv;
29368
29369             if ( nElements ) {
29370
29371                 var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29372                 var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29373
29374                 init_faces3_flat( nElements, start, offsetMaterials );
29375                 init_uvs3( nElements, offsetUvs );
29376
29377             }
29378
29379         };
29380
29381         function init_triangles_smooth( start ) {
29382
29383             var nElements = md.ntri_smooth;
29384
29385             if ( nElements ) {
29386
29387                 var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29388                 var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29389
29390                 init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
29391
29392             }
29393
29394         };
29395
29396         function init_triangles_smooth_uv( start ) {
29397
29398             var nElements = md.ntri_smooth_uv;
29399
29400             if ( nElements ) {
29401
29402                 var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29403                 var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29404                 var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29405
29406                 init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
29407                 init_uvs3( nElements, offsetUvs );
29408
29409             }
29410
29411         };
29412
29413         function init_quads_flat( start ) {
29414
29415             var nElements = md.nquad_flat;
29416
29417             if ( nElements ) {
29418
29419                 var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29420                 init_faces4_flat( nElements, start, offsetMaterials );
29421
29422             }
29423
29424         };
29425
29426         function init_quads_flat_uv( start ) {
29427
29428             var nElements = md.nquad_flat_uv;
29429
29430             if ( nElements ) {
29431
29432                 var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29433                 var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29434
29435                 init_faces4_flat( nElements, start, offsetMaterials );
29436                 init_uvs4( nElements, offsetUvs );
29437
29438             }
29439
29440         };
29441
29442         function init_quads_smooth( start ) {
29443
29444             var nElements = md.nquad_smooth;
29445
29446             if ( nElements ) {
29447
29448                 var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29449                 var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29450
29451                 init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
29452
29453             }
29454
29455         };
29456
29457         function init_quads_smooth_uv( start ) {
29458
29459             var nElements = md.nquad_smooth_uv;
29460
29461             if ( nElements ) {
29462
29463                 var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29464                 var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29465                 var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29466
29467                 init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
29468                 init_uvs4( nElements, offsetUvs );
29469
29470             }
29471
29472         };
29473
29474     };
29475
29476     function vertex ( scope, x, y, z ) {
29477
29478         scope.vertices.push( new THREE.Vector3( x, y, z ) );
29479
29480     };
29481
29482     function f3 ( scope, a, b, c, mi ) {
29483
29484         scope.faces.push( new THREE.Face3( a, b, c, null, null, mi ) );
29485
29486     };
29487
29488     function f4 ( scope, a, b, c, d, mi ) {
29489
29490         scope.faces.push( new THREE.Face4( a, b, c, d, null, null, mi ) );
29491
29492     };
29493
29494     function f3n ( scope, normals, a, b, c, mi, na, nb, nc ) {
29495
29496         var nax = normals[ na*3     ],
29497             nay = normals[ na*3 + 1 ],
29498             naz = normals[ na*3 + 2 ],
29499
29500             nbx = normals[ nb*3     ],
29501             nby = normals[ nb*3 + 1 ],
29502             nbz = normals[ nb*3 + 2 ],
29503
29504             ncx = normals[ nc*3     ],
29505             ncy = normals[ nc*3 + 1 ],
29506             ncz = normals[ nc*3 + 2 ];
29507
29508         scope.faces.push( new THREE.Face3( a, b, c,
29509                           [new THREE.Vector3( nax, nay, naz ),
29510                            new THREE.Vector3( nbx, nby, nbz ),
29511                            new THREE.Vector3( ncx, ncy, ncz )],
29512                           null,
29513                           mi ) );
29514
29515     };
29516
29517     function f4n ( scope, normals, a, b, c, d, mi, na, nb, nc, nd ) {
29518
29519         var nax = normals[ na*3     ],
29520             nay = normals[ na*3 + 1 ],
29521             naz = normals[ na*3 + 2 ],
29522
29523             nbx = normals[ nb*3     ],
29524             nby = normals[ nb*3 + 1 ],
29525             nbz = normals[ nb*3 + 2 ],
29526
29527             ncx = normals[ nc*3     ],
29528             ncy = normals[ nc*3 + 1 ],
29529             ncz = normals[ nc*3 + 2 ],
29530
29531             ndx = normals[ nd*3     ],
29532             ndy = normals[ nd*3 + 1 ],
29533             ndz = normals[ nd*3 + 2 ];
29534
29535         scope.faces.push( new THREE.Face4( a, b, c, d,
29536                           [new THREE.Vector3( nax, nay, naz ),
29537                            new THREE.Vector3( nbx, nby, nbz ),
29538                            new THREE.Vector3( ncx, ncy, ncz ),
29539                            new THREE.Vector3( ndx, ndy, ndz )],
29540                           null,
29541                           mi ) );
29542
29543     };
29544
29545     function uv3 ( where, u1, v1, u2, v2, u3, v3 ) {
29546
29547         var uv = [];
29548         uv.push( new THREE.UV( u1, v1 ) );
29549         uv.push( new THREE.UV( u2, v2 ) );
29550         uv.push( new THREE.UV( u3, v3 ) );
29551         where.push( uv );
29552
29553     };
29554
29555     function uv4 ( where, u1, v1, u2, v2, u3, v3, u4, v4 ) {
29556
29557         var uv = [];
29558         uv.push( new THREE.UV( u1, v1 ) );
29559         uv.push( new THREE.UV( u2, v2 ) );
29560         uv.push( new THREE.UV( u3, v3 ) );
29561         uv.push( new THREE.UV( u4, v4 ) );
29562         where.push( uv );
29563
29564     };
29565
29566     Model.prototype = Object.create( THREE.Geometry.prototype );
29567
29568     callback( new Model( texturePath ) );
29569
29570 };
29571 /**
29572  * @author mrdoob / http://mrdoob.com/
29573  */
29574
29575 THREE.ImageLoader = function () {
29576
29577     THREE.EventTarget.call( this );
29578
29579     this.crossOrigin = null;
29580
29581 };
29582
29583 THREE.ImageLoader.prototype = {
29584
29585     constructor: THREE.ImageLoader,
29586
29587     load: function ( url, image ) {
29588
29589         var scope = this;
29590
29591         if ( image === undefined ) image = new Image();
29592
29593         image.addEventListener( 'load', function () {
29594
29595             scope.dispatchEvent( { type: 'load', content: image } );
29596
29597         }, false );
29598
29599         image.addEventListener( 'error', function () {
29600
29601             scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
29602
29603         }, false );
29604
29605         if ( scope.crossOrigin ) image.crossOrigin = scope.crossOrigin;
29606
29607         image.src = url;
29608
29609     }
29610
29611 }
29612 /**
29613  * @author mrdoob / http://mrdoob.com/
29614  * @author alteredq / http://alteredqualia.com/
29615  */
29616
29617 THREE.JSONLoader = function ( showStatus ) {
29618
29619     THREE.Loader.call( this, showStatus );
29620
29621 };
29622
29623 THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype );
29624
29625 THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) {
29626
29627     var scope = this;
29628
29629     texturePath = texturePath ? texturePath : this.extractUrlBase( url );
29630
29631     this.onLoadStart();
29632     this.loadAjaxJSON( this, url, callback, texturePath );
29633
29634 };
29635
29636 THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, callbackProgress ) {
29637
29638     var xhr = new XMLHttpRequest();
29639
29640     var length = 0;
29641
29642     xhr.onreadystatechange = function () {
29643
29644         if ( xhr.readyState === xhr.DONE ) {
29645
29646             if ( xhr.status === 200 || xhr.status === 0 ) {
29647
29648                 if ( xhr.responseText ) {
29649
29650                     var json = JSON.parse( xhr.responseText );
29651                     context.createModel( json, callback, texturePath );
29652
29653                 } else {
29654
29655                     console.warn( "THREE.JSONLoader: [" + url + "] seems to be unreachable or file there is empty" );
29656
29657                 }
29658
29659                 // in context of more complex asset initialization
29660                 // do not block on single failed file
29661                 // maybe should go even one more level up
29662
29663                 context.onLoadComplete();
29664
29665             } else {
29666
29667                 console.error( "THREE.JSONLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
29668
29669             }
29670
29671         } else if ( xhr.readyState === xhr.LOADING ) {
29672
29673             if ( callbackProgress ) {
29674
29675                 if ( length === 0 ) {
29676
29677                     length = xhr.getResponseHeader( "Content-Length" );
29678
29679                 }
29680
29681                 callbackProgress( { total: length, loaded: xhr.responseText.length } );
29682
29683             }
29684
29685         } else if ( xhr.readyState === xhr.HEADERS_RECEIVED ) {
29686
29687             length = xhr.getResponseHeader( "Content-Length" );
29688
29689         }
29690
29691     };
29692
29693     xhr.open( "GET", url, true );
29694     xhr.send( null );
29695
29696 };
29697
29698 THREE.JSONLoader.prototype.createModel = function ( json, callback, texturePath ) {
29699
29700     var scope = this,
29701     geometry = new THREE.Geometry(),
29702     scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
29703
29704     this.initMaterials( geometry, json.materials, texturePath );
29705
29706     parseModel( scale );
29707
29708     parseSkin();
29709     parseMorphing( scale );
29710
29711     geometry.computeCentroids();
29712     geometry.computeFaceNormals();
29713
29714     if ( this.hasNormals( geometry ) ) geometry.computeTangents();
29715
29716
29717     function parseModel( scale ) {
29718
29719         function isBitSet( value, position ) {
29720
29721             return value & ( 1 << position );
29722
29723         }
29724
29725         var i, j, fi,
29726
29727         offset, zLength, nVertices,
29728
29729         colorIndex, normalIndex, uvIndex, materialIndex,
29730
29731         type,
29732         isQuad,
29733         hasMaterial,
29734         hasFaceUv, hasFaceVertexUv,
29735         hasFaceNormal, hasFaceVertexNormal,
29736         hasFaceColor, hasFaceVertexColor,
29737
29738         vertex, face, color, normal,
29739
29740         uvLayer, uvs, u, v,
29741
29742         faces = json.faces,
29743         vertices = json.vertices,
29744         normals = json.normals,
29745         colors = json.colors,
29746
29747         nUvLayers = 0;
29748
29749         // disregard empty arrays
29750
29751         for ( i = 0; i < json.uvs.length; i++ ) {
29752
29753             if ( json.uvs[ i ].length ) nUvLayers ++;
29754
29755         }
29756
29757         for ( i = 0; i < nUvLayers; i++ ) {
29758
29759             geometry.faceUvs[ i ] = [];
29760             geometry.faceVertexUvs[ i ] = [];
29761
29762         }
29763
29764         offset = 0;
29765         zLength = vertices.length;
29766
29767         while ( offset < zLength ) {
29768
29769             vertex = new THREE.Vector3();
29770
29771             vertex.x = vertices[ offset ++ ] * scale;
29772             vertex.y = vertices[ offset ++ ] * scale;
29773             vertex.z = vertices[ offset ++ ] * scale;
29774
29775             geometry.vertices.push( vertex );
29776
29777         }
29778
29779         offset = 0;
29780         zLength = faces.length;
29781
29782         while ( offset < zLength ) {
29783
29784             type = faces[ offset ++ ];
29785
29786
29787             isQuad              = isBitSet( type, 0 );
29788             hasMaterial         = isBitSet( type, 1 );
29789             hasFaceUv           = isBitSet( type, 2 );
29790             hasFaceVertexUv     = isBitSet( type, 3 );
29791             hasFaceNormal       = isBitSet( type, 4 );
29792             hasFaceVertexNormal = isBitSet( type, 5 );
29793             hasFaceColor        = isBitSet( type, 6 );
29794             hasFaceVertexColor  = isBitSet( type, 7 );
29795
29796             //console.log("type", type, "bits", isQuad, hasMaterial, hasFaceUv, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
29797
29798             if ( isQuad ) {
29799
29800                 face = new THREE.Face4();
29801
29802                 face.a = faces[ offset ++ ];
29803                 face.b = faces[ offset ++ ];
29804                 face.c = faces[ offset ++ ];
29805                 face.d = faces[ offset ++ ];
29806
29807                 nVertices = 4;
29808
29809             } else {
29810
29811                 face = new THREE.Face3();
29812
29813                 face.a = faces[ offset ++ ];
29814                 face.b = faces[ offset ++ ];
29815                 face.c = faces[ offset ++ ];
29816
29817                 nVertices = 3;
29818
29819             }
29820
29821             if ( hasMaterial ) {
29822
29823                 materialIndex = faces[ offset ++ ];
29824                 face.materialIndex = materialIndex;
29825
29826             }
29827
29828             // to get face <=> uv index correspondence
29829
29830             fi = geometry.faces.length;
29831
29832             if ( hasFaceUv ) {
29833
29834                 for ( i = 0; i < nUvLayers; i++ ) {
29835
29836                     uvLayer = json.uvs[ i ];
29837
29838                     uvIndex = faces[ offset ++ ];
29839
29840                     u = uvLayer[ uvIndex * 2 ];
29841                     v = uvLayer[ uvIndex * 2 + 1 ];
29842
29843                     geometry.faceUvs[ i ][ fi ] = new THREE.UV( u, v );
29844
29845                 }
29846
29847             }
29848
29849             if ( hasFaceVertexUv ) {
29850
29851                 for ( i = 0; i < nUvLayers; i++ ) {
29852
29853                     uvLayer = json.uvs[ i ];
29854
29855                     uvs = [];
29856
29857                     for ( j = 0; j < nVertices; j ++ ) {
29858
29859                         uvIndex = faces[ offset ++ ];
29860
29861                         u = uvLayer[ uvIndex * 2 ];
29862                         v = uvLayer[ uvIndex * 2 + 1 ];
29863
29864                         uvs[ j ] = new THREE.UV( u, v );
29865
29866                     }
29867
29868                     geometry.faceVertexUvs[ i ][ fi ] = uvs;
29869
29870                 }
29871
29872             }
29873
29874             if ( hasFaceNormal ) {
29875
29876                 normalIndex = faces[ offset ++ ] * 3;
29877
29878                 normal = new THREE.Vector3();
29879
29880                 normal.x = normals[ normalIndex ++ ];
29881                 normal.y = normals[ normalIndex ++ ];
29882                 normal.z = normals[ normalIndex ];
29883
29884                 face.normal = normal;
29885
29886             }
29887
29888             if ( hasFaceVertexNormal ) {
29889
29890                 for ( i = 0; i < nVertices; i++ ) {
29891
29892                     normalIndex = faces[ offset ++ ] * 3;
29893
29894                     normal = new THREE.Vector3();
29895
29896                     normal.x = normals[ normalIndex ++ ];
29897                     normal.y = normals[ normalIndex ++ ];
29898                     normal.z = normals[ normalIndex ];
29899
29900                     face.vertexNormals.push( normal );
29901
29902                 }
29903
29904             }
29905
29906
29907             if ( hasFaceColor ) {
29908
29909                 colorIndex = faces[ offset ++ ];
29910
29911                 color = new THREE.Color( colors[ colorIndex ] );
29912                 face.color = color;
29913
29914             }
29915
29916
29917             if ( hasFaceVertexColor ) {
29918
29919                 for ( i = 0; i < nVertices; i++ ) {
29920
29921                     colorIndex = faces[ offset ++ ];
29922
29923                     color = new THREE.Color( colors[ colorIndex ] );
29924                     face.vertexColors.push( color );
29925
29926                 }
29927
29928             }
29929
29930             geometry.faces.push( face );
29931
29932         }
29933
29934     };
29935
29936     function parseSkin() {
29937
29938         var i, l, x, y, z, w, a, b, c, d;
29939
29940         if ( json.skinWeights ) {
29941
29942             for ( i = 0, l = json.skinWeights.length; i < l; i += 2 ) {
29943
29944                 x = json.skinWeights[ i     ];
29945                 y = json.skinWeights[ i + 1 ];
29946                 z = 0;
29947                 w = 0;
29948
29949                 geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
29950
29951             }
29952
29953         }
29954
29955         if ( json.skinIndices ) {
29956
29957             for ( i = 0, l = json.skinIndices.length; i < l; i += 2 ) {
29958
29959                 a = json.skinIndices[ i     ];
29960                 b = json.skinIndices[ i + 1 ];
29961                 c = 0;
29962                 d = 0;
29963
29964                 geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
29965
29966             }
29967
29968         }
29969
29970         geometry.bones = json.bones;
29971         geometry.animation = json.animation;
29972
29973     };
29974
29975     function parseMorphing( scale ) {
29976
29977         if ( json.morphTargets !== undefined ) {
29978
29979             var i, l, v, vl, dstVertices, srcVertices;
29980
29981             for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {
29982
29983                 geometry.morphTargets[ i ] = {};
29984                 geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
29985                 geometry.morphTargets[ i ].vertices = [];
29986
29987                 dstVertices = geometry.morphTargets[ i ].vertices;
29988                 srcVertices = json.morphTargets [ i ].vertices;
29989
29990                 for( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
29991
29992                     var vertex = new THREE.Vector3();
29993                     vertex.x = srcVertices[ v ] * scale;
29994                     vertex.y = srcVertices[ v + 1 ] * scale;
29995                     vertex.z = srcVertices[ v + 2 ] * scale;
29996
29997                     dstVertices.push( vertex );
29998
29999                 }
30000
30001             }
30002
30003         }
30004
30005         if ( json.morphColors !== undefined ) {
30006
30007             var i, l, c, cl, dstColors, srcColors, color;
30008
30009             for ( i = 0, l = json.morphColors.length; i < l; i++ ) {
30010
30011                 geometry.morphColors[ i ] = {};
30012                 geometry.morphColors[ i ].name = json.morphColors[ i ].name;
30013                 geometry.morphColors[ i ].colors = [];
30014
30015                 dstColors = geometry.morphColors[ i ].colors;
30016                 srcColors = json.morphColors [ i ].colors;
30017
30018                 for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {
30019
30020                     color = new THREE.Color( 0xffaa00 );
30021                     color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
30022                     dstColors.push( color );
30023
30024                 }
30025
30026             }
30027
30028         }
30029
30030     };
30031
30032     callback( geometry );
30033
30034 };
30035 /**
30036  * @author mrdoob / http://mrdoob.com/
30037  */
30038
30039 THREE.LoadingMonitor = function () {
30040
30041     THREE.EventTarget.call( this );
30042
30043     var scope = this;
30044
30045     var loaded = 0;
30046     var total = 0;
30047
30048     var onLoad = function ( event ) {
30049
30050         loaded ++;
30051
30052         scope.dispatchEvent( { type: 'progress', loaded: loaded, total: total } );
30053
30054         if ( loaded === total ) {
30055
30056             scope.dispatchEvent( { type: 'load' } );
30057
30058         }
30059
30060     };
30061
30062     this.add = function ( loader ) {
30063
30064         total ++;
30065
30066         loader.addEventListener( 'load', onLoad, false );
30067
30068     };
30069
30070 };
30071 /**
30072  * @author mrdoob / http://mrdoob.com/
30073  * @author alteredq / http://alteredqualia.com/
30074  */
30075
30076 THREE.GeometryLoader = function () {
30077
30078     THREE.EventTarget.call( this );
30079
30080     this.crossOrigin = null;
30081     this.path = null;
30082
30083
30084 };
30085
30086 THREE.GeometryLoader.prototype = {
30087
30088     constructor: THREE.GeometryLoader,
30089
30090     load: function ( url ) {
30091
30092         var scope = this;
30093         var geometry = null;
30094
30095         if ( scope.path === null ) {
30096
30097             var parts = url.split( '/' ); parts.pop();
30098             scope.path = ( parts.length < 1 ? '.' : parts.join( '/' ) );
30099
30100         }
30101
30102         //
30103
30104         var xhr = new XMLHttpRequest();
30105
30106         xhr.addEventListener( 'load', function ( event ) {
30107
30108             if ( event.target.responseText ) {
30109
30110                 geometry = scope.parse( JSON.parse( event.target.responseText ), monitor );
30111
30112             } else {
30113
30114                 scope.dispatchEvent( { type: 'error', message: 'Invalid file [' + url + ']' } );
30115
30116             }
30117
30118         }, false );
30119
30120         xhr.addEventListener( 'error', function () {
30121
30122             scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
30123
30124         }, false );
30125
30126         xhr.open( 'GET', url, true );
30127         xhr.send( null );
30128
30129         //
30130
30131         var monitor = new THREE.LoadingMonitor();
30132
30133         monitor.addEventListener( 'load', function ( event ) {
30134
30135             scope.dispatchEvent( { type: 'load', content: geometry } );
30136
30137         } );
30138
30139         monitor.add( xhr );
30140
30141     },
30142
30143     parse: function ( data, monitor ) {
30144
30145         var scope = this;
30146         var geometry = new THREE.Geometry();
30147
30148         var scale = ( data.scale !== undefined ) ? 1 / data.scale : 1;
30149
30150         // materials
30151
30152         if ( data.materials ) {
30153
30154             geometry.materials = [];
30155
30156             for ( var i = 0; i < data.materials.length; ++ i ) {
30157
30158                 var m = data.materials[ i ];
30159
30160                 function isPow2( n ) {
30161
30162                     var l = Math.log( n ) / Math.LN2;
30163                     return Math.floor( l ) == l;
30164
30165                 }
30166
30167                 function nearestPow2( n ) {
30168
30169                     var l = Math.log( n ) / Math.LN2;
30170                     return Math.pow( 2, Math.round(  l ) );
30171
30172                 }
30173
30174                 function createTexture( where, name, sourceFile, repeat, offset, wrap ) {
30175
30176                     where[ name ] = new THREE.Texture();
30177                     where[ name ].sourceFile = sourceFile;
30178
30179                     if ( repeat ) {
30180
30181                         where[ name ].repeat.set( repeat[ 0 ], repeat[ 1 ] );
30182
30183                         if ( repeat[ 0 ] !== 1 ) where[ name ].wrapS = THREE.RepeatWrapping;
30184                         if ( repeat[ 1 ] !== 1 ) where[ name ].wrapT = THREE.RepeatWrapping;
30185
30186                     }
30187
30188                     if ( offset ) {
30189
30190                         where[ name ].offset.set( offset[ 0 ], offset[ 1 ] );
30191
30192                     }
30193
30194                     if ( wrap ) {
30195
30196                         var wrapMap = {
30197
30198                             "repeat": THREE.RepeatWrapping,
30199                             "mirror": THREE.MirroredRepeatWrapping
30200
30201                         }
30202
30203                         if ( wrapMap[ wrap[ 0 ] ] !== undefined ) where[ name ].wrapS = wrapMap[ wrap[ 0 ] ];
30204                         if ( wrapMap[ wrap[ 1 ] ] !== undefined ) where[ name ].wrapT = wrapMap[ wrap[ 1 ] ];
30205
30206                     }
30207
30208                     // load image
30209
30210                     var texture = where[ name ];
30211
30212                     var loader = new THREE.ImageLoader();
30213                     loader.addEventListener( 'load', function ( event ) {
30214
30215                         var image = event.content;
30216
30217                         if ( !isPow2( image.width ) || !isPow2( image.height ) ) {
30218
30219                             var width = nearestPow2( image.width );
30220                             var height = nearestPow2( image.height );
30221
30222                             texture.image = document.createElement( 'canvas' );
30223                             texture.image.width = width;
30224                             texture.image.height = height;
30225                             texture.image.getContext( '2d' ).drawImage( image, 0, 0, width, height );
30226
30227                         } else {
30228
30229                             texture.image = image;
30230
30231                         }
30232
30233                         texture.needsUpdate = true;
30234
30235                     } );
30236                     loader.crossOrigin = scope.crossOrigin;
30237                     loader.load( scope.path + '/' + sourceFile );
30238
30239                     if ( monitor ) monitor.add( loader );
30240
30241                 }
30242
30243                 function rgb2hex( rgb ) {
30244
30245                     return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255;
30246
30247                 }
30248
30249                 // defaults
30250
30251                 var mtype = "MeshLambertMaterial";
30252                 var mpars = { color: 0xeeeeee, opacity: 1.0, map: null, lightMap: null, normalMap: null, bumpMap: null, wireframe: false };
30253
30254                 // parameters from model file
30255
30256                 if ( m.shading ) {
30257
30258                     var shading = m.shading.toLowerCase();
30259
30260                     if ( shading === "phong" ) mtype = "MeshPhongMaterial";
30261                     else if ( shading === "basic" ) mtype = "MeshBasicMaterial";
30262
30263                 }
30264
30265                 if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) {
30266
30267                     mpars.blending = THREE[ m.blending ];
30268
30269                 }
30270
30271                 if ( m.transparent !== undefined || m.opacity < 1.0 ) {
30272
30273                     mpars.transparent = m.transparent;
30274
30275                 }
30276
30277                 if ( m.depthTest !== undefined ) {
30278
30279                     mpars.depthTest = m.depthTest;
30280
30281                 }
30282
30283                 if ( m.depthWrite !== undefined ) {
30284
30285                     mpars.depthWrite = m.depthWrite;
30286
30287                 }
30288
30289                 if ( m.vertexColors !== undefined ) {
30290
30291                     if ( m.vertexColors == "face" ) {
30292
30293                         mpars.vertexColors = THREE.FaceColors;
30294
30295                     } else if ( m.vertexColors ) {
30296
30297                         mpars.vertexColors = THREE.VertexColors;
30298
30299                     }
30300
30301                 }
30302
30303                 // colors
30304
30305                 if ( m.colorDiffuse ) {
30306
30307                     mpars.color = rgb2hex( m.colorDiffuse );
30308
30309                 } else if ( m.DbgColor ) {
30310
30311                     mpars.color = m.DbgColor;
30312
30313                 }
30314
30315                 if ( m.colorSpecular ) {
30316
30317                     mpars.specular = rgb2hex( m.colorSpecular );
30318
30319                 }
30320
30321                 if ( m.colorAmbient ) {
30322
30323                     mpars.ambient = rgb2hex( m.colorAmbient );
30324
30325                 }
30326
30327                 // modifiers
30328
30329                 if ( m.transparency ) {
30330
30331                     mpars.opacity = m.transparency;
30332
30333                 }
30334
30335                 if ( m.specularCoef ) {
30336
30337                     mpars.shininess = m.specularCoef;
30338
30339                 }
30340
30341                 if ( m.visible !== undefined ) {
30342
30343                     mpars.visible = m.visible;
30344
30345                 }
30346
30347                 if ( m.flipSided !== undefined ) {
30348
30349                     mpars.side = THREE.BackSide;
30350
30351                 }
30352
30353                 if ( m.doubleSided !== undefined ) {
30354
30355                     mpars.side = THREE.DoubleSide;
30356
30357                 }
30358
30359                 if ( m.wireframe !== undefined ) {
30360
30361                     mpars.wireframe = m.wireframe;
30362
30363                 }
30364
30365                 // textures
30366
30367                 if ( m.mapDiffuse ) {
30368
30369                     createTexture( mpars, "map", m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap );
30370
30371                 }
30372
30373                 if ( m.mapLight ) {
30374
30375                     createTexture( mpars, "lightMap", m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap );
30376
30377                 }
30378
30379                 if ( m.mapBump ) {
30380
30381                     createTexture( mpars, "bumpMap", m.mapBump, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap );
30382
30383                 }
30384
30385                 if ( m.mapNormal ) {
30386
30387                     createTexture( mpars, "normalMap", m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap );
30388
30389                 }
30390
30391                 if ( m.mapSpecular ) {
30392
30393                     createTexture( mpars, "specularMap", m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap );
30394
30395                 }
30396
30397                 // special case for normal mapped material
30398
30399                 if ( m.mapNormal ) {
30400
30401                     var shader = THREE.ShaderUtils.lib[ "normal" ];
30402                     var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
30403
30404                     uniforms[ "tNormal" ].value = mpars.normalMap;
30405
30406                     if ( m.mapNormalFactor ) {
30407
30408                         uniforms[ "uNormalScale" ].value.set( m.mapNormalFactor, m.mapNormalFactor );
30409
30410                     }
30411
30412                     if ( mpars.map ) {
30413
30414                         uniforms[ "tDiffuse" ].value = mpars.map;
30415                         uniforms[ "enableDiffuse" ].value = true;
30416
30417                     }
30418
30419                     if ( mpars.specularMap ) {
30420
30421                         uniforms[ "tSpecular" ].value = mpars.specularMap;
30422                         uniforms[ "enableSpecular" ].value = true;
30423
30424                     }
30425
30426                     if ( mpars.lightMap ) {
30427
30428                         uniforms[ "tAO" ].value = mpars.lightMap;
30429                         uniforms[ "enableAO" ].value = true;
30430
30431                     }
30432
30433                     // for the moment don't handle displacement texture
30434
30435                     uniforms[ "uDiffuseColor" ].value.setHex( mpars.color );
30436                     uniforms[ "uSpecularColor" ].value.setHex( mpars.specular );
30437                     uniforms[ "uAmbientColor" ].value.setHex( mpars.ambient );
30438
30439                     uniforms[ "uShininess" ].value = mpars.shininess;
30440
30441                     if ( mpars.opacity !== undefined ) {
30442
30443                         uniforms[ "uOpacity" ].value = mpars.opacity;
30444
30445                     }
30446
30447                     var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
30448                     var material = new THREE.ShaderMaterial( parameters );
30449
30450                 } else {
30451
30452                     var material = new THREE[ mtype ]( mpars );
30453
30454                 }
30455
30456                 if ( m.DbgName !== undefined ) material.name = m.DbgName;
30457
30458                 geometry.materials[ i ] = material;
30459
30460             }
30461
30462         }
30463
30464         // geometry
30465
30466         function isBitSet( value, position ) {
30467
30468             return value & ( 1 << position );
30469
30470         }
30471
30472         var faces = data.faces;
30473         var vertices = data.vertices;
30474         var normals = data.normals;
30475         var colors = data.colors;
30476         var nUvLayers = 0;
30477
30478         // disregard empty arrays
30479
30480         if ( data.uvs ) {
30481
30482             for ( var i = 0; i < data.uvs.length; i ++ ) {
30483
30484                 if ( data.uvs[ i ].length ) nUvLayers ++;
30485
30486             }
30487
30488         }
30489
30490         for ( var i = 0; i < nUvLayers; i ++ ) {
30491
30492             geometry.faceUvs[ i ] = [];
30493             geometry.faceVertexUvs[ i ] = [];
30494
30495         }
30496
30497         var offset = 0;
30498         var zLength = vertices.length;
30499
30500         while ( offset < zLength ) {
30501
30502             var vertex = new THREE.Vector3();
30503
30504             vertex.x = vertices[ offset ++ ] * scale;
30505             vertex.y = vertices[ offset ++ ] * scale;
30506             vertex.z = vertices[ offset ++ ] * scale;
30507
30508             geometry.vertices.push( vertex );
30509
30510         }
30511
30512         offset = 0;
30513         zLength = faces.length;
30514
30515         while ( offset < zLength ) {
30516
30517             var type = faces[ offset ++ ];
30518
30519             var isQuad = isBitSet( type, 0 );
30520
30521             var hasMaterial = isBitSet( type, 1 );
30522             var hasFaceUv = isBitSet( type, 2 );
30523             var hasFaceVertexUv = isBitSet( type, 3 );
30524             var hasFaceNormal = isBitSet( type, 4 );
30525             var hasFaceVertexNormal = isBitSet( type, 5 );
30526             var hasFaceColor = isBitSet( type, 6 );
30527             var hasFaceVertexColor = isBitSet( type, 7 );
30528
30529             // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceUv, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
30530
30531             if ( isQuad ) {
30532
30533                 var face = new THREE.Face4();
30534
30535                 face.a = faces[ offset ++ ];
30536                 face.b = faces[ offset ++ ];
30537                 face.c = faces[ offset ++ ];
30538                 face.d = faces[ offset ++ ];
30539
30540                 var nVertices = 4;
30541
30542             } else {
30543
30544                 var face = new THREE.Face3();
30545
30546                 face.a = faces[ offset ++ ];
30547                 face.b = faces[ offset ++ ];
30548                 face.c = faces[ offset ++ ];
30549
30550                 var nVertices = 3;
30551
30552             }
30553
30554             if ( hasMaterial ) {
30555
30556                 var materialIndex = faces[ offset ++ ];
30557                 face.materialIndex = materialIndex;
30558
30559             }
30560
30561             // to get face <=> uv index correspondence
30562
30563             var fi = geometry.faces.length;
30564
30565             if ( hasFaceUv ) {
30566
30567                 for ( var i = 0; i < nUvLayers; i ++ ) {
30568
30569                     var uvLayer = data.uvs[ i ];
30570
30571                     var uvIndex = faces[ offset ++ ];
30572
30573                     var u = uvLayer[ uvIndex * 2 ];
30574                     var v = uvLayer[ uvIndex * 2 + 1 ];
30575
30576                     geometry.faceUvs[ i ][ fi ] = new THREE.UV( u, v );
30577
30578                 }
30579
30580             }
30581
30582             if ( hasFaceVertexUv ) {
30583
30584                 for ( var i = 0; i < nUvLayers; i ++ ) {
30585
30586                     var uvLayer = data.uvs[ i ];
30587
30588                     var uvs = [];
30589
30590                     for ( var j = 0; j < nVertices; j ++ ) {
30591
30592                         var uvIndex = faces[ offset ++ ];
30593
30594                         var u = uvLayer[ uvIndex * 2 ];
30595                         var v = uvLayer[ uvIndex * 2 + 1 ];
30596
30597                         uvs[ j ] = new THREE.UV( u, v );
30598
30599                     }
30600
30601                     geometry.faceVertexUvs[ i ][ fi ] = uvs;
30602
30603                 }
30604
30605             }
30606
30607             if ( hasFaceNormal ) {
30608
30609                 var normalIndex = faces[ offset ++ ] * 3;
30610
30611                 var normal = new THREE.Vector3();
30612
30613                 normal.x = normals[ normalIndex ++ ];
30614                 normal.y = normals[ normalIndex ++ ];
30615                 normal.z = normals[ normalIndex ];
30616
30617                 face.normal = normal;
30618
30619             }
30620
30621             if ( hasFaceVertexNormal ) {
30622
30623                 for ( i = 0; i < nVertices; i ++ ) {
30624
30625                     var normalIndex = faces[ offset ++ ] * 3;
30626
30627                     var normal = new THREE.Vector3();
30628
30629                     normal.x = normals[ normalIndex ++ ];
30630                     normal.y = normals[ normalIndex ++ ];
30631                     normal.z = normals[ normalIndex ];
30632
30633                     face.vertexNormals.push( normal );
30634
30635                 }
30636
30637             }
30638
30639
30640             if ( hasFaceColor ) {
30641
30642                 var colorIndex = faces[ offset ++ ];
30643
30644                 face.color = new THREE.Color( colors[ colorIndex ] );
30645
30646             }
30647
30648
30649             if ( hasFaceVertexColor ) {
30650
30651                 for ( var i = 0; i < nVertices; i ++ ) {
30652
30653                     var colorIndex = faces[ offset ++ ];
30654
30655                     face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );
30656
30657                 }
30658
30659             }
30660
30661             geometry.faces.push( face );
30662
30663         }
30664
30665
30666         // skin
30667
30668         if ( data.skinWeights ) {
30669
30670             for ( var i = 0, l = data.skinWeights.length; i < l; i += 2 ) {
30671
30672                 var x = data.skinWeights[ i ];
30673                 var y = data.skinWeights[ i + 1 ];
30674                 var z = 0;
30675                 var w = 0;
30676
30677                 geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
30678
30679             }
30680
30681         }
30682
30683         if ( data.skinIndices ) {
30684
30685             for ( var i = 0, l = data.skinIndices.length; i < l; i += 2 ) {
30686
30687                 var a = data.skinIndices[ i ];
30688                 var b = data.skinIndices[ i + 1 ];
30689                 var c = 0;
30690                 var d = 0;
30691
30692                 geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
30693
30694             }
30695
30696         }
30697
30698         geometry.bones = data.bones;
30699         geometry.animation = data.animation;
30700
30701
30702         // morphing
30703
30704         if ( data.morphTargets ) {
30705
30706             for ( var i = 0, l = data.morphTargets.length; i < l; i ++ ) {
30707
30708                 geometry.morphTargets[ i ] = {};
30709                 geometry.morphTargets[ i ].name = data.morphTargets[ i ].name;
30710                 geometry.morphTargets[ i ].vertices = [];
30711
30712                 var dstVertices = geometry.morphTargets[ i ].vertices;
30713                 var srcVertices = data.morphTargets [ i ].vertices;
30714
30715                 for( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
30716
30717                     var vertex = new THREE.Vector3();
30718                     vertex.x = srcVertices[ v ] * scale;
30719                     vertex.y = srcVertices[ v + 1 ] * scale;
30720                     vertex.z = srcVertices[ v + 2 ] * scale;
30721
30722                     dstVertices.push( vertex );
30723
30724                 }
30725
30726             }
30727
30728         }
30729
30730         if ( data.morphColors ) {
30731
30732             for ( var i = 0, l = data.morphColors.length; i < l; i++ ) {
30733
30734                 geometry.morphColors[ i ] = {};
30735                 geometry.morphColors[ i ].name = data.morphColors[ i ].name;
30736                 geometry.morphColors[ i ].colors = [];
30737
30738                 var dstColors = geometry.morphColors[ i ].colors;
30739                 var srcColors = data.morphColors [ i ].colors;
30740
30741                 for ( var c = 0, cl = srcColors.length; c < cl; c += 3 ) {
30742
30743                     var color = new THREE.Color( 0xffaa00 );
30744                     color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
30745
30746                     dstColors.push( color );
30747
30748                 }
30749
30750             }
30751
30752         }
30753
30754         geometry.computeCentroids();
30755         geometry.computeFaceNormals();
30756
30757         return geometry;
30758
30759     }
30760
30761 };
30762 /**
30763  * @author alteredq / http://alteredqualia.com/
30764  */
30765
30766 THREE.SceneLoader = function () {
30767
30768     this.onLoadStart = function () {};
30769     this.onLoadProgress = function() {};
30770     this.onLoadComplete = function () {};
30771
30772     this.callbackSync = function () {};
30773     this.callbackProgress = function () {};
30774
30775     this.geometryHandlerMap = {};
30776
30777     this.addGeometryHandler( "ascii", THREE.JSONLoader );
30778     this.addGeometryHandler( "binary", THREE.BinaryLoader );
30779
30780 };
30781
30782 THREE.SceneLoader.prototype.constructor = THREE.SceneLoader;
30783
30784 THREE.SceneLoader.prototype.load = function ( url, callbackFinished ) {
30785
30786     var scope = this;
30787
30788     var xhr = new XMLHttpRequest();
30789
30790     xhr.onreadystatechange = function () {
30791
30792         if ( xhr.readyState === 4 ) {
30793
30794             if ( xhr.status === 200 || xhr.status === 0 ) {
30795
30796                 var json = JSON.parse( xhr.responseText );
30797                 scope.parse( json, callbackFinished, url );
30798
30799             } else {
30800
30801                 console.error( "THREE.SceneLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
30802
30803             }
30804
30805         }
30806
30807     };
30808
30809     xhr.open( "GET", url, true );
30810     xhr.send( null );
30811
30812 };
30813
30814 THREE.SceneLoader.prototype.addGeometryHandler = function ( typeID, loaderClass ) {
30815
30816     this.geometryHandlerMap[ typeID ] = { "loaderClass": loaderClass };
30817
30818 };
30819
30820 THREE.SceneLoader.prototype.parse = function ( json, callbackFinished, url ) {
30821
30822     var scope = this;
30823
30824     var urlBase = THREE.Loader.prototype.extractUrlBase( url );
30825
30826     var dg, dm, dl, dc, df, dt,
30827         g, m, l, d, p, r, q, s, c, t, f, tt, pp, u,
30828         geometry, material, camera, fog,
30829         texture, images,
30830         light,
30831         counter_models, counter_textures,
30832         total_models, total_textures,
30833         result;
30834
30835     var data = json;
30836
30837     // async geometry loaders
30838
30839     for ( var typeID in this.geometryHandlerMap ) {
30840
30841         var loaderClass = this.geometryHandlerMap[ typeID ][ "loaderClass" ];
30842         this.geometryHandlerMap[ typeID ][ "loaderObject" ] = new loaderClass();
30843
30844     }
30845
30846     counter_models = 0;
30847     counter_textures = 0;
30848
30849     result = {
30850
30851         scene: new THREE.Scene(),
30852         geometries: {},
30853         materials: {},
30854         textures: {},
30855         objects: {},
30856         cameras: {},
30857         lights: {},
30858         fogs: {},
30859         empties: {}
30860
30861     };
30862
30863     if ( data.transform ) {
30864
30865         var position = data.transform.position,
30866             rotation = data.transform.rotation,
30867             scale = data.transform.scale;
30868
30869         if ( position )
30870             result.scene.position.set( position[ 0 ], position[ 1 ], position [ 2 ] );
30871
30872         if ( rotation )
30873             result.scene.rotation.set( rotation[ 0 ], rotation[ 1 ], rotation [ 2 ] );
30874
30875         if ( scale )
30876             result.scene.scale.set( scale[ 0 ], scale[ 1 ], scale [ 2 ] );
30877
30878         if ( position || rotation || scale ) {
30879
30880             result.scene.updateMatrix();
30881             result.scene.updateMatrixWorld();
30882
30883         }
30884
30885     }
30886
30887     function get_url( source_url, url_type ) {
30888
30889         if ( url_type == "relativeToHTML" ) {
30890
30891             return source_url;
30892
30893         } else {
30894
30895             return urlBase + "/" + source_url;
30896
30897         }
30898
30899     };
30900
30901     // toplevel loader function, delegates to handle_children
30902
30903     function handle_objects() {
30904
30905         handle_children( result.scene, data.objects );
30906
30907     }
30908
30909     // handle all the children from the loaded json and attach them to given parent
30910
30911     function handle_children( parent, children ) {
30912
30913         for ( var dd in children ) {
30914
30915             // check by id if child has already been handled,
30916             // if not, create new object
30917
30918             if ( result.objects[ dd ] === undefined ) {
30919
30920                 var o = children[ dd ];
30921
30922                 var object = null;
30923
30924                 if ( o.geometry !== undefined ) {
30925
30926                     geometry = result.geometries[ o.geometry ];
30927
30928                     // geometry already loaded
30929
30930                     if ( geometry ) {
30931
30932                         var hasNormals = false;
30933
30934                         // not anymore support for multiple materials
30935                         // shouldn't really be array
30936
30937                         material = result.materials[ o.materials[ 0 ] ];
30938                         hasNormals = material instanceof THREE.ShaderMaterial;
30939
30940                         if ( hasNormals ) {
30941
30942                             geometry.computeTangents();
30943
30944                         }
30945
30946                         p = o.position;
30947                         r = o.rotation;
30948                         q = o.quaternion;
30949                         s = o.scale;
30950                         m = o.matrix;
30951
30952                         // turn off quaternions, for the moment
30953
30954                         q = 0;
30955
30956                         if ( o.materials.length === 0 ) {
30957
30958                             material = new THREE.MeshFaceMaterial();
30959
30960                         }
30961
30962                         // dirty hack to handle meshes with multiple materials
30963                         // just use face materials defined in model
30964
30965                         if ( o.materials.length > 1 ) {
30966
30967                             material = new THREE.MeshFaceMaterial();
30968
30969                         }
30970
30971                         if ( o.morph ) {
30972
30973                             object = new THREE.MorphAnimMesh( geometry, material );
30974
30975                             if ( o.duration !== undefined ) {
30976
30977                                 object.duration = o.duration;
30978
30979                             }
30980
30981                             if ( o.time !== undefined ) {
30982
30983                                 object.time = o.time;
30984
30985                             }
30986
30987                             if ( o.mirroredLoop !== undefined ) {
30988
30989                                 object.mirroredLoop = o.mirroredLoop;
30990
30991                             }
30992
30993                             if ( material.morphNormals ) {
30994
30995                                 geometry.computeMorphNormals();
30996
30997                             }
30998
30999                         } else {
31000
31001                             object = new THREE.Mesh( geometry, material );
31002
31003                         }
31004
31005                         object.name = dd;
31006
31007                         if ( m ) {
31008
31009                             object.matrixAutoUpdate = false;
31010                             object.matrix.set(
31011                                 m[0], m[1], m[2], m[3],
31012                                 m[4], m[5], m[6], m[7],
31013                                 m[8], m[9], m[10], m[11],
31014                                 m[12], m[13], m[14], m[15]
31015                             );
31016
31017                         } else {
31018
31019                             object.position.set( p[0], p[1], p[2] );
31020
31021                             if ( q ) {
31022
31023                                 object.quaternion.set( q[0], q[1], q[2], q[3] );
31024                                 object.useQuaternion = true;
31025
31026                             } else {
31027
31028                                 object.rotation.set( r[0], r[1], r[2] );
31029
31030                             }
31031
31032                             object.scale.set( s[0], s[1], s[2] );
31033
31034                         }
31035
31036                         object.visible = o.visible;
31037                         object.castShadow = o.castShadow;
31038                         object.receiveShadow = o.receiveShadow;
31039
31040                         parent.add( object );
31041
31042                         result.objects[ dd ] = object;
31043
31044                     }
31045
31046                 // pure Object3D
31047
31048                 } else {
31049
31050                     p = o.position;
31051                     r = o.rotation;
31052                     q = o.quaternion;
31053                     s = o.scale;
31054
31055                     // turn off quaternions, for the moment
31056
31057                     q = 0;
31058
31059                     object = new THREE.Object3D();
31060                     object.name = dd;
31061                     object.position.set( p[0], p[1], p[2] );
31062
31063                     if ( q ) {
31064
31065                         object.quaternion.set( q[0], q[1], q[2], q[3] );
31066                         object.useQuaternion = true;
31067
31068                     } else {
31069
31070                         object.rotation.set( r[0], r[1], r[2] );
31071
31072                     }
31073
31074                     object.scale.set( s[0], s[1], s[2] );
31075                     object.visible = ( o.visible !== undefined ) ? o.visible : false;
31076
31077                     parent.add( object );
31078
31079                     result.objects[ dd ] = object;
31080                     result.empties[ dd ] = object;
31081
31082                 }
31083
31084                 if ( object ) {
31085
31086                     if ( o.properties !== undefined )  {
31087
31088                         for ( var key in o.properties ) {
31089
31090                             var value = o.properties[ key ];
31091                             object.properties[ key ] = value;
31092
31093                         }
31094
31095                     }
31096
31097                     if ( o.children !== undefined ) {
31098
31099                         handle_children( object, o.children );
31100
31101                     }
31102
31103                 }
31104
31105             }
31106
31107         }
31108
31109     };
31110
31111     function handle_mesh( geo, id ) {
31112
31113         result.geometries[ id ] = geo;
31114         handle_objects();
31115
31116     };
31117
31118     function create_callback( id ) {
31119
31120         return function( geo ) {
31121
31122             handle_mesh( geo, id );
31123
31124             counter_models -= 1;
31125
31126             scope.onLoadComplete();
31127
31128             async_callback_gate();
31129
31130         }
31131
31132     };
31133
31134     function create_callback_embed( id ) {
31135
31136         return function( geo ) {
31137
31138             result.geometries[ id ] = geo;
31139
31140         }
31141
31142     };
31143
31144     function async_callback_gate() {
31145
31146         var progress = {
31147
31148             totalModels : total_models,
31149             totalTextures : total_textures,
31150             loadedModels : total_models - counter_models,
31151             loadedTextures : total_textures - counter_textures
31152
31153         };
31154
31155         scope.callbackProgress( progress, result );
31156
31157         scope.onLoadProgress();
31158
31159         if ( counter_models === 0 && counter_textures === 0 ) {
31160
31161             callbackFinished( result );
31162
31163         }
31164
31165     };
31166
31167     var callbackTexture = function ( count ) {
31168
31169         counter_textures -= count;
31170         async_callback_gate();
31171
31172         scope.onLoadComplete();
31173
31174     };
31175
31176     // must use this instead of just directly calling callbackTexture
31177     // because of closure in the calling context loop
31178
31179     var generateTextureCallback = function ( count ) {
31180
31181         return function() {
31182
31183             callbackTexture( count );
31184
31185         };
31186
31187     };
31188
31189     // first go synchronous elements
31190
31191     // cameras
31192
31193     for( dc in data.cameras ) {
31194
31195         c = data.cameras[ dc ];
31196
31197         if ( c.type === "perspective" ) {
31198
31199             camera = new THREE.PerspectiveCamera( c.fov, c.aspect, c.near, c.far );
31200
31201         } else if ( c.type === "ortho" ) {
31202
31203             camera = new THREE.OrthographicCamera( c.left, c.right, c.top, c.bottom, c.near, c.far );
31204
31205         }
31206
31207         p = c.position;
31208         t = c.target;
31209         u = c.up;
31210
31211         camera.position.set( p[0], p[1], p[2] );
31212         camera.target = new THREE.Vector3( t[0], t[1], t[2] );
31213         if ( u ) camera.up.set( u[0], u[1], u[2] );
31214
31215         result.cameras[ dc ] = camera;
31216
31217     }
31218
31219     // lights
31220
31221     var hex, intensity;
31222
31223     for ( dl in data.lights ) {
31224
31225         l = data.lights[ dl ];
31226
31227         hex = ( l.color !== undefined ) ? l.color : 0xffffff;
31228         intensity = ( l.intensity !== undefined ) ? l.intensity : 1;
31229
31230         if ( l.type === "directional" ) {
31231
31232             p = l.direction;
31233
31234             light = new THREE.DirectionalLight( hex, intensity );
31235             light.position.set( p[0], p[1], p[2] );
31236             light.position.normalize();
31237
31238         } else if ( l.type === "point" ) {
31239
31240             p = l.position;
31241             d = l.distance;
31242
31243             light = new THREE.PointLight( hex, intensity, d );
31244             light.position.set( p[0], p[1], p[2] );
31245
31246         } else if ( l.type === "ambient" ) {
31247
31248             light = new THREE.AmbientLight( hex );
31249
31250         }
31251
31252         result.scene.add( light );
31253
31254         result.lights[ dl ] = light;
31255
31256     }
31257
31258     // fogs
31259
31260     for( df in data.fogs ) {
31261
31262         f = data.fogs[ df ];
31263
31264         if ( f.type === "linear" ) {
31265
31266             fog = new THREE.Fog( 0x000000, f.near, f.far );
31267
31268         } else if ( f.type === "exp2" ) {
31269
31270             fog = new THREE.FogExp2( 0x000000, f.density );
31271
31272         }
31273
31274         c = f.color;
31275         fog.color.setRGB( c[0], c[1], c[2] );
31276
31277         result.fogs[ df ] = fog;
31278
31279     }
31280
31281     // defaults
31282
31283     if ( result.cameras && data.defaults && data.defaults.camera ) {
31284
31285         result.currentCamera = result.cameras[ data.defaults.camera ];
31286
31287     }
31288
31289     if ( result.fogs && data.defaults && data.defaults.fog ) {
31290
31291         result.scene.fog = result.fogs[ data.defaults.fog ];
31292
31293     }
31294
31295     c = data.defaults.bgcolor;
31296     result.bgColor = new THREE.Color();
31297     result.bgColor.setRGB( c[0], c[1], c[2] );
31298
31299     result.bgColorAlpha = data.defaults.bgalpha;
31300
31301     // now come potentially asynchronous elements
31302
31303     // geometries
31304
31305     // count how many models will be loaded asynchronously
31306
31307     for( dg in data.geometries ) {
31308
31309         g = data.geometries[ dg ];
31310
31311         if ( g.type in this.geometryHandlerMap ) {
31312
31313             counter_models += 1;
31314
31315             scope.onLoadStart();
31316
31317         }
31318
31319     }
31320
31321     total_models = counter_models;
31322
31323     for ( dg in data.geometries ) {
31324
31325         g = data.geometries[ dg ];
31326
31327         if ( g.type === "cube" ) {
31328
31329             geometry = new THREE.CubeGeometry( g.width, g.height, g.depth, g.segmentsWidth, g.segmentsHeight, g.segmentsDepth, null, g.flipped, g.sides );
31330             result.geometries[ dg ] = geometry;
31331
31332         } else if ( g.type === "plane" ) {
31333
31334             geometry = new THREE.PlaneGeometry( g.width, g.height, g.segmentsWidth, g.segmentsHeight );
31335             result.geometries[ dg ] = geometry;
31336
31337         } else if ( g.type === "sphere" ) {
31338
31339             geometry = new THREE.SphereGeometry( g.radius, g.segmentsWidth, g.segmentsHeight );
31340             result.geometries[ dg ] = geometry;
31341
31342         } else if ( g.type === "cylinder" ) {
31343
31344             geometry = new THREE.CylinderGeometry( g.topRad, g.botRad, g.height, g.radSegs, g.heightSegs );
31345             result.geometries[ dg ] = geometry;
31346
31347         } else if ( g.type === "torus" ) {
31348
31349             geometry = new THREE.TorusGeometry( g.radius, g.tube, g.segmentsR, g.segmentsT );
31350             result.geometries[ dg ] = geometry;
31351
31352         } else if ( g.type === "icosahedron" ) {
31353
31354             geometry = new THREE.IcosahedronGeometry( g.radius, g.subdivisions );
31355             result.geometries[ dg ] = geometry;
31356
31357         } else if ( g.type in this.geometryHandlerMap ) {
31358
31359             var loaderParameters = {};
31360             for ( var parType in g ) {
31361
31362                 if ( parType !== "type" && parType !== "url" ) {
31363
31364                     loaderParameters[ parType ] = g[ parType ];
31365
31366                 }
31367
31368             }
31369
31370             var loader = this.geometryHandlerMap[ g.type ][ "loaderObject" ];
31371             loader.load( get_url( g.url, data.urlBaseType ), create_callback( dg ), loaderParameters );
31372
31373         } else if ( g.type === "embedded" ) {
31374
31375             var modelJson = data.embeds[ g.id ],
31376                 texture_path = "";
31377
31378             // pass metadata along to jsonLoader so it knows the format version
31379
31380             modelJson.metadata = data.metadata;
31381
31382             if ( modelJson ) {
31383
31384                 var jsonLoader = this.geometryHandlerMap[ "ascii" ][ "loaderObject" ];
31385                 jsonLoader.createModel( modelJson, create_callback_embed( dg ), texture_path );
31386
31387             }
31388
31389         }
31390
31391     }
31392
31393     // textures
31394
31395     // count how many textures will be loaded asynchronously
31396
31397     for( dt in data.textures ) {
31398
31399         tt = data.textures[ dt ];
31400
31401         if( tt.url instanceof Array ) {
31402
31403             counter_textures += tt.url.length;
31404
31405             for( var n = 0; n < tt.url.length; n ++ ) {
31406
31407                 scope.onLoadStart();
31408
31409             }
31410
31411         } else {
31412
31413             counter_textures += 1;
31414
31415             scope.onLoadStart();
31416
31417         }
31418
31419     }
31420
31421     total_textures = counter_textures;
31422
31423     for ( dt in data.textures ) {
31424
31425         tt = data.textures[ dt ];
31426
31427         if ( tt.mapping !== undefined && THREE[ tt.mapping ] !== undefined  ) {
31428
31429             tt.mapping = new THREE[ tt.mapping ]();
31430
31431         }
31432
31433         if ( tt.url instanceof Array ) {
31434
31435             var count = tt.url.length;
31436             var url_array = [];
31437
31438             for( var i = 0; i < count; i ++ ) {
31439
31440                 url_array[ i ] = get_url( tt.url[ i ], data.urlBaseType );
31441
31442             }
31443
31444             var isCompressed = url_array[ 0 ].endsWith( ".dds" );
31445
31446             if ( isCompressed ) {
31447
31448                 texture = THREE.ImageUtils.loadCompressedTextureCube( url_array, tt.mapping, generateTextureCallback( count ) );
31449
31450             } else {
31451
31452                 texture = THREE.ImageUtils.loadTextureCube( url_array, tt.mapping, generateTextureCallback( count ) );
31453
31454             }
31455
31456         } else {
31457
31458             var isCompressed = tt.url.toLowerCase().endsWith( ".dds" );
31459             var fullUrl = get_url( tt.url, data.urlBaseType );
31460             var textureCallback = generateTextureCallback( 1 );
31461
31462             if ( isCompressed ) {
31463
31464                 texture = THREE.ImageUtils.loadCompressedTexture( fullUrl, tt.mapping, textureCallback );
31465
31466             } else {
31467
31468                 texture = THREE.ImageUtils.loadTexture( fullUrl, tt.mapping, textureCallback );
31469
31470             }
31471
31472             if ( THREE[ tt.minFilter ] !== undefined )
31473                 texture.minFilter = THREE[ tt.minFilter ];
31474
31475             if ( THREE[ tt.magFilter ] !== undefined )
31476                 texture.magFilter = THREE[ tt.magFilter ];
31477
31478             if ( tt.anisotropy ) texture.anisotropy = tt.anisotropy;
31479
31480             if ( tt.repeat ) {
31481
31482                 texture.repeat.set( tt.repeat[ 0 ], tt.repeat[ 1 ] );
31483
31484                 if ( tt.repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping;
31485                 if ( tt.repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping;
31486
31487             }
31488
31489             if ( tt.offset ) {
31490
31491                 texture.offset.set( tt.offset[ 0 ], tt.offset[ 1 ] );
31492
31493             }
31494
31495             // handle wrap after repeat so that default repeat can be overriden
31496
31497             if ( tt.wrap ) {
31498
31499                 var wrapMap = {
31500                 "repeat"     : THREE.RepeatWrapping,
31501                 "mirror"    : THREE.MirroredRepeatWrapping
31502                 }
31503
31504                 if ( wrapMap[ tt.wrap[ 0 ] ] !== undefined ) texture.wrapS = wrapMap[ tt.wrap[ 0 ] ];
31505                 if ( wrapMap[ tt.wrap[ 1 ] ] !== undefined ) texture.wrapT = wrapMap[ tt.wrap[ 1 ] ];
31506
31507             }
31508
31509         }
31510
31511         result.textures[ dt ] = texture;
31512
31513     }
31514
31515     // materials
31516
31517     for ( dm in data.materials ) {
31518
31519         m = data.materials[ dm ];
31520
31521         for ( pp in m.parameters ) {
31522
31523             if ( pp === "envMap" || pp === "map" || pp === "lightMap" || pp === "bumpMap" ) {
31524
31525                 m.parameters[ pp ] = result.textures[ m.parameters[ pp ] ];
31526
31527             } else if ( pp === "shading" ) {
31528
31529                 m.parameters[ pp ] = ( m.parameters[ pp ] === "flat" ) ? THREE.FlatShading : THREE.SmoothShading;
31530
31531             } else if ( pp === "side" ) {
31532
31533                 if (  m.parameters[ pp ] == "double" ) {
31534
31535                     m.parameters[ pp ] = THREE.DoubleSide;
31536
31537                 } else if ( m.parameters[ pp ] == "back" ) {
31538
31539                     m.parameters[ pp ] = THREE.BackSide;
31540
31541                 } else {
31542
31543                     m.parameters[ pp ] = THREE.FrontSide;
31544
31545                 }
31546
31547             } else if ( pp === "blending" ) {
31548
31549                 m.parameters[ pp ] = m.parameters[ pp ] in THREE ? THREE[ m.parameters[ pp ] ] : THREE.NormalBlending;
31550
31551             } else if ( pp === "combine" ) {
31552
31553                 m.parameters[ pp ] = ( m.parameters[ pp ] == "MixOperation" ) ? THREE.MixOperation : THREE.MultiplyOperation;
31554
31555             } else if ( pp === "vertexColors" ) {
31556
31557                 if ( m.parameters[ pp ] == "face" ) {
31558
31559                     m.parameters[ pp ] = THREE.FaceColors;
31560
31561                 // default to vertex colors if "vertexColors" is anything else face colors or 0 / null / false
31562
31563                 } else if ( m.parameters[ pp ] )   {
31564
31565                     m.parameters[ pp ] = THREE.VertexColors;
31566
31567                 }
31568
31569             } else if ( pp === "wrapRGB" ) {
31570
31571                 var v3 = m.parameters[ pp ];
31572                 m.parameters[ pp ] = new THREE.Vector3( v3[ 0 ], v3[ 1 ], v3[ 2 ] );
31573
31574             }
31575
31576         }
31577
31578         if ( m.parameters.opacity !== undefined && m.parameters.opacity < 1.0 ) {
31579
31580             m.parameters.transparent = true;
31581
31582         }
31583
31584         if ( m.parameters.normalMap ) {
31585
31586             var shader = THREE.ShaderUtils.lib[ "normal" ];
31587             var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
31588
31589             var diffuse = m.parameters.color;
31590             var specular = m.parameters.specular;
31591             var ambient = m.parameters.ambient;
31592             var shininess = m.parameters.shininess;
31593
31594             uniforms[ "tNormal" ].value = result.textures[ m.parameters.normalMap ];
31595
31596             if ( m.parameters.normalScale ) {
31597
31598                 uniforms[ "uNormalScale" ].value.set( m.parameters.normalScale[ 0 ], m.parameters.normalScale[ 1 ] );
31599
31600             }
31601
31602             if ( m.parameters.map ) {
31603
31604                 uniforms[ "tDiffuse" ].value = m.parameters.map;
31605                 uniforms[ "enableDiffuse" ].value = true;
31606
31607             }
31608
31609             if ( m.parameters.envMap ) {
31610
31611                 uniforms[ "tCube" ].value = m.parameters.envMap;
31612                 uniforms[ "enableReflection" ].value = true;
31613                 uniforms[ "uReflectivity" ].value = m.parameters.reflectivity;
31614
31615             }
31616
31617             if ( m.parameters.lightMap ) {
31618
31619                 uniforms[ "tAO" ].value = m.parameters.lightMap;
31620                 uniforms[ "enableAO" ].value = true;
31621
31622             }
31623
31624             if ( m.parameters.specularMap ) {
31625
31626                 uniforms[ "tSpecular" ].value = result.textures[ m.parameters.specularMap ];
31627                 uniforms[ "enableSpecular" ].value = true;
31628
31629             }
31630
31631             if ( m.parameters.displacementMap ) {
31632
31633                 uniforms[ "tDisplacement" ].value = result.textures[ m.parameters.displacementMap ];
31634                 uniforms[ "enableDisplacement" ].value = true;
31635
31636                 uniforms[ "uDisplacementBias" ].value = m.parameters.displacementBias;
31637                 uniforms[ "uDisplacementScale" ].value = m.parameters.displacementScale;
31638
31639             }
31640
31641             uniforms[ "uDiffuseColor" ].value.setHex( diffuse );
31642             uniforms[ "uSpecularColor" ].value.setHex( specular );
31643             uniforms[ "uAmbientColor" ].value.setHex( ambient );
31644
31645             uniforms[ "uShininess" ].value = shininess;
31646
31647             if ( m.parameters.opacity ) {
31648
31649                 uniforms[ "uOpacity" ].value = m.parameters.opacity;
31650
31651             }
31652
31653             var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
31654
31655             material = new THREE.ShaderMaterial( parameters );
31656
31657         } else {
31658
31659             material = new THREE[ m.type ]( m.parameters );
31660
31661         }
31662
31663         result.materials[ dm ] = material;
31664
31665     }
31666
31667     // objects ( synchronous init of procedural primitives )
31668
31669     handle_objects();
31670
31671     // synchronous callback
31672
31673     scope.callbackSync( result );
31674
31675     // just in case there are no async elements
31676
31677     async_callback_gate();
31678
31679 };
31680 /**
31681  * @author mrdoob / http://mrdoob.com/
31682  */
31683
31684 THREE.TextureLoader = function () {
31685
31686     THREE.EventTarget.call( this );
31687
31688     this.crossOrigin = null;
31689
31690 };
31691
31692 THREE.TextureLoader.prototype = {
31693
31694     constructor: THREE.TextureLoader,
31695
31696     load: function ( url ) {
31697
31698         var scope = this;
31699
31700         var image = new Image();
31701
31702         image.addEventListener( 'load', function () {
31703
31704             var texture = new THREE.Texture( image );
31705             texture.needsUpdate = true;
31706
31707             scope.dispatchEvent( { type: 'load', content: texture } );
31708
31709         }, false );
31710
31711         image.addEventListener( 'error', function () {
31712
31713             scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
31714
31715         }, false );
31716
31717         if ( scope.crossOrigin ) image.crossOrigin = scope.crossOrigin;
31718
31719         image.src = url;
31720
31721     }
31722
31723 }
31724 /**
31725  * @author mrdoob / http://mrdoob.com/
31726  * @author alteredq / http://alteredqualia.com/
31727  */
31728
31729 THREE.Material = function () {
31730
31731     this.id = THREE.MaterialCount ++;
31732
31733     this.name = '';
31734
31735     this.side = THREE.FrontSide;
31736
31737     this.opacity = 1;
31738     this.transparent = false;
31739
31740     this.blending = THREE.NormalBlending;
31741
31742     this.blendSrc = THREE.SrcAlphaFactor;
31743     this.blendDst = THREE.OneMinusSrcAlphaFactor;
31744     this.blendEquation = THREE.AddEquation;
31745
31746     this.depthTest = true;
31747     this.depthWrite = true;
31748
31749     this.polygonOffset = false;
31750     this.polygonOffsetFactor = 0;
31751     this.polygonOffsetUnits = 0;
31752
31753     this.alphaTest = 0;
31754
31755     this.overdraw = false; // Boolean for fixing antialiasing gaps in CanvasRenderer
31756
31757     this.visible = true;
31758
31759     this.needsUpdate = true;
31760
31761 };
31762
31763 THREE.Material.prototype.setValues = function ( values ) {
31764
31765     if ( values === undefined ) return;
31766
31767     for ( var key in values ) {
31768
31769         var newValue = values[ key ];
31770
31771         if ( newValue === undefined ) {
31772
31773             console.warn( 'THREE.Material: \'' + key + '\' parameter is undefined.' );
31774             continue;
31775
31776         }
31777
31778         if ( key in this ) {
31779
31780             var currentValue = this[ key ];
31781
31782             if ( currentValue instanceof THREE.Color && newValue instanceof THREE.Color ) {
31783
31784                 currentValue.copy( newValue );
31785
31786             } else if ( currentValue instanceof THREE.Color && typeof( newValue ) === "number" ) {
31787
31788                 currentValue.setHex( newValue );
31789
31790             } else if ( currentValue instanceof THREE.Vector3 && newValue instanceof THREE.Vector3 ) {
31791
31792                 currentValue.copy( newValue );
31793
31794             } else {
31795
31796                 this[ key ] = newValue;
31797
31798             }
31799
31800         }
31801
31802     }
31803
31804 };
31805
31806 THREE.Material.prototype.clone = function ( material ) {
31807
31808     if ( material === undefined ) material = new THREE.Material();
31809
31810     material.name = this.name;
31811
31812     material.side = this.side;
31813
31814     material.opacity = this.opacity;
31815     material.transparent = this.transparent;
31816
31817     material.blending = this.blending;
31818
31819     material.blendSrc = this.blendSrc;
31820     material.blendDst = this.blendDst;
31821     material.blendEquation = this.blendEquation;
31822
31823     material.depthTest = this.depthTest;
31824     material.depthWrite = this.depthWrite;
31825
31826     material.polygonOffset = this.polygonOffset;
31827     material.polygonOffsetFactor = this.polygonOffsetFactor;
31828     material.polygonOffsetUnits = this.polygonOffsetUnits;
31829
31830     material.alphaTest = this.alphaTest;
31831
31832     material.overdraw = this.overdraw;
31833
31834     material.visible = this.visible;
31835
31836     return material;
31837
31838 };
31839
31840 THREE.MaterialCount = 0;
31841 /**
31842  * @author mrdoob / http://mrdoob.com/
31843  * @author alteredq / http://alteredqualia.com/
31844  *
31845  * parameters = {
31846  *  color: <hex>,
31847  *  opacity: <float>,
31848  *
31849  *  blending: THREE.NormalBlending,
31850  *  depthTest: <bool>,
31851  *
31852  *  linewidth: <float>,
31853  *  linecap: "round",
31854  *  linejoin: "round",
31855  *
31856  *  vertexColors: <bool>
31857  *
31858  *  fog: <bool>
31859  * }
31860  */
31861
31862 THREE.LineBasicMaterial = function ( parameters ) {
31863
31864     THREE.Material.call( this );
31865
31866     this.color = new THREE.Color( 0xffffff );
31867
31868     this.linewidth = 1;
31869     this.linecap = 'round';
31870     this.linejoin = 'round';
31871
31872     this.vertexColors = false;
31873
31874     this.fog = true;
31875
31876     this.setValues( parameters );
31877
31878 };
31879
31880 THREE.LineBasicMaterial.prototype = Object.create( THREE.Material.prototype );
31881
31882 THREE.LineBasicMaterial.prototype.clone = function () {
31883
31884     var material = new THREE.LineBasicMaterial();
31885
31886     THREE.Material.prototype.clone.call( this, material );
31887
31888     material.color.copy( this.color );
31889
31890     material.linewidth = this.linewidth;
31891     material.linecap = this.linecap;
31892     material.linejoin = this.linejoin;
31893
31894     material.vertexColors = this.vertexColors;
31895
31896     material.fog = this.fog;
31897
31898     return material;
31899
31900 };
31901 /**
31902  * @author mrdoob / http://mrdoob.com/
31903  * @author alteredq / http://alteredqualia.com/
31904  *
31905  * parameters = {
31906  *  color: <hex>,
31907  *  opacity: <float>,
31908  *  map: new THREE.Texture( <Image> ),
31909  *
31910  *  lightMap: new THREE.Texture( <Image> ),
31911  *
31912  *  specularMap: new THREE.Texture( <Image> ),
31913  *
31914  *  envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
31915  *  combine: THREE.Multiply,
31916  *  reflectivity: <float>,
31917  *  refractionRatio: <float>,
31918  *
31919  *  shading: THREE.SmoothShading,
31920  *  blending: THREE.NormalBlending,
31921  *  depthTest: <bool>,
31922  *
31923  *  wireframe: <boolean>,
31924  *  wireframeLinewidth: <float>,
31925  *
31926  *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
31927  *
31928  *  skinning: <bool>,
31929  *  morphTargets: <bool>,
31930  *
31931  *  fog: <bool>
31932  * }
31933  */
31934
31935 THREE.MeshBasicMaterial = function ( parameters ) {
31936
31937     THREE.Material.call( this );
31938
31939     this.color = new THREE.Color( 0xffffff ); // emissive
31940
31941     this.map = null;
31942
31943     this.lightMap = null;
31944
31945     this.specularMap = null;
31946
31947     this.envMap = null;
31948     this.combine = THREE.MultiplyOperation;
31949     this.reflectivity = 1;
31950     this.refractionRatio = 0.98;
31951
31952     this.fog = true;
31953
31954     this.shading = THREE.SmoothShading;
31955
31956     this.wireframe = false;
31957     this.wireframeLinewidth = 1;
31958     this.wireframeLinecap = 'round';
31959     this.wireframeLinejoin = 'round';
31960
31961     this.vertexColors = THREE.NoColors;
31962
31963     this.skinning = false;
31964     this.morphTargets = false;
31965
31966     this.setValues( parameters );
31967
31968 };
31969
31970 THREE.MeshBasicMaterial.prototype = Object.create( THREE.Material.prototype );
31971
31972 THREE.MeshBasicMaterial.prototype.clone = function () {
31973
31974     var material = new THREE.MeshBasicMaterial();
31975
31976     THREE.Material.prototype.clone.call( this, material );
31977
31978     material.color.copy( this.color );
31979
31980     material.map = this.map;
31981
31982     material.lightMap = this.lightMap;
31983
31984     material.specularMap = this.specularMap;
31985
31986     material.envMap = this.envMap;
31987     material.combine = this.combine;
31988     material.reflectivity = this.reflectivity;
31989     material.refractionRatio = this.refractionRatio;
31990
31991     material.fog = this.fog;
31992
31993     material.shading = this.shading;
31994
31995     material.wireframe = this.wireframe;
31996     material.wireframeLinewidth = this.wireframeLinewidth;
31997     material.wireframeLinecap = this.wireframeLinecap;
31998     material.wireframeLinejoin = this.wireframeLinejoin;
31999
32000     material.vertexColors = this.vertexColors;
32001
32002     material.skinning = this.skinning;
32003     material.morphTargets = this.morphTargets;
32004
32005     return material;
32006
32007 };
32008 /**
32009  * @author mrdoob / http://mrdoob.com/
32010  * @author alteredq / http://alteredqualia.com/
32011  *
32012  * parameters = {
32013  *  color: <hex>,
32014  *  ambient: <hex>,
32015  *  emissive: <hex>,
32016  *  opacity: <float>,
32017  *
32018  *  map: new THREE.Texture( <Image> ),
32019  *
32020  *  lightMap: new THREE.Texture( <Image> ),
32021  *
32022  *  specularMap: new THREE.Texture( <Image> ),
32023  *
32024  *  envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
32025  *  combine: THREE.Multiply,
32026  *  reflectivity: <float>,
32027  *  refractionRatio: <float>,
32028  *
32029  *  shading: THREE.SmoothShading,
32030  *  blending: THREE.NormalBlending,
32031  *  depthTest: <bool>,
32032  *
32033  *  wireframe: <boolean>,
32034  *  wireframeLinewidth: <float>,
32035  *
32036  *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
32037  *
32038  *  skinning: <bool>,
32039  *  morphTargets: <bool>,
32040  *  morphNormals: <bool>,
32041  *
32042  *    fog: <bool>
32043  * }
32044  */
32045
32046 THREE.MeshLambertMaterial = function ( parameters ) {
32047
32048     THREE.Material.call( this );
32049
32050     this.color = new THREE.Color( 0xffffff ); // diffuse
32051     this.ambient = new THREE.Color( 0xffffff );
32052     this.emissive = new THREE.Color( 0x000000 );
32053
32054     this.wrapAround = false;
32055     this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
32056
32057     this.map = null;
32058
32059     this.lightMap = null;
32060
32061     this.specularMap = null;
32062
32063     this.envMap = null;
32064     this.combine = THREE.MultiplyOperation;
32065     this.reflectivity = 1;
32066     this.refractionRatio = 0.98;
32067
32068     this.fog = true;
32069
32070     this.shading = THREE.SmoothShading;
32071
32072     this.wireframe = false;
32073     this.wireframeLinewidth = 1;
32074     this.wireframeLinecap = 'round';
32075     this.wireframeLinejoin = 'round';
32076
32077     this.vertexColors = THREE.NoColors;
32078
32079     this.skinning = false;
32080     this.morphTargets = false;
32081     this.morphNormals = false;
32082
32083     this.setValues( parameters );
32084
32085 };
32086
32087 THREE.MeshLambertMaterial.prototype = Object.create( THREE.Material.prototype );
32088
32089 THREE.MeshLambertMaterial.prototype.clone = function () {
32090
32091     var material = new THREE.MeshLambertMaterial();
32092
32093     THREE.Material.prototype.clone.call( this, material );
32094
32095     material.color.copy( this.color );
32096     material.ambient.copy( this.ambient );
32097     material.emissive.copy( this.emissive );
32098
32099     material.wrapAround = this.wrapAround;
32100     material.wrapRGB.copy( this.wrapRGB );
32101
32102     material.map = this.map;
32103
32104     material.lightMap = this.lightMap;
32105
32106     material.specularMap = this.specularMap;
32107
32108     material.envMap = this.envMap;
32109     material.combine = this.combine;
32110     material.reflectivity = this.reflectivity;
32111     material.refractionRatio = this.refractionRatio;
32112
32113     material.fog = this.fog;
32114
32115     material.shading = this.shading;
32116
32117     material.wireframe = this.wireframe;
32118     material.wireframeLinewidth = this.wireframeLinewidth;
32119     material.wireframeLinecap = this.wireframeLinecap;
32120     material.wireframeLinejoin = this.wireframeLinejoin;
32121
32122     material.vertexColors = this.vertexColors;
32123
32124     material.skinning = this.skinning;
32125     material.morphTargets = this.morphTargets;
32126     material.morphNormals = this.morphNormals;
32127
32128     return material;
32129
32130 };
32131 /**
32132  * @author mrdoob / http://mrdoob.com/
32133  * @author alteredq / http://alteredqualia.com/
32134  *
32135  * parameters = {
32136  *  color: <hex>,
32137  *  ambient: <hex>,
32138  *  emissive: <hex>,
32139  *  specular: <hex>,
32140  *  shininess: <float>,
32141  *  opacity: <float>,
32142  *
32143  *  map: new THREE.Texture( <Image> ),
32144  *
32145  *  lightMap: new THREE.Texture( <Image> ),
32146  *
32147  *  bumpMap: new THREE.Texture( <Image> ),
32148  *  bumpScale: <float>,
32149  *
32150  *  normalMap: new THREE.Texture( <Image> ),
32151  *  normalScale: <Vector2>,
32152  *
32153  *  specularMap: new THREE.Texture( <Image> ),
32154  *
32155  *  envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
32156  *  combine: THREE.Multiply,
32157  *  reflectivity: <float>,
32158  *  refractionRatio: <float>,
32159  *
32160  *  shading: THREE.SmoothShading,
32161  *  blending: THREE.NormalBlending,
32162  *  depthTest: <bool>,
32163  *
32164  *  wireframe: <boolean>,
32165  *  wireframeLinewidth: <float>,
32166  *
32167  *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
32168  *
32169  *  skinning: <bool>,
32170  *  morphTargets: <bool>,
32171  *  morphNormals: <bool>,
32172  *
32173  *    fog: <bool>
32174  * }
32175  */
32176
32177 THREE.MeshPhongMaterial = function ( parameters ) {
32178
32179     THREE.Material.call( this );
32180
32181     this.color = new THREE.Color( 0xffffff ); // diffuse
32182     this.ambient = new THREE.Color( 0xffffff );
32183     this.emissive = new THREE.Color( 0x000000 );
32184     this.specular = new THREE.Color( 0x111111 );
32185     this.shininess = 30;
32186
32187     this.metal = false;
32188     this.perPixel = false;
32189
32190     this.wrapAround = false;
32191     this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
32192
32193     this.map = null;
32194
32195     this.lightMap = null;
32196
32197     this.bumpMap = null;
32198     this.bumpScale = 1;
32199
32200     this.normalMap = null;
32201     this.normalScale = new THREE.Vector2( 1, 1 );
32202
32203     this.specularMap = null;
32204
32205     this.envMap = null;
32206     this.combine = THREE.MultiplyOperation;
32207     this.reflectivity = 1;
32208     this.refractionRatio = 0.98;
32209
32210     this.fog = true;
32211
32212     this.shading = THREE.SmoothShading;
32213
32214     this.wireframe = false;
32215     this.wireframeLinewidth = 1;
32216     this.wireframeLinecap = 'round';
32217     this.wireframeLinejoin = 'round';
32218
32219     this.vertexColors = THREE.NoColors;
32220
32221     this.skinning = false;
32222     this.morphTargets = false;
32223     this.morphNormals = false;
32224
32225     this.setValues( parameters );
32226
32227 };
32228
32229 THREE.MeshPhongMaterial.prototype = Object.create( THREE.Material.prototype );
32230
32231 THREE.MeshPhongMaterial.prototype.clone = function () {
32232
32233     var material = new THREE.MeshPhongMaterial();
32234
32235     THREE.Material.prototype.clone.call( this, material );
32236
32237     material.color.copy( this.color );
32238     material.ambient.copy( this.ambient );
32239     material.emissive.copy( this.emissive );
32240     material.specular.copy( this.specular );
32241     material.shininess = this.shininess;
32242
32243     material.metal = this.metal;
32244     material.perPixel = this.perPixel;
32245
32246     material.wrapAround = this.wrapAround;
32247     material.wrapRGB.copy( this.wrapRGB );
32248
32249     material.map = this.map;
32250
32251     material.lightMap = this.lightMap;
32252
32253     material.bumpMap = this.bumpMap;
32254     material.bumpScale = this.bumpScale;
32255
32256     material.normalMap = this.normalMap;
32257     material.normalScale.copy( this.normalScale );
32258
32259     material.specularMap = this.specularMap;
32260
32261     material.envMap = this.envMap;
32262     material.combine = this.combine;
32263     material.reflectivity = this.reflectivity;
32264     material.refractionRatio = this.refractionRatio;
32265
32266     material.fog = this.fog;
32267
32268     material.shading = this.shading;
32269
32270     material.wireframe = this.wireframe;
32271     material.wireframeLinewidth = this.wireframeLinewidth;
32272     material.wireframeLinecap = this.wireframeLinecap;
32273     material.wireframeLinejoin = this.wireframeLinejoin;
32274
32275     material.vertexColors = this.vertexColors;
32276
32277     material.skinning = this.skinning;
32278     material.morphTargets = this.morphTargets;
32279     material.morphNormals = this.morphNormals;
32280
32281     return material;
32282
32283 };
32284 /**
32285  * @author mrdoob / http://mrdoob.com/
32286  * @author alteredq / http://alteredqualia.com/
32287  *
32288  * parameters = {
32289  *  opacity: <float>,
32290
32291  *  blending: THREE.NormalBlending,
32292  *  depthTest: <bool>,
32293
32294  *  wireframe: <boolean>,
32295  *  wireframeLinewidth: <float>
32296  * }
32297  */
32298
32299 THREE.MeshDepthMaterial = function ( parameters ) {
32300
32301     THREE.Material.call( this );
32302
32303     this.wireframe = false;
32304     this.wireframeLinewidth = 1;
32305
32306     this.setValues( parameters );
32307
32308 };
32309
32310 THREE.MeshDepthMaterial.prototype = Object.create( THREE.Material.prototype );
32311
32312 THREE.MeshDepthMaterial.prototype.clone = function () {
32313
32314     var material = new THREE.LineBasicMaterial();
32315
32316     THREE.Material.prototype.clone.call( this, material );
32317
32318     material.wireframe = this.wireframe;
32319     material.wireframeLinewidth = this.wireframeLinewidth;
32320
32321     return material;
32322
32323 };
32324 /**
32325  * @author mrdoob / http://mrdoob.com/
32326  *
32327  * parameters = {
32328  *  opacity: <float>,
32329
32330  *  shading: THREE.FlatShading,
32331  *  blending: THREE.NormalBlending,
32332  *  depthTest: <bool>,
32333
32334  *  wireframe: <boolean>,
32335  *  wireframeLinewidth: <float>
32336  * }
32337  */
32338
32339 THREE.MeshNormalMaterial = function ( parameters ) {
32340
32341     THREE.Material.call( this, parameters );
32342
32343     this.shading = THREE.FlatShading;
32344
32345     this.wireframe = false;
32346     this.wireframeLinewidth = 1;
32347
32348     this.setValues( parameters );
32349
32350 };
32351
32352 THREE.MeshNormalMaterial.prototype = Object.create( THREE.Material.prototype );
32353
32354 THREE.MeshNormalMaterial.prototype.clone = function () {
32355
32356     var material = new THREE.MeshNormalMaterial();
32357
32358     THREE.Material.prototype.clone.call( this, material );
32359
32360     material.shading = this.shading;
32361
32362     material.wireframe = this.wireframe;
32363     material.wireframeLinewidth = this.wireframeLinewidth;
32364
32365     return material;
32366
32367 };
32368 /**
32369  * @author mrdoob / http://mrdoob.com/
32370  */
32371
32372 THREE.MeshFaceMaterial = function () {};
32373
32374 THREE.MeshFaceMaterial.prototype.clone = function () {
32375
32376     return new THREE.MeshFaceMaterial();
32377
32378 };
32379 /**
32380  * @author mrdoob / http://mrdoob.com/
32381  * @author alteredq / http://alteredqualia.com/
32382  *
32383  * parameters = {
32384  *  color: <hex>,
32385  *  opacity: <float>,
32386  *  map: new THREE.Texture( <Image> ),
32387  *
32388  *  size: <float>,
32389  *
32390  *  blending: THREE.NormalBlending,
32391  *  depthTest: <bool>,
32392  *
32393  *  vertexColors: <bool>,
32394  *
32395  *  fog: <bool>
32396  * }
32397  */
32398
32399 THREE.ParticleBasicMaterial = function ( parameters ) {
32400
32401     THREE.Material.call( this );
32402
32403     this.color = new THREE.Color( 0xffffff );
32404
32405     this.map = null;
32406
32407     this.size = 1;
32408     this.sizeAttenuation = true;
32409
32410     this.vertexColors = false;
32411
32412     this.fog = true;
32413
32414     this.setValues( parameters );
32415
32416 };
32417
32418 THREE.ParticleBasicMaterial.prototype = Object.create( THREE.Material.prototype );
32419
32420 THREE.ParticleBasicMaterial.prototype.clone = function () {
32421
32422     var material = new THREE.ParticleBasicMaterial();
32423
32424     THREE.Material.prototype.clone.call( this, material );
32425
32426     material.color.copy( this.color );
32427
32428     material.map = this.map;
32429
32430     material.size = this.size;
32431     material.sizeAttenuation = this.sizeAttenuation;
32432
32433     material.vertexColors = this.vertexColors;
32434
32435     material.fog = this.fog;
32436
32437     return material;
32438
32439 };
32440 /**
32441  * @author mrdoob / http://mrdoob.com/
32442  *
32443  * parameters = {
32444  *  color: <hex>,
32445  *  program: <function>,
32446  *  opacity: <float>,
32447  *  blending: THREE.NormalBlending
32448  * }
32449  */
32450
32451 THREE.ParticleCanvasMaterial = function ( parameters ) {
32452
32453     THREE.Material.call( this );
32454
32455     this.color = new THREE.Color( 0xffffff );
32456     this.program = function ( context, color ) {};
32457
32458     this.setValues( parameters );
32459
32460 };
32461
32462 THREE.ParticleCanvasMaterial.prototype = Object.create( THREE.Material.prototype );
32463
32464 THREE.ParticleCanvasMaterial.prototype.clone = function () {
32465
32466     var material = new THREE.ParticleCanvasMaterial();
32467
32468     THREE.Material.prototype.clone.call( this, material );
32469
32470     material.color.copy( this.color );
32471     material.program = this.program;
32472
32473     return material;
32474
32475 };
32476 /**
32477  * @author mrdoob / http://mrdoob.com/
32478  */
32479
32480 THREE.ParticleDOMMaterial = function ( element ) {
32481
32482     this.element = element;
32483
32484 };
32485
32486 THREE.ParticleDOMMaterial.prototype.clone = function(){
32487
32488     return new THREE.ParticleDOMMaterial( this.element );
32489
32490 };
32491 /**
32492  * @author alteredq / http://alteredqualia.com/
32493  *
32494  * parameters = {
32495  *  fragmentShader: <string>,
32496  *  vertexShader: <string>,
32497  *
32498  *  uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } },
32499  *
32500  *  shading: THREE.SmoothShading,
32501  *  blending: THREE.NormalBlending,
32502  *  depthTest: <bool>,
32503  *
32504  *  wireframe: <boolean>,
32505  *  wireframeLinewidth: <float>,
32506  *
32507  *  lights: <bool>,
32508  *
32509  *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
32510  *
32511  *  skinning: <bool>,
32512  *  morphTargets: <bool>,
32513  *  morphNormals: <bool>,
32514  *
32515  *    fog: <bool>
32516  * }
32517  */
32518
32519 THREE.ShaderMaterial = function ( parameters ) {
32520
32521     THREE.Material.call( this );
32522
32523     this.fragmentShader = "void main() {}";
32524     this.vertexShader = "void main() {}";
32525     this.uniforms = {};
32526     this.attributes = null;
32527
32528     this.shading = THREE.SmoothShading;
32529
32530     this.wireframe = false;
32531     this.wireframeLinewidth = 1;
32532
32533     this.fog = false; // set to use scene fog
32534
32535     this.lights = false; // set to use scene lights
32536
32537     this.vertexColors = THREE.NoColors; // set to use "color" attribute stream
32538
32539     this.skinning = false; // set to use skinning attribute streams
32540
32541     this.morphTargets = false; // set to use morph targets
32542     this.morphNormals = false; // set to use morph normals
32543
32544     this.setValues( parameters );
32545
32546 };
32547
32548 THREE.ShaderMaterial.prototype = Object.create( THREE.Material.prototype );
32549
32550 THREE.ShaderMaterial.prototype.clone = function () {
32551
32552     var material = new THREE.ShaderMaterial();
32553
32554     THREE.Material.prototype.clone.call( this, material );
32555
32556     material.fragmentShader = this.fragmentShader;
32557     material.vertexShader = this.vertexShader;
32558     material.uniforms = this.uniforms;
32559     material.attributes = this.attributes;
32560
32561     material.shading = this.shading;
32562
32563     material.wireframe = this.wireframe;
32564     material.wireframeLinewidth = this.wireframeLinewidth;
32565
32566     material.fog = this.fog;
32567
32568     material.lights = this.lights;
32569
32570     material.vertexColors = this.vertexColors;
32571
32572     material.skinning = this.skinning;
32573
32574     material.morphTargets = this.morphTargets;
32575     material.morphNormals = this.morphNormals;
32576
32577     return material;
32578
32579 };
32580 /**
32581  * @author mrdoob / http://mrdoob.com/
32582  * @author alteredq / http://alteredqualia.com/
32583  * @author szimek / https://github.com/szimek/
32584  */
32585
32586 THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
32587
32588     this.id = THREE.TextureCount ++;
32589
32590     this.image = image;
32591
32592     this.mapping = mapping !== undefined ? mapping : new THREE.UVMapping();
32593
32594     this.wrapS = wrapS !== undefined ? wrapS : THREE.ClampToEdgeWrapping;
32595     this.wrapT = wrapT !== undefined ? wrapT : THREE.ClampToEdgeWrapping;
32596
32597     this.magFilter = magFilter !== undefined ? magFilter : THREE.LinearFilter;
32598     this.minFilter = minFilter !== undefined ? minFilter : THREE.LinearMipMapLinearFilter;
32599
32600     this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
32601
32602     this.format = format !== undefined ? format : THREE.RGBAFormat;
32603     this.type = type !== undefined ? type : THREE.UnsignedByteType;
32604
32605     this.offset = new THREE.Vector2( 0, 0 );
32606     this.repeat = new THREE.Vector2( 1, 1 );
32607
32608     this.generateMipmaps = true;
32609     this.premultiplyAlpha = false;
32610     this.flipY = true;
32611
32612     this.needsUpdate = false;
32613     this.onUpdate = null;
32614
32615 };
32616
32617 THREE.Texture.prototype = {
32618
32619     constructor: THREE.Texture,
32620
32621     clone: function () {
32622
32623         var texture = new THREE.Texture();
32624
32625         texture.image = this.image;
32626
32627         texture.mapping = this.mapping;
32628
32629         texture.wrapS = this.wrapS;
32630         texture.wrapT = this.wrapT;
32631
32632         texture.magFilter = this.magFilter;
32633         texture.minFilter = this.minFilter;
32634
32635         texture.anisotropy = this.anisotropy;
32636
32637         texture.format = this.format;
32638         texture.type = this.type;
32639
32640         texture.offset.copy( this.offset );
32641         texture.repeat.copy( this.repeat );
32642
32643         texture.generateMipmaps = this.generateMipmaps;
32644         texture.premultiplyAlpha = this.premultiplyAlpha;
32645         texture.flipY = this.flipY;
32646
32647         return texture;
32648
32649     }
32650
32651 };
32652
32653 THREE.TextureCount = 0;
32654 /**
32655  * @author alteredq / http://alteredqualia.com/
32656  */
32657
32658 THREE.CompressedTexture = function ( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter ) {
32659
32660     THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type );
32661
32662     this.image = { width: width, height: height };
32663     this.mipmaps = mipmaps;
32664
32665 };
32666
32667 THREE.CompressedTexture.prototype = Object.create( THREE.Texture.prototype );
32668
32669 THREE.CompressedTexture.prototype.clone = function () {
32670
32671     var texture = new THREE.CompressedTexture();
32672
32673     texture.image = this.image;
32674     texture.mipmaps = this.mipmaps;
32675
32676     texture.format = this.format;
32677     texture.type = this.type;
32678
32679     texture.mapping = this.mapping;
32680
32681     texture.wrapS = this.wrapS;
32682     texture.wrapT = this.wrapT;
32683
32684     texture.magFilter = this.magFilter;
32685     texture.minFilter = this.minFilter;
32686
32687     texture.anisotropy = this.anisotropy;
32688
32689     texture.offset.copy( this.offset );
32690     texture.repeat.copy( this.repeat );
32691
32692     return texture;
32693
32694 };
32695 /**
32696  * @author alteredq / http://alteredqualia.com/
32697  */
32698
32699 THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter ) {
32700
32701     THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type );
32702
32703     this.image = { data: data, width: width, height: height };
32704
32705 };
32706
32707 THREE.DataTexture.prototype = Object.create( THREE.Texture.prototype );
32708
32709 THREE.DataTexture.prototype.clone = function () {
32710
32711     var clonedTexture = new THREE.DataTexture( this.image.data,  this.image.width, this.image.height, this.format, this.type, this.mapping, this.wrapS, this.wrapT, this.magFilter, this.minFilter );
32712
32713     clonedTexture.offset.copy( this.offset );
32714     clonedTexture.repeat.copy( this.repeat );
32715
32716     return clonedTexture;
32717
32718 };
32719 /**
32720  * @author mrdoob / http://mrdoob.com/
32721  */
32722
32723 THREE.Particle = function ( material ) {
32724
32725     THREE.Object3D.call( this );
32726
32727     this.material = material;
32728
32729 };
32730
32731 THREE.Particle.prototype = Object.create( THREE.Object3D.prototype );
32732 /**
32733  * @author alteredq / http://alteredqualia.com/
32734  */
32735
32736 THREE.ParticleSystem = function ( geometry, material ) {
32737
32738     THREE.Object3D.call( this );
32739
32740     this.geometry = geometry;
32741     this.material = ( material !== undefined ) ? material : new THREE.ParticleBasicMaterial( { color: Math.random() * 0xffffff } );
32742
32743     this.sortParticles = false;
32744
32745     if ( this.geometry ) {
32746
32747         // calc bound radius
32748
32749         if( !this.geometry.boundingSphere ) {
32750
32751             this.geometry.computeBoundingSphere();
32752
32753         }
32754
32755         this.boundRadius = geometry.boundingSphere.radius;
32756
32757     }
32758
32759     this.frustumCulled = false;
32760
32761 };
32762
32763 THREE.ParticleSystem.prototype = Object.create( THREE.Object3D.prototype );
32764 /**
32765  * @author mrdoob / http://mrdoob.com/
32766  */
32767
32768 THREE.Line = function ( geometry, material, type ) {
32769
32770     THREE.Object3D.call( this );
32771
32772     this.geometry = geometry;
32773     this.material = ( material !== undefined ) ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } );
32774     this.type = ( type !== undefined ) ? type : THREE.LineStrip;
32775
32776     if ( this.geometry ) {
32777
32778         if ( ! this.geometry.boundingSphere ) {
32779
32780             this.geometry.computeBoundingSphere();
32781
32782         }
32783
32784     }
32785
32786 };
32787
32788 THREE.LineStrip = 0;
32789 THREE.LinePieces = 1;
32790
32791 THREE.Line.prototype = Object.create( THREE.Object3D.prototype );
32792 /**
32793  * @author mrdoob / http://mrdoob.com/
32794  * @author alteredq / http://alteredqualia.com/
32795  * @author mikael emtinger / http://gomo.se/
32796  */
32797
32798 THREE.Mesh = function ( geometry, material ) {
32799
32800     THREE.Object3D.call( this );
32801
32802     this.geometry = geometry;
32803     this.material = ( material !== undefined ) ? material : new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, wireframe: true } );
32804
32805     if ( this.geometry ) {
32806
32807         // calc bound radius
32808
32809         if ( ! this.geometry.boundingSphere ) {
32810
32811             this.geometry.computeBoundingSphere();
32812
32813         }
32814
32815         this.boundRadius = geometry.boundingSphere.radius;
32816
32817
32818         // setup morph targets
32819
32820         if( this.geometry.morphTargets.length ) {
32821
32822             this.morphTargetBase = -1;
32823             this.morphTargetForcedOrder = [];
32824             this.morphTargetInfluences = [];
32825             this.morphTargetDictionary = {};
32826
32827             for( var m = 0; m < this.geometry.morphTargets.length; m ++ ) {
32828
32829                 this.morphTargetInfluences.push( 0 );
32830                 this.morphTargetDictionary[ this.geometry.morphTargets[ m ].name ] = m;
32831
32832             }
32833
32834         }
32835
32836     }
32837
32838 }
32839
32840 THREE.Mesh.prototype = Object.create( THREE.Object3D.prototype );
32841
32842
32843 /*
32844  * Get Morph Target Index by Name
32845  */
32846
32847 THREE.Mesh.prototype.getMorphTargetIndexByName = function( name ) {
32848
32849     if ( this.morphTargetDictionary[ name ] !== undefined ) {
32850
32851         return this.morphTargetDictionary[ name ];
32852     }
32853
32854     console.log( "THREE.Mesh.getMorphTargetIndexByName: morph target " + name + " does not exist. Returning 0." );
32855     return 0;
32856
32857 }
32858 /**
32859  * @author mikael emtinger / http://gomo.se/
32860  * @author alteredq / http://alteredqualia.com/
32861  */
32862
32863 THREE.Bone = function( belongsToSkin ) {
32864
32865     THREE.Object3D.call( this );
32866
32867     this.skin = belongsToSkin;
32868     this.skinMatrix = new THREE.Matrix4();
32869
32870 };
32871
32872 THREE.Bone.prototype = Object.create( THREE.Object3D.prototype );
32873
32874 THREE.Bone.prototype.update = function( parentSkinMatrix, forceUpdate ) {
32875
32876     // update local
32877
32878     if ( this.matrixAutoUpdate ) {
32879
32880         forceUpdate |= this.updateMatrix();
32881
32882     }
32883
32884     // update skin matrix
32885
32886     if ( forceUpdate || this.matrixWorldNeedsUpdate ) {
32887
32888         if( parentSkinMatrix ) {
32889
32890             this.skinMatrix.multiply( parentSkinMatrix, this.matrix );
32891
32892         } else {
32893
32894             this.skinMatrix.copy( this.matrix );
32895
32896         }
32897
32898         this.matrixWorldNeedsUpdate = false;
32899         forceUpdate = true;
32900
32901     }
32902
32903     // update children
32904
32905     var child, i, l = this.children.length;
32906
32907     for ( i = 0; i < l; i ++ ) {
32908
32909         this.children[ i ].update( this.skinMatrix, forceUpdate );
32910
32911     }
32912
32913 };
32914
32915 /**
32916  * @author mikael emtinger / http://gomo.se/
32917  * @author alteredq / http://alteredqualia.com/
32918  */
32919
32920 THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) {
32921
32922     THREE.Mesh.call( this, geometry, material );
32923
32924     //
32925
32926     this.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;
32927
32928     // init bones
32929
32930     this.identityMatrix = new THREE.Matrix4();
32931
32932     this.bones = [];
32933     this.boneMatrices = [];
32934
32935     var b, bone, gbone, p, q, s;
32936
32937     if ( this.geometry.bones !== undefined ) {
32938
32939         for ( b = 0; b < this.geometry.bones.length; b ++ ) {
32940
32941             gbone = this.geometry.bones[ b ];
32942
32943             p = gbone.pos;
32944             q = gbone.rotq;
32945             s = gbone.scl;
32946
32947             bone = this.addBone();
32948
32949             bone.name = gbone.name;
32950             bone.position.set( p[0], p[1], p[2] );
32951             bone.quaternion.set( q[0], q[1], q[2], q[3] );
32952             bone.useQuaternion = true;
32953
32954             if ( s !== undefined ) {
32955
32956                 bone.scale.set( s[0], s[1], s[2] );
32957
32958             } else {
32959
32960                 bone.scale.set( 1, 1, 1 );
32961
32962             }
32963
32964         }
32965
32966         for ( b = 0; b < this.bones.length; b ++ ) {
32967
32968             gbone = this.geometry.bones[ b ];
32969             bone = this.bones[ b ];
32970
32971             if ( gbone.parent === -1 ) {
32972
32973                 this.add( bone );
32974
32975             } else {
32976
32977                 this.bones[ gbone.parent ].add( bone );
32978
32979             }
32980
32981         }
32982
32983         //
32984
32985         var nBones = this.bones.length;
32986
32987         if ( this.useVertexTexture ) {
32988
32989             // layout (1 matrix = 4 pixels)
32990             //    RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
32991             //  with  8x8  pixel texture max   16 bones  (8 * 8  / 4)
32992             //       16x16 pixel texture max   64 bones (16 * 16 / 4)
32993             //       32x32 pixel texture max  256 bones (32 * 32 / 4)
32994             //       64x64 pixel texture max 1024 bones (64 * 64 / 4)
32995
32996             var size;
32997
32998             if ( nBones > 256 )
32999                 size = 64;
33000             else if ( nBones > 64 )
33001                 size = 32;
33002             else if ( nBones > 16 )
33003                 size = 16;
33004             else
33005                 size = 8;
33006
33007             this.boneTextureWidth = size;
33008             this.boneTextureHeight = size;
33009
33010             this.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel
33011             this.boneTexture = new THREE.DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, THREE.RGBAFormat, THREE.FloatType );
33012             this.boneTexture.minFilter = THREE.NearestFilter;
33013             this.boneTexture.magFilter = THREE.NearestFilter;
33014             this.boneTexture.generateMipmaps = false;
33015             this.boneTexture.flipY = false;
33016
33017         } else {
33018
33019             this.boneMatrices = new Float32Array( 16 * nBones );
33020
33021         }
33022
33023         this.pose();
33024
33025     }
33026
33027 };
33028
33029 THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype );
33030
33031 THREE.SkinnedMesh.prototype.addBone = function( bone ) {
33032
33033     if ( bone === undefined ) {
33034
33035         bone = new THREE.Bone( this );
33036
33037     }
33038
33039     this.bones.push( bone );
33040
33041     return bone;
33042
33043 };
33044
33045 THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) {
33046
33047     this.matrixAutoUpdate && this.updateMatrix();
33048
33049     // update matrixWorld
33050
33051     if ( this.matrixWorldNeedsUpdate || force ) {
33052
33053         if ( this.parent ) {
33054
33055             this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
33056
33057         } else {
33058
33059             this.matrixWorld.copy( this.matrix );
33060
33061         }
33062
33063         this.matrixWorldNeedsUpdate = false;
33064
33065         force = true;
33066
33067     }
33068
33069     // update children
33070
33071     for ( var i = 0, l = this.children.length; i < l; i ++ ) {
33072
33073         var child = this.children[ i ];
33074
33075         if ( child instanceof THREE.Bone ) {
33076
33077             child.update( this.identityMatrix, false );
33078
33079         } else {
33080
33081             child.updateMatrixWorld( true );
33082
33083         }
33084
33085     }
33086
33087     // make a snapshot of the bones' rest position
33088
33089     if ( this.boneInverses == undefined ) {
33090
33091         this.boneInverses = [];
33092
33093         for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
33094
33095             var inverse = new THREE.Matrix4();
33096
33097             inverse.getInverse( this.bones[ b ].skinMatrix );
33098
33099             this.boneInverses.push( inverse );
33100
33101         }
33102
33103     }
33104
33105     // flatten bone matrices to array
33106
33107     for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
33108
33109         // compute the offset between the current and the original transform;
33110
33111         //TODO: we could get rid of this multiplication step if the skinMatrix
33112         // was already representing the offset; however, this requires some
33113         // major changes to the animation system
33114
33115         THREE.SkinnedMesh.offsetMatrix.multiply( this.bones[ b ].skinMatrix, this.boneInverses[ b ] );
33116
33117         THREE.SkinnedMesh.offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
33118
33119     }
33120
33121     if ( this.useVertexTexture ) {
33122
33123         this.boneTexture.needsUpdate = true;
33124
33125     }
33126
33127 };
33128
33129 /*
33130  * Pose
33131  */
33132
33133 THREE.SkinnedMesh.prototype.pose = function() {
33134
33135     this.updateMatrixWorld( true );
33136
33137     for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
33138
33139         // normalize weights
33140
33141         var sw = this.geometry.skinWeights[ i ];
33142
33143         var scale = 1.0 / sw.lengthManhattan();
33144
33145         if ( scale !== Infinity ) {
33146
33147             sw.multiplyScalar( scale );
33148
33149         } else {
33150
33151             sw.set( 1 ); // this will be normalized by the shader anyway
33152
33153         }
33154
33155     }
33156
33157 };
33158
33159 THREE.SkinnedMesh.offsetMatrix = new THREE.Matrix4();
33160
33161 /**
33162  * @author alteredq / http://alteredqualia.com/
33163  */
33164
33165 THREE.MorphAnimMesh = function ( geometry, material ) {
33166
33167     THREE.Mesh.call( this, geometry, material );
33168
33169     // API
33170
33171     this.duration = 1000; // milliseconds
33172     this.mirroredLoop = false;
33173     this.time = 0;
33174
33175     // internals
33176
33177     this.lastKeyframe = 0;
33178     this.currentKeyframe = 0;
33179
33180     this.direction = 1;
33181     this.directionBackwards = false;
33182
33183     this.setFrameRange( 0, this.geometry.morphTargets.length - 1 );
33184
33185 };
33186
33187 THREE.MorphAnimMesh.prototype = Object.create( THREE.Mesh.prototype );
33188
33189 THREE.MorphAnimMesh.prototype.setFrameRange = function ( start, end ) {
33190
33191     this.startKeyframe = start;
33192     this.endKeyframe = end;
33193
33194     this.length = this.endKeyframe - this.startKeyframe + 1;
33195
33196 };
33197
33198 THREE.MorphAnimMesh.prototype.setDirectionForward = function () {
33199
33200     this.direction = 1;
33201     this.directionBackwards = false;
33202
33203 };
33204
33205 THREE.MorphAnimMesh.prototype.setDirectionBackward = function () {
33206
33207     this.direction = -1;
33208     this.directionBackwards = true;
33209
33210 };
33211
33212 THREE.MorphAnimMesh.prototype.parseAnimations = function () {
33213
33214     var geometry = this.geometry;
33215
33216     if ( ! geometry.animations ) geometry.animations = {};
33217
33218     var firstAnimation, animations = geometry.animations;
33219
33220     var pattern = /([a-z]+)(\d+)/;
33221
33222     for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
33223
33224         var morph = geometry.morphTargets[ i ];
33225         var parts = morph.name.match( pattern );
33226
33227         if ( parts && parts.length > 1 ) {
33228
33229             var label = parts[ 1 ];
33230             var num = parts[ 2 ];
33231
33232             if ( ! animations[ label ] ) animations[ label ] = { start: Infinity, end: -Infinity };
33233
33234             var animation = animations[ label ];
33235
33236             if ( i < animation.start ) animation.start = i;
33237             if ( i > animation.end ) animation.end = i;
33238
33239             if ( ! firstAnimation ) firstAnimation = label;
33240
33241         }
33242
33243     }
33244
33245     geometry.firstAnimation = firstAnimation;
33246
33247 };
33248
33249 THREE.MorphAnimMesh.prototype.setAnimationLabel = function ( label, start, end ) {
33250
33251     if ( ! this.geometry.animations ) this.geometry.animations = {};
33252
33253     this.geometry.animations[ label ] = { start: start, end: end };
33254
33255 };
33256
33257 THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) {
33258
33259     var animation = this.geometry.animations[ label ];
33260
33261     if ( animation ) {
33262
33263         this.setFrameRange( animation.start, animation.end );
33264         this.duration = 1000 * ( ( animation.end - animation.start ) / fps );
33265         this.time = 0;
33266
33267     } else {
33268
33269         console.warn( "animation[" + label + "] undefined" );
33270
33271     }
33272
33273 };
33274
33275 THREE.MorphAnimMesh.prototype.updateAnimation = function ( delta ) {
33276
33277     var frameTime = this.duration / this.length;
33278
33279     this.time += this.direction * delta;
33280
33281     if ( this.mirroredLoop ) {
33282
33283         if ( this.time > this.duration || this.time < 0 ) {
33284
33285             this.direction *= -1;
33286
33287             if ( this.time > this.duration ) {
33288
33289                 this.time = this.duration;
33290                 this.directionBackwards = true;
33291
33292             }
33293
33294             if ( this.time < 0 ) {
33295
33296                 this.time = 0;
33297                 this.directionBackwards = false;
33298
33299             }
33300
33301         }
33302
33303     } else {
33304
33305         this.time = this.time % this.duration;
33306
33307         if ( this.time < 0 ) this.time += this.duration;
33308
33309     }
33310
33311     var keyframe = this.startKeyframe + THREE.Math.clamp( Math.floor( this.time / frameTime ), 0, this.length - 1 );
33312
33313     if ( keyframe !== this.currentKeyframe ) {
33314
33315         this.morphTargetInfluences[ this.lastKeyframe ] = 0;
33316         this.morphTargetInfluences[ this.currentKeyframe ] = 1;
33317
33318         this.morphTargetInfluences[ keyframe ] = 0;
33319
33320         this.lastKeyframe = this.currentKeyframe;
33321         this.currentKeyframe = keyframe;
33322
33323     }
33324
33325     var mix = ( this.time % frameTime ) / frameTime;
33326
33327     if ( this.directionBackwards ) {
33328
33329         mix = 1 - mix;
33330
33331     }
33332
33333     this.morphTargetInfluences[ this.currentKeyframe ] = mix;
33334     this.morphTargetInfluences[ this.lastKeyframe ] = 1 - mix;
33335
33336 };
33337 /**
33338  * @author alteredq / http://alteredqualia.com/
33339  */
33340
33341 THREE.Ribbon = function ( geometry, material ) {
33342
33343     THREE.Object3D.call( this );
33344
33345     this.geometry = geometry;
33346     this.material = material;
33347
33348 };
33349
33350 THREE.Ribbon.prototype = Object.create( THREE.Object3D.prototype );
33351 /**
33352  * @author mikael emtinger / http://gomo.se/
33353  * @author alteredq / http://alteredqualia.com/
33354  * @author mrdoob / http://mrdoob.com/
33355  */
33356
33357 THREE.LOD = function () {
33358
33359     THREE.Object3D.call( this );
33360
33361     this.LODs = [];
33362
33363 };
33364
33365
33366 THREE.LOD.prototype = Object.create( THREE.Object3D.prototype );
33367
33368 THREE.LOD.prototype.addLevel = function ( object3D, visibleAtDistance ) {
33369
33370     if ( visibleAtDistance === undefined ) {
33371
33372         visibleAtDistance = 0;
33373
33374     }
33375
33376     visibleAtDistance = Math.abs( visibleAtDistance );
33377
33378     for ( var l = 0; l < this.LODs.length; l ++ ) {
33379
33380         if ( visibleAtDistance < this.LODs[ l ].visibleAtDistance ) {
33381
33382             break;
33383
33384         }
33385
33386     }
33387
33388     this.LODs.splice( l, 0, { visibleAtDistance: visibleAtDistance, object3D: object3D } );
33389     this.add( object3D );
33390
33391 };
33392
33393 THREE.LOD.prototype.update = function ( camera ) {
33394
33395     if ( this.LODs.length > 1 ) {
33396
33397         camera.matrixWorldInverse.getInverse( camera.matrixWorld );
33398
33399         var inverse  = camera.matrixWorldInverse;
33400         var distance = -( inverse.elements[2] * this.matrixWorld.elements[12] + inverse.elements[6] * this.matrixWorld.elements[13] + inverse.elements[10] * this.matrixWorld.elements[14] + inverse.elements[14] );
33401
33402         this.LODs[ 0 ].object3D.visible = true;
33403
33404         for ( var l = 1; l < this.LODs.length; l ++ ) {
33405
33406             if( distance >= this.LODs[ l ].visibleAtDistance ) {
33407
33408                 this.LODs[ l - 1 ].object3D.visible = false;
33409                 this.LODs[ l     ].object3D.visible = true;
33410
33411             } else {
33412
33413                 break;
33414
33415             }
33416
33417         }
33418
33419         for( ; l < this.LODs.length; l ++ ) {
33420
33421             this.LODs[ l ].object3D.visible = false;
33422
33423         }
33424
33425     }
33426
33427 };
33428 /**
33429  * @author mikael emtinger / http://gomo.se/
33430  */
33431
33432 THREE.Sprite = function ( parameters ) {
33433
33434     THREE.Object3D.call( this );
33435
33436     this.color = ( parameters.color !== undefined ) ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
33437     this.map = ( parameters.map !== undefined ) ? parameters.map : new THREE.Texture();
33438
33439     this.blending = ( parameters.blending !== undefined ) ? parameters.blending : THREE.NormalBlending;
33440
33441     this.blendSrc = parameters.blendSrc !== undefined ? parameters.blendSrc : THREE.SrcAlphaFactor;
33442     this.blendDst = parameters.blendDst !== undefined ? parameters.blendDst : THREE.OneMinusSrcAlphaFactor;
33443     this.blendEquation = parameters.blendEquation !== undefined ? parameters.blendEquation : THREE.AddEquation;
33444
33445     this.useScreenCoordinates = ( parameters.useScreenCoordinates !== undefined ) ? parameters.useScreenCoordinates : true;
33446     this.mergeWith3D = ( parameters.mergeWith3D !== undefined ) ? parameters.mergeWith3D : !this.useScreenCoordinates;
33447     this.affectedByDistance = ( parameters.affectedByDistance !== undefined ) ? parameters.affectedByDistance : !this.useScreenCoordinates;
33448     this.scaleByViewport = ( parameters.scaleByViewport !== undefined ) ? parameters.scaleByViewport : !this.affectedByDistance;
33449     this.alignment = ( parameters.alignment instanceof THREE.Vector2 ) ? parameters.alignment : THREE.SpriteAlignment.center;
33450
33451     this.rotation3d = this.rotation;
33452     this.rotation = 0;
33453     this.opacity = 1;
33454
33455     this.uvOffset = new THREE.Vector2( 0, 0 );
33456     this.uvScale  = new THREE.Vector2( 1, 1 );
33457
33458 };
33459
33460 THREE.Sprite.prototype = Object.create( THREE.Object3D.prototype );
33461
33462 /*
33463  * Custom update matrix
33464  */
33465
33466 THREE.Sprite.prototype.updateMatrix = function () {
33467
33468     this.matrix.setPosition( this.position );
33469
33470     this.rotation3d.set( 0, 0, this.rotation );
33471     this.matrix.setRotationFromEuler( this.rotation3d );
33472
33473     if ( this.scale.x !== 1 || this.scale.y !== 1 ) {
33474
33475         this.matrix.scale( this.scale );
33476         this.boundRadiusScale = Math.max( this.scale.x, this.scale.y );
33477
33478     }
33479
33480     this.matrixWorldNeedsUpdate = true;
33481
33482 };
33483
33484 /*
33485  * Alignment
33486  */
33487
33488 THREE.SpriteAlignment = {};
33489 THREE.SpriteAlignment.topLeft = new THREE.Vector2( 1, -1 );
33490 THREE.SpriteAlignment.topCenter = new THREE.Vector2( 0, -1 );
33491 THREE.SpriteAlignment.topRight = new THREE.Vector2( -1, -1 );
33492 THREE.SpriteAlignment.centerLeft = new THREE.Vector2( 1, 0 );
33493 THREE.SpriteAlignment.center = new THREE.Vector2( 0, 0 );
33494 THREE.SpriteAlignment.centerRight = new THREE.Vector2( -1, 0 );
33495 THREE.SpriteAlignment.bottomLeft = new THREE.Vector2( 1, 1 );
33496 THREE.SpriteAlignment.bottomCenter = new THREE.Vector2( 0, 1 );
33497 THREE.SpriteAlignment.bottomRight = new THREE.Vector2( -1, 1 );
33498 /**
33499  * @author mrdoob / http://mrdoob.com/
33500  */
33501
33502 THREE.Scene = function () {
33503
33504     THREE.Object3D.call( this );
33505
33506     this.fog = null;
33507     this.overrideMaterial = null;
33508
33509     this.matrixAutoUpdate = false;
33510
33511     this.__objects = [];
33512     this.__lights = [];
33513
33514     this.__objectsAdded = [];
33515     this.__objectsRemoved = [];
33516
33517 };
33518
33519 THREE.Scene.prototype = Object.create( THREE.Object3D.prototype );
33520
33521 THREE.Scene.prototype.__addObject = function ( object ) {
33522
33523     if ( object instanceof THREE.Light ) {
33524
33525         if ( this.__lights.indexOf( object ) === - 1 ) {
33526
33527             this.__lights.push( object );
33528
33529         }
33530
33531         if ( object.target && object.target.parent === undefined ) {
33532
33533             this.add( object.target );
33534
33535         }
33536
33537     } else if ( !( object instanceof THREE.Camera || object instanceof THREE.Bone ) ) {
33538
33539         if ( this.__objects.indexOf( object ) === - 1 ) {
33540
33541             this.__objects.push( object );
33542             this.__objectsAdded.push( object );
33543
33544             // check if previously removed
33545
33546             var i = this.__objectsRemoved.indexOf( object );
33547
33548             if ( i !== -1 ) {
33549
33550                 this.__objectsRemoved.splice( i, 1 );
33551
33552             }
33553
33554         }
33555
33556     }
33557
33558     for ( var c = 0; c < object.children.length; c ++ ) {
33559
33560         this.__addObject( object.children[ c ] );
33561
33562     }
33563
33564 };
33565
33566 THREE.Scene.prototype.__removeObject = function ( object ) {
33567
33568     if ( object instanceof THREE.Light ) {
33569
33570         var i = this.__lights.indexOf( object );
33571
33572         if ( i !== -1 ) {
33573
33574             this.__lights.splice( i, 1 );
33575
33576         }
33577
33578     } else if ( !( object instanceof THREE.Camera ) ) {
33579
33580         var i = this.__objects.indexOf( object );
33581
33582         if( i !== -1 ) {
33583
33584             this.__objects.splice( i, 1 );
33585             this.__objectsRemoved.push( object );
33586
33587             // check if previously added
33588
33589             var ai = this.__objectsAdded.indexOf( object );
33590
33591             if ( ai !== -1 ) {
33592
33593                 this.__objectsAdded.splice( ai, 1 );
33594
33595             }
33596
33597         }
33598
33599     }
33600
33601     for ( var c = 0; c < object.children.length; c ++ ) {
33602
33603         this.__removeObject( object.children[ c ] );
33604
33605     }
33606
33607 };
33608 /**
33609  * @author mrdoob / http://mrdoob.com/
33610  * @author alteredq / http://alteredqualia.com/
33611  */
33612
33613 THREE.Fog = function ( hex, near, far ) {
33614
33615     this.color = new THREE.Color( hex );
33616
33617     this.near = ( near !== undefined ) ? near : 1;
33618     this.far = ( far !== undefined ) ? far : 1000;
33619
33620 };
33621 /**
33622  * @author mrdoob / http://mrdoob.com/
33623  * @author alteredq / http://alteredqualia.com/
33624  */
33625
33626 THREE.FogExp2 = function ( hex, density ) {
33627
33628     this.color = new THREE.Color( hex );
33629     this.density = ( density !== undefined ) ? density : 0.00025;
33630
33631 };
33632 /**
33633  * @author mrdoob / http://mrdoob.com/
33634  */
33635
33636 THREE.CanvasRenderer = function ( parameters ) {
33637
33638     console.log( 'THREE.CanvasRenderer', THREE.REVISION );
33639
33640     parameters = parameters || {};
33641
33642     var _this = this,
33643     _renderData, _elements, _lights,
33644     _projector = new THREE.Projector(),
33645
33646     _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
33647
33648     _canvasWidth, _canvasHeight, _canvasWidthHalf, _canvasHeightHalf,
33649     _context = _canvas.getContext( '2d' ),
33650
33651     _clearColor = new THREE.Color( 0x000000 ),
33652     _clearOpacity = 0,
33653
33654     _contextGlobalAlpha = 1,
33655     _contextGlobalCompositeOperation = 0,
33656     _contextStrokeStyle = null,
33657     _contextFillStyle = null,
33658     _contextLineWidth = null,
33659     _contextLineCap = null,
33660     _contextLineJoin = null,
33661
33662     _v1, _v2, _v3, _v4,
33663     _v5 = new THREE.RenderableVertex(),
33664     _v6 = new THREE.RenderableVertex(),
33665
33666     _v1x, _v1y, _v2x, _v2y, _v3x, _v3y,
33667     _v4x, _v4y, _v5x, _v5y, _v6x, _v6y,
33668
33669     _color = new THREE.Color(),
33670     _color1 = new THREE.Color(),
33671     _color2 = new THREE.Color(),
33672     _color3 = new THREE.Color(),
33673     _color4 = new THREE.Color(),
33674
33675     _patterns = {}, _imagedatas = {},
33676
33677     _near, _far,
33678
33679     _image, _uvs,
33680     _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y,
33681
33682     _clipRect = new THREE.Rectangle(),
33683     _clearRect = new THREE.Rectangle(),
33684     _bboxRect = new THREE.Rectangle(),
33685
33686     _enableLighting = false,
33687     _ambientLight = new THREE.Color(),
33688     _directionalLights = new THREE.Color(),
33689     _pointLights = new THREE.Color(),
33690
33691     _pi2 = Math.PI * 2,
33692     _vector3 = new THREE.Vector3(), // Needed for PointLight
33693
33694     _pixelMap, _pixelMapContext, _pixelMapImage, _pixelMapData,
33695     _gradientMap, _gradientMapContext, _gradientMapQuality = 16;
33696
33697     _pixelMap = document.createElement( 'canvas' );
33698     _pixelMap.width = _pixelMap.height = 2;
33699
33700     _pixelMapContext = _pixelMap.getContext( '2d' );
33701     _pixelMapContext.fillStyle = 'rgba(0,0,0,1)';
33702     _pixelMapContext.fillRect( 0, 0, 2, 2 );
33703
33704     _pixelMapImage = _pixelMapContext.getImageData( 0, 0, 2, 2 );
33705     _pixelMapData = _pixelMapImage.data;
33706
33707     _gradientMap = document.createElement( 'canvas' );
33708     _gradientMap.width = _gradientMap.height = _gradientMapQuality;
33709
33710     _gradientMapContext = _gradientMap.getContext( '2d' );
33711     _gradientMapContext.translate( - _gradientMapQuality / 2, - _gradientMapQuality / 2 );
33712     _gradientMapContext.scale( _gradientMapQuality, _gradientMapQuality );
33713
33714     _gradientMapQuality --; // Fix UVs
33715
33716     this.domElement = _canvas;
33717
33718     this.autoClear = true;
33719     this.sortObjects = true;
33720     this.sortElements = true;
33721
33722     this.info = {
33723
33724         render: {
33725
33726             vertices: 0,
33727             faces: 0
33728
33729         }
33730
33731     }
33732
33733     this.setSize = function ( width, height ) {
33734
33735         _canvasWidth = width;
33736         _canvasHeight = height;
33737         _canvasWidthHalf = Math.floor( _canvasWidth / 2 );
33738         _canvasHeightHalf = Math.floor( _canvasHeight / 2 );
33739
33740         _canvas.width = _canvasWidth;
33741         _canvas.height = _canvasHeight;
33742
33743         _clipRect.set( - _canvasWidthHalf, - _canvasHeightHalf, _canvasWidthHalf, _canvasHeightHalf );
33744         _clearRect.set( - _canvasWidthHalf, - _canvasHeightHalf, _canvasWidthHalf, _canvasHeightHalf );
33745
33746         _contextGlobalAlpha = 1;
33747         _contextGlobalCompositeOperation = 0;
33748         _contextStrokeStyle = null;
33749         _contextFillStyle = null;
33750         _contextLineWidth = null;
33751         _contextLineCap = null;
33752         _contextLineJoin = null;
33753
33754     };
33755
33756     this.setClearColor = function ( color, opacity ) {
33757
33758         _clearColor.copy( color );
33759         _clearOpacity = opacity !== undefined ? opacity : 1;
33760
33761         _clearRect.set( - _canvasWidthHalf, - _canvasHeightHalf, _canvasWidthHalf, _canvasHeightHalf );
33762
33763     };
33764
33765     this.setClearColorHex = function ( hex, opacity ) {
33766
33767         _clearColor.setHex( hex );
33768         _clearOpacity = opacity !== undefined ? opacity : 1;
33769
33770         _clearRect.set( - _canvasWidthHalf, - _canvasHeightHalf, _canvasWidthHalf, _canvasHeightHalf );
33771
33772     };
33773
33774     this.getMaxAnisotropy  = function () {
33775
33776         return 0;
33777
33778     };
33779
33780     this.clear = function () {
33781
33782         _context.setTransform( 1, 0, 0, - 1, _canvasWidthHalf, _canvasHeightHalf );
33783
33784         if ( _clearRect.isEmpty() === false ) {
33785
33786             _clearRect.minSelf( _clipRect );
33787             _clearRect.inflate( 2 );
33788
33789             if ( _clearOpacity < 1 ) {
33790
33791                 _context.clearRect( Math.floor( _clearRect.getX() ), Math.floor( _clearRect.getY() ), Math.floor( _clearRect.getWidth() ), Math.floor( _clearRect.getHeight() ) );
33792
33793             }
33794
33795             if ( _clearOpacity > 0 ) {
33796
33797                 setBlending( THREE.NormalBlending );
33798                 setOpacity( 1 );
33799
33800                 setFillStyle( 'rgba(' + Math.floor( _clearColor.r * 255 ) + ',' + Math.floor( _clearColor.g * 255 ) + ',' + Math.floor( _clearColor.b * 255 ) + ',' + _clearOpacity + ')' );
33801
33802                 _context.fillRect( Math.floor( _clearRect.getX() ), Math.floor( _clearRect.getY() ), Math.floor( _clearRect.getWidth() ), Math.floor( _clearRect.getHeight() ) );
33803
33804             }
33805
33806             _clearRect.empty();
33807
33808         }
33809
33810
33811     };
33812
33813     this.render = function ( scene, camera ) {
33814
33815         if ( camera instanceof THREE.Camera === false ) {
33816
33817             console.error( 'THREE.CanvasRenderer.render: camera is not an instance of THREE.Camera.' );
33818             return;
33819
33820         }
33821
33822         var e, el, element, material;
33823
33824         this.autoClear === true ? this.clear() : _context.setTransform( 1, 0, 0, - 1, _canvasWidthHalf, _canvasHeightHalf );
33825
33826         _this.info.render.vertices = 0;
33827         _this.info.render.faces = 0;
33828
33829         _renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements );
33830         _elements = _renderData.elements;
33831         _lights = _renderData.lights;
33832
33833         /* DEBUG
33834         _context.fillStyle = 'rgba( 0, 255, 255, 0.5 )';
33835         _context.fillRect( _clipRect.getX(), _clipRect.getY(), _clipRect.getWidth(), _clipRect.getHeight() );
33836         */
33837
33838         _enableLighting = _lights.length > 0;
33839
33840         if ( _enableLighting === true ) {
33841
33842              calculateLights();
33843
33844         }
33845
33846         for ( e = 0, el = _elements.length; e < el; e++ ) {
33847
33848             element = _elements[ e ];
33849
33850             material = element.material;
33851
33852             if ( material === undefined || material.visible === false ) continue;
33853
33854             _bboxRect.empty();
33855
33856             if ( element instanceof THREE.RenderableParticle ) {
33857
33858                 _v1 = element;
33859                 _v1.x *= _canvasWidthHalf; _v1.y *= _canvasHeightHalf;
33860
33861                 renderParticle( _v1, element, material, scene );
33862
33863             } else if ( element instanceof THREE.RenderableLine ) {
33864
33865                 _v1 = element.v1; _v2 = element.v2;
33866
33867                 _v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf;
33868                 _v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf;
33869
33870                 _bboxRect.addPoint( _v1.positionScreen.x, _v1.positionScreen.y );
33871                 _bboxRect.addPoint( _v2.positionScreen.x, _v2.positionScreen.y );
33872
33873                 if ( _clipRect.intersects( _bboxRect ) === true ) {
33874
33875                     renderLine( _v1, _v2, element, material, scene );
33876
33877                 }
33878
33879
33880             } else if ( element instanceof THREE.RenderableFace3 ) {
33881
33882                 _v1 = element.v1; _v2 = element.v2; _v3 = element.v3;
33883
33884                 _v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf;
33885                 _v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf;
33886                 _v3.positionScreen.x *= _canvasWidthHalf; _v3.positionScreen.y *= _canvasHeightHalf;
33887
33888                 if ( material.overdraw === true ) {
33889
33890                     expand( _v1.positionScreen, _v2.positionScreen );
33891                     expand( _v2.positionScreen, _v3.positionScreen );
33892                     expand( _v3.positionScreen, _v1.positionScreen );
33893
33894                 }
33895
33896                 _bboxRect.add3Points( _v1.positionScreen.x, _v1.positionScreen.y,
33897                               _v2.positionScreen.x, _v2.positionScreen.y,
33898                               _v3.positionScreen.x, _v3.positionScreen.y );
33899
33900                 if ( _clipRect.intersects( _bboxRect ) === true ) {
33901
33902                     renderFace3( _v1, _v2, _v3, 0, 1, 2, element, material, scene );
33903
33904                 }
33905
33906             } else if ( element instanceof THREE.RenderableFace4 ) {
33907
33908                 _v1 = element.v1; _v2 = element.v2; _v3 = element.v3; _v4 = element.v4;
33909
33910                 _v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf;
33911                 _v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf;
33912                 _v3.positionScreen.x *= _canvasWidthHalf; _v3.positionScreen.y *= _canvasHeightHalf;
33913                 _v4.positionScreen.x *= _canvasWidthHalf; _v4.positionScreen.y *= _canvasHeightHalf;
33914
33915                 _v5.positionScreen.copy( _v2.positionScreen );
33916                 _v6.positionScreen.copy( _v4.positionScreen );
33917
33918                 if ( material.overdraw === true ) {
33919
33920                     expand( _v1.positionScreen, _v2.positionScreen );
33921                     expand( _v2.positionScreen, _v4.positionScreen );
33922                     expand( _v4.positionScreen, _v1.positionScreen );
33923
33924                     expand( _v3.positionScreen, _v5.positionScreen );
33925                     expand( _v3.positionScreen, _v6.positionScreen );
33926
33927                 }
33928
33929                 _bboxRect.addPoint( _v1.positionScreen.x, _v1.positionScreen.y );
33930                 _bboxRect.addPoint( _v2.positionScreen.x, _v2.positionScreen.y );
33931                 _bboxRect.addPoint( _v3.positionScreen.x, _v3.positionScreen.y );
33932                 _bboxRect.addPoint( _v4.positionScreen.x, _v4.positionScreen.y );
33933
33934                 if ( _clipRect.intersects( _bboxRect ) === true ) {
33935
33936                     renderFace4( _v1, _v2, _v3, _v4, _v5, _v6, element, material, scene );
33937
33938                 }
33939
33940             }
33941
33942             /* DEBUG
33943             _context.lineWidth = 1;
33944             _context.strokeStyle = 'rgba( 0, 255, 0, 0.5 )';
33945             _context.strokeRect( _bboxRect.getX(), _bboxRect.getY(), _bboxRect.getWidth(), _bboxRect.getHeight() );
33946             */
33947
33948             _clearRect.addRectangle( _bboxRect );
33949
33950
33951         }
33952
33953         /* DEBUG
33954         _context.lineWidth = 1;
33955         _context.strokeStyle = 'rgba( 255, 0, 0, 0.5 )';
33956         _context.strokeRect( _clearRect.getX(), _clearRect.getY(), _clearRect.getWidth(), _clearRect.getHeight() );
33957         */
33958
33959         _context.setTransform( 1, 0, 0, 1, 0, 0 );
33960
33961         //
33962
33963         function calculateLights() {
33964
33965             _ambientLight.setRGB( 0, 0, 0 );
33966             _directionalLights.setRGB( 0, 0, 0 );
33967             _pointLights.setRGB( 0, 0, 0 );
33968
33969             for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
33970
33971                 var light = _lights[ l ];
33972                 var lightColor = light.color;
33973
33974                 if ( light instanceof THREE.AmbientLight ) {
33975
33976                     _ambientLight.r += lightColor.r;
33977                     _ambientLight.g += lightColor.g;
33978                     _ambientLight.b += lightColor.b;
33979
33980                 } else if ( light instanceof THREE.DirectionalLight ) {
33981
33982                     // for particles
33983
33984                     _directionalLights.r += lightColor.r;
33985                     _directionalLights.g += lightColor.g;
33986                     _directionalLights.b += lightColor.b;
33987
33988                 } else if ( light instanceof THREE.PointLight ) {
33989
33990                     // for particles
33991
33992                     _pointLights.r += lightColor.r;
33993                     _pointLights.g += lightColor.g;
33994                     _pointLights.b += lightColor.b;
33995
33996                 }
33997
33998             }
33999
34000         }
34001
34002         function calculateLight( position, normal, color ) {
34003
34004             for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
34005
34006                 var light = _lights[ l ];
34007                 var lightColor = light.color;
34008
34009                 if ( light instanceof THREE.DirectionalLight ) {
34010
34011                     var lightPosition = light.matrixWorld.getPosition().normalize();
34012
34013                     var amount = normal.dot( lightPosition );
34014
34015                     if ( amount <= 0 ) continue;
34016
34017                     amount *= light.intensity;
34018
34019                     color.r += lightColor.r * amount;
34020                     color.g += lightColor.g * amount;
34021                     color.b += lightColor.b * amount;
34022
34023                 } else if ( light instanceof THREE.PointLight ) {
34024
34025                     var lightPosition = light.matrixWorld.getPosition();
34026
34027                     var amount = normal.dot( _vector3.sub( lightPosition, position ).normalize() );
34028
34029                     if ( amount <= 0 ) continue;
34030
34031                     amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
34032
34033                     if ( amount == 0 ) continue;
34034
34035                     amount *= light.intensity;
34036
34037                     color.r += lightColor.r * amount;
34038                     color.g += lightColor.g * amount;
34039                     color.b += lightColor.b * amount;
34040
34041                 }
34042
34043             }
34044
34045         }
34046
34047         function renderParticle( v1, element, material, scene ) {
34048
34049             setOpacity( material.opacity );
34050             setBlending( material.blending );
34051
34052             var width, height, scaleX, scaleY,
34053             bitmap, bitmapWidth, bitmapHeight;
34054
34055             if ( material instanceof THREE.ParticleBasicMaterial ) {
34056
34057                 if ( material.map === null ) {
34058
34059                     scaleX = element.object.scale.x;
34060                     scaleY = element.object.scale.y;
34061
34062                     // TODO: Be able to disable this
34063
34064                     scaleX *= element.scale.x * _canvasWidthHalf;
34065                     scaleY *= element.scale.y * _canvasHeightHalf;
34066
34067                     _bboxRect.set( v1.x - scaleX, v1.y - scaleY, v1.x  + scaleX, v1.y + scaleY );
34068
34069                     if ( _clipRect.intersects( _bboxRect ) === false ) {
34070
34071                         return;
34072
34073                     }
34074
34075                     setFillStyle( material.color.getContextStyle() );
34076
34077                     _context.save();
34078                     _context.translate( v1.x, v1.y );
34079                     _context.rotate( - element.rotation );
34080                     _context.scale( scaleX, scaleY );
34081                     _context.fillRect( -1, -1, 2, 2 );
34082                     _context.restore();
34083
34084                 } else {
34085
34086                     bitmap = material.map.image;
34087                     bitmapWidth = bitmap.width >> 1;
34088                     bitmapHeight = bitmap.height >> 1;
34089
34090                     scaleX = element.scale.x * _canvasWidthHalf;
34091                     scaleY = element.scale.y * _canvasHeightHalf;
34092
34093                     width = scaleX * bitmapWidth;
34094                     height = scaleY * bitmapHeight;
34095
34096                     // TODO: Rotations break this...
34097
34098                     _bboxRect.set( v1.x - width, v1.y - height, v1.x  + width, v1.y + height );
34099
34100                     if ( _clipRect.intersects( _bboxRect ) === false ) {
34101
34102                         return;
34103
34104                     }
34105
34106                     _context.save();
34107                     _context.translate( v1.x, v1.y );
34108                     _context.rotate( - element.rotation );
34109                     _context.scale( scaleX, - scaleY );
34110
34111                     _context.translate( - bitmapWidth, - bitmapHeight );
34112                     _context.drawImage( bitmap, 0, 0 );
34113                     _context.restore();
34114
34115                 }
34116
34117                 /* DEBUG
34118                 setStrokeStyle( 'rgb(255,255,0)' );
34119                 _context.beginPath();
34120                 _context.moveTo( v1.x - 10, v1.y );
34121                 _context.lineTo( v1.x + 10, v1.y );
34122                 _context.moveTo( v1.x, v1.y - 10 );
34123                 _context.lineTo( v1.x, v1.y + 10 );
34124                 _context.stroke();
34125                 */
34126
34127             } else if ( material instanceof THREE.ParticleCanvasMaterial ) {
34128
34129                 width = element.scale.x * _canvasWidthHalf;
34130                 height = element.scale.y * _canvasHeightHalf;
34131
34132                 _bboxRect.set( v1.x - width, v1.y - height, v1.x + width, v1.y + height );
34133
34134                 if ( _clipRect.intersects( _bboxRect ) === false ) {
34135
34136                     return;
34137
34138                 }
34139
34140                 setStrokeStyle( material.color.getContextStyle() );
34141                 setFillStyle( material.color.getContextStyle() );
34142
34143                 _context.save();
34144                 _context.translate( v1.x, v1.y );
34145                 _context.rotate( - element.rotation );
34146                 _context.scale( width, height );
34147
34148                 material.program( _context );
34149
34150                 _context.restore();
34151
34152             }
34153
34154         }
34155
34156         function renderLine( v1, v2, element, material, scene ) {
34157
34158             setOpacity( material.opacity );
34159             setBlending( material.blending );
34160
34161             _context.beginPath();
34162             _context.moveTo( v1.positionScreen.x, v1.positionScreen.y );
34163             _context.lineTo( v2.positionScreen.x, v2.positionScreen.y );
34164
34165             if ( material instanceof THREE.LineBasicMaterial ) {
34166
34167                 setLineWidth( material.linewidth );
34168                 setLineCap( material.linecap );
34169                 setLineJoin( material.linejoin );
34170                 setStrokeStyle( material.color.getContextStyle() );
34171
34172                 _context.stroke();
34173                 _bboxRect.inflate( material.linewidth * 2 );
34174
34175             }
34176
34177         }
34178
34179         function renderFace3( v1, v2, v3, uv1, uv2, uv3, element, material, scene ) {
34180
34181             _this.info.render.vertices += 3;
34182             _this.info.render.faces ++;
34183
34184             setOpacity( material.opacity );
34185             setBlending( material.blending );
34186
34187             _v1x = v1.positionScreen.x; _v1y = v1.positionScreen.y;
34188             _v2x = v2.positionScreen.x; _v2y = v2.positionScreen.y;
34189             _v3x = v3.positionScreen.x; _v3y = v3.positionScreen.y;
34190
34191             drawTriangle( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y );
34192
34193             if ( ( material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) && material.map === null && material.map === null ) {
34194
34195                 if ( _enableLighting === true ) {
34196
34197                     var diffuse = material.color;
34198                     var emissive = material.emissive;
34199
34200                     if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsLength == 3 ) {
34201
34202                         _color1.r = _color2.r = _color3.r = _ambientLight.r;
34203                         _color1.g = _color2.g = _color3.g = _ambientLight.g;
34204                         _color1.b = _color2.b = _color3.b = _ambientLight.b;
34205
34206                         calculateLight( element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
34207                         calculateLight( element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
34208                         calculateLight( element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color3 );
34209
34210                         _color1.r = diffuse.r * _color1.r + emissive.r;
34211                         _color1.g = diffuse.g * _color1.g + emissive.g;
34212                         _color1.b = diffuse.b * _color1.b + emissive.b;
34213
34214                         _color2.r = diffuse.r * _color2.r + emissive.r;
34215                         _color2.g = diffuse.g * _color2.g + emissive.g;
34216                         _color2.b = diffuse.b * _color2.b + emissive.b;
34217
34218                         _color3.r = diffuse.r * _color3.r + emissive.r;
34219                         _color3.g = diffuse.g * _color3.g + emissive.g;
34220                         _color3.b = diffuse.b * _color3.b + emissive.b;
34221
34222                         _color4.r = ( _color2.r + _color3.r ) * 0.5;
34223                         _color4.g = ( _color2.g + _color3.g ) * 0.5;
34224                         _color4.b = ( _color2.b + _color3.b ) * 0.5;
34225
34226                         _image = getGradientTexture( _color1, _color2, _color3, _color4 );
34227
34228                         clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, 0, 0, 1, 0, 0, 1, _image );
34229
34230                     } else {
34231
34232                         _color.r = _ambientLight.r;
34233                         _color.g = _ambientLight.g;
34234                         _color.b = _ambientLight.b;
34235
34236                         calculateLight( element.centroidWorld, element.normalWorld, _color );
34237
34238                         _color.r = diffuse.r * _color.r + emissive.r;
34239                         _color.g = diffuse.g * _color.g + emissive.g;
34240                         _color.b = diffuse.b * _color.b + emissive.b;
34241
34242                         material.wireframe === true ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( _color );
34243
34244                     }
34245
34246                 } else {
34247
34248                     material.wireframe === true ? strokePath( material.color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( material.color );
34249
34250                 }
34251
34252             } else if ( material instanceof THREE.MeshBasicMaterial || material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) {
34253
34254                 if ( material.map !== null ) {
34255
34256                     if ( material.map.mapping instanceof THREE.UVMapping ) {
34257
34258                         _uvs = element.uvs[ 0 ];
34259                         patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uvs[ uv1 ].u, _uvs[ uv1 ].v, _uvs[ uv2 ].u, _uvs[ uv2 ].v, _uvs[ uv3 ].u, _uvs[ uv3 ].v, material.map );
34260
34261                     }
34262
34263
34264                 } else if ( material.envMap !== null ) {
34265
34266                     if ( material.envMap.mapping instanceof THREE.SphericalReflectionMapping ) {
34267
34268                         var cameraMatrix = camera.matrixWorldInverse;
34269
34270                         _vector3.copy( element.vertexNormalsWorld[ uv1 ] );
34271                         _uv1x = ( _vector3.x * cameraMatrix.elements[0] + _vector3.y * cameraMatrix.elements[4] + _vector3.z * cameraMatrix.elements[8] ) * 0.5 + 0.5;
34272                         _uv1y = ( _vector3.x * cameraMatrix.elements[1] + _vector3.y * cameraMatrix.elements[5] + _vector3.z * cameraMatrix.elements[9] ) * 0.5 + 0.5;
34273
34274                         _vector3.copy( element.vertexNormalsWorld[ uv2 ] );
34275                         _uv2x = ( _vector3.x * cameraMatrix.elements[0] + _vector3.y * cameraMatrix.elements[4] + _vector3.z * cameraMatrix.elements[8] ) * 0.5 + 0.5;
34276                         _uv2y = ( _vector3.x * cameraMatrix.elements[1] + _vector3.y * cameraMatrix.elements[5] + _vector3.z * cameraMatrix.elements[9] ) * 0.5 + 0.5;
34277
34278                         _vector3.copy( element.vertexNormalsWorld[ uv3 ] );
34279                         _uv3x = ( _vector3.x * cameraMatrix.elements[0] + _vector3.y * cameraMatrix.elements[4] + _vector3.z * cameraMatrix.elements[8] ) * 0.5 + 0.5;
34280                         _uv3y = ( _vector3.x * cameraMatrix.elements[1] + _vector3.y * cameraMatrix.elements[5] + _vector3.z * cameraMatrix.elements[9] ) * 0.5 + 0.5;
34281
34282                         patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y, material.envMap );
34283
34284                     }/* else if ( material.envMap.mapping == THREE.SphericalRefractionMapping ) {
34285
34286
34287
34288                     }*/
34289
34290
34291                 } else {
34292
34293                     material.wireframe === true ? strokePath( material.color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( material.color );
34294
34295                 }
34296
34297             } else if ( material instanceof THREE.MeshDepthMaterial ) {
34298
34299                 _near = camera.near;
34300                 _far = camera.far;
34301
34302                 _color1.r = _color1.g = _color1.b = 1 - smoothstep( v1.positionScreen.z, _near, _far );
34303                 _color2.r = _color2.g = _color2.b = 1 - smoothstep( v2.positionScreen.z, _near, _far );
34304                 _color3.r = _color3.g = _color3.b = 1 - smoothstep( v3.positionScreen.z, _near, _far );
34305
34306                 _color4.r = ( _color2.r + _color3.r ) * 0.5;
34307                 _color4.g = ( _color2.g + _color3.g ) * 0.5;
34308                 _color4.b = ( _color2.b + _color3.b ) * 0.5;
34309
34310                 _image = getGradientTexture( _color1, _color2, _color3, _color4 );
34311
34312                 clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, 0, 0, 1, 0, 0, 1, _image );
34313
34314             } else if ( material instanceof THREE.MeshNormalMaterial ) {
34315
34316                 _color.r = normalToComponent( element.normalWorld.x );
34317                 _color.g = normalToComponent( element.normalWorld.y );
34318                 _color.b = normalToComponent( element.normalWorld.z );
34319
34320                 material.wireframe === true ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( _color );
34321
34322             }
34323
34324         }
34325
34326         function renderFace4( v1, v2, v3, v4, v5, v6, element, material, scene ) {
34327
34328             _this.info.render.vertices += 4;
34329             _this.info.render.faces ++;
34330
34331             setOpacity( material.opacity );
34332             setBlending( material.blending );
34333
34334             if ( ( material.map !== undefined && material.map !== null ) || ( material.envMap !== undefined && material.envMap !== null ) ) {
34335
34336                 // Let renderFace3() handle this
34337
34338                 renderFace3( v1, v2, v4, 0, 1, 3, element, material, scene );
34339                 renderFace3( v5, v3, v6, 1, 2, 3, element, material, scene );
34340
34341                 return;
34342
34343             }
34344
34345             _v1x = v1.positionScreen.x; _v1y = v1.positionScreen.y;
34346             _v2x = v2.positionScreen.x; _v2y = v2.positionScreen.y;
34347             _v3x = v3.positionScreen.x; _v3y = v3.positionScreen.y;
34348             _v4x = v4.positionScreen.x; _v4y = v4.positionScreen.y;
34349             _v5x = v5.positionScreen.x; _v5y = v5.positionScreen.y;
34350             _v6x = v6.positionScreen.x; _v6y = v6.positionScreen.y;
34351
34352             if ( material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) {
34353
34354                 if ( _enableLighting === true ) {
34355
34356                     var diffuse = material.color;
34357                     var emissive = material.emissive;
34358
34359                     if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsLength == 4 ) {
34360
34361                         _color1.r = _color2.r = _color3.r = _color4.r = _ambientLight.r;
34362                         _color1.g = _color2.g = _color3.g = _color4.g = _ambientLight.g;
34363                         _color1.b = _color2.b = _color3.b = _color4.b = _ambientLight.b;
34364
34365                         calculateLight( element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
34366                         calculateLight( element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
34367                         calculateLight( element.v4.positionWorld, element.vertexNormalsWorld[ 3 ], _color3 );
34368                         calculateLight( element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color4 );
34369
34370                         _color1.r = diffuse.r * _color1.r + emissive.r;
34371                         _color1.g = diffuse.g * _color1.g + emissive.g;
34372                         _color1.b = diffuse.b * _color1.b + emissive.b;
34373
34374                         _color2.r = diffuse.r * _color2.r + emissive.r;
34375                         _color2.g = diffuse.g * _color2.g + emissive.g;
34376                         _color2.b = diffuse.b * _color2.b + emissive.b;
34377
34378                         _color3.r = diffuse.r * _color3.r + emissive.r;
34379                         _color3.g = diffuse.g * _color3.g + emissive.g;
34380                         _color3.b = diffuse.b * _color3.b + emissive.b;
34381
34382                         _color4.r = diffuse.r * _color4.r + emissive.r;
34383                         _color4.g = diffuse.g * _color4.g + emissive.g;
34384                         _color4.b = diffuse.b * _color4.b + emissive.b;
34385
34386                         _image = getGradientTexture( _color1, _color2, _color3, _color4 );
34387
34388                         // TODO: UVs are incorrect, v4->v3?
34389
34390                         drawTriangle( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y );
34391                         clipImage( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y, 0, 0, 1, 0, 0, 1, _image );
34392
34393                         drawTriangle( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y );
34394                         clipImage( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y, 1, 0, 1, 1, 0, 1, _image );
34395
34396                     } else {
34397
34398                         _color.r = _ambientLight.r;
34399                         _color.g = _ambientLight.g;
34400                         _color.b = _ambientLight.b;
34401
34402                         calculateLight( element.centroidWorld, element.normalWorld, _color );
34403
34404                         _color.r = diffuse.r * _color.r + emissive.r;
34405                         _color.g = diffuse.g * _color.g + emissive.g;
34406                         _color.b = diffuse.b * _color.b + emissive.b;
34407
34408                         drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
34409
34410                         material.wireframe === true ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( _color );
34411
34412                     }
34413
34414                 } else {
34415
34416                     drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
34417
34418                     material.wireframe === true ? strokePath( material.color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( material.color );
34419
34420                 }
34421
34422             } else if ( material instanceof THREE.MeshBasicMaterial ) {
34423
34424                 drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
34425
34426                 material.wireframe === true ? strokePath( material.color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( material.color );
34427
34428             } else if ( material instanceof THREE.MeshNormalMaterial ) {
34429
34430                 _color.r = normalToComponent( element.normalWorld.x );
34431                 _color.g = normalToComponent( element.normalWorld.y );
34432                 _color.b = normalToComponent( element.normalWorld.z );
34433
34434                 drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
34435
34436                 material.wireframe === true ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( _color );
34437
34438             } else if ( material instanceof THREE.MeshDepthMaterial ) {
34439
34440                 _near = camera.near;
34441                 _far = camera.far;
34442
34443                 _color1.r = _color1.g = _color1.b = 1 - smoothstep( v1.positionScreen.z, _near, _far );
34444                 _color2.r = _color2.g = _color2.b = 1 - smoothstep( v2.positionScreen.z, _near, _far );
34445                 _color3.r = _color3.g = _color3.b = 1 - smoothstep( v4.positionScreen.z, _near, _far );
34446                 _color4.r = _color4.g = _color4.b = 1 - smoothstep( v3.positionScreen.z, _near, _far );
34447
34448                 _image = getGradientTexture( _color1, _color2, _color3, _color4 );
34449
34450                 // TODO: UVs are incorrect, v4->v3?
34451
34452                 drawTriangle( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y );
34453                 clipImage( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y, 0, 0, 1, 0, 0, 1, _image );
34454
34455                 drawTriangle( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y );
34456                 clipImage( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y, 1, 0, 1, 1, 0, 1, _image );
34457
34458             }
34459
34460         }
34461
34462         //
34463
34464         function drawTriangle( x0, y0, x1, y1, x2, y2 ) {
34465
34466             _context.beginPath();
34467             _context.moveTo( x0, y0 );
34468             _context.lineTo( x1, y1 );
34469             _context.lineTo( x2, y2 );
34470             _context.closePath();
34471
34472         }
34473
34474         function drawQuad( x0, y0, x1, y1, x2, y2, x3, y3 ) {
34475
34476             _context.beginPath();
34477             _context.moveTo( x0, y0 );
34478             _context.lineTo( x1, y1 );
34479             _context.lineTo( x2, y2 );
34480             _context.lineTo( x3, y3 );
34481             _context.closePath();
34482
34483         }
34484
34485         function strokePath( color, linewidth, linecap, linejoin ) {
34486
34487             setLineWidth( linewidth );
34488             setLineCap( linecap );
34489             setLineJoin( linejoin );
34490             setStrokeStyle( color.getContextStyle() );
34491
34492             _context.stroke();
34493
34494             _bboxRect.inflate( linewidth * 2 );
34495
34496         }
34497
34498         function fillPath( color ) {
34499
34500             setFillStyle( color.getContextStyle() );
34501             _context.fill();
34502
34503         }
34504
34505         function patternPath( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, texture ) {
34506
34507             if ( texture instanceof THREE.DataTexture || texture.image === undefined || texture.image.width == 0 ) return;
34508
34509             if ( texture.needsUpdate === true ) {
34510
34511                 var repeatX = texture.wrapS == THREE.RepeatWrapping;
34512                 var repeatY = texture.wrapT == THREE.RepeatWrapping;
34513
34514                 _patterns[ texture.id ] = _context.createPattern(
34515                     texture.image, repeatX === true && repeatY === true
34516                         ? 'repeat'
34517                         : repeatX === true && repeatY === false
34518                             ? 'repeat-x'
34519                             : repeatX === false && repeatY === true
34520                                 ? 'repeat-y'
34521                                 : 'no-repeat'
34522                 );
34523
34524                 texture.needsUpdate = false;
34525
34526             }
34527
34528             _patterns[ texture.id ] === undefined
34529                 ? setFillStyle( 'rgba(0,0,0,1)' )
34530                 : setFillStyle( _patterns[ texture.id ] );
34531
34532             // http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
34533
34534             var a, b, c, d, e, f, det, idet,
34535             offsetX = texture.offset.x / texture.repeat.x,
34536             offsetY = texture.offset.y / texture.repeat.y,
34537             width = texture.image.width * texture.repeat.x,
34538             height = texture.image.height * texture.repeat.y;
34539
34540             u0 = ( u0 + offsetX ) * width;
34541             v0 = ( 1.0 - v0 + offsetY ) * height;
34542
34543             u1 = ( u1 + offsetX ) * width;
34544             v1 = ( 1.0 - v1 + offsetY ) * height;
34545
34546             u2 = ( u2 + offsetX ) * width;
34547             v2 = ( 1.0 - v2 + offsetY ) * height;
34548
34549             x1 -= x0; y1 -= y0;
34550             x2 -= x0; y2 -= y0;
34551
34552             u1 -= u0; v1 -= v0;
34553             u2 -= u0; v2 -= v0;
34554
34555             det = u1 * v2 - u2 * v1;
34556
34557             if ( det === 0 ) {
34558
34559                 if ( _imagedatas[ texture.id ] === undefined ) {
34560
34561                     var canvas = document.createElement( 'canvas' )
34562                     canvas.width = texture.image.width;
34563                     canvas.height = texture.image.height;
34564
34565                     var context = canvas.getContext( '2d' );
34566                     context.drawImage( texture.image, 0, 0 );
34567
34568                     _imagedatas[ texture.id ] = context.getImageData( 0, 0, texture.image.width, texture.image.height ).data;
34569
34570                 }
34571
34572                 var data = _imagedatas[ texture.id ];
34573                 var index = ( Math.floor( u0 ) + Math.floor( v0 ) * texture.image.width ) * 4;
34574
34575                 _color.setRGB( data[ index ] / 255, data[ index + 1 ] / 255, data[ index + 2 ] / 255 );
34576                 fillPath( _color );
34577
34578                 return;
34579
34580             }
34581
34582             idet = 1 / det;
34583
34584             a = ( v2 * x1 - v1 * x2 ) * idet;
34585             b = ( v2 * y1 - v1 * y2 ) * idet;
34586             c = ( u1 * x2 - u2 * x1 ) * idet;
34587             d = ( u1 * y2 - u2 * y1 ) * idet;
34588
34589             e = x0 - a * u0 - c * v0;
34590             f = y0 - b * u0 - d * v0;
34591
34592             _context.save();
34593             _context.transform( a, b, c, d, e, f );
34594             _context.fill();
34595             _context.restore();
34596
34597         }
34598
34599         function clipImage( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, image ) {
34600
34601             // http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
34602
34603             var a, b, c, d, e, f, det, idet,
34604             width = image.width - 1,
34605             height = image.height - 1;
34606
34607             u0 *= width; v0 *= height;
34608             u1 *= width; v1 *= height;
34609             u2 *= width; v2 *= height;
34610
34611             x1 -= x0; y1 -= y0;
34612             x2 -= x0; y2 -= y0;
34613
34614             u1 -= u0; v1 -= v0;
34615             u2 -= u0; v2 -= v0;
34616
34617             det = u1 * v2 - u2 * v1;
34618
34619             idet = 1 / det;
34620
34621             a = ( v2 * x1 - v1 * x2 ) * idet;
34622             b = ( v2 * y1 - v1 * y2 ) * idet;
34623             c = ( u1 * x2 - u2 * x1 ) * idet;
34624             d = ( u1 * y2 - u2 * y1 ) * idet;
34625
34626             e = x0 - a * u0 - c * v0;
34627             f = y0 - b * u0 - d * v0;
34628
34629             _context.save();
34630             _context.transform( a, b, c, d, e, f );
34631             _context.clip();
34632             _context.drawImage( image, 0, 0 );
34633             _context.restore();
34634
34635         }
34636
34637         function getGradientTexture( color1, color2, color3, color4 ) {
34638
34639             // http://mrdoob.com/blog/post/710
34640
34641             _pixelMapData[ 0 ] = ( color1.r * 255 ) | 0;
34642             _pixelMapData[ 1 ] = ( color1.g * 255 ) | 0;
34643             _pixelMapData[ 2 ] = ( color1.b * 255 ) | 0;
34644
34645             _pixelMapData[ 4 ] = ( color2.r * 255 ) | 0;
34646             _pixelMapData[ 5 ] = ( color2.g * 255 ) | 0;
34647             _pixelMapData[ 6 ] = ( color2.b * 255 ) | 0;
34648
34649             _pixelMapData[ 8 ] = ( color3.r * 255 ) | 0;
34650             _pixelMapData[ 9 ] = ( color3.g * 255 ) | 0;
34651             _pixelMapData[ 10 ] = ( color3.b * 255 ) | 0;
34652
34653             _pixelMapData[ 12 ] = ( color4.r * 255 ) | 0;
34654             _pixelMapData[ 13 ] = ( color4.g * 255 ) | 0;
34655             _pixelMapData[ 14 ] = ( color4.b * 255 ) | 0;
34656
34657             _pixelMapContext.putImageData( _pixelMapImage, 0, 0 );
34658             _gradientMapContext.drawImage( _pixelMap, 0, 0 );
34659
34660             return _gradientMap;
34661
34662         }
34663
34664         function smoothstep( value, min, max ) {
34665
34666             var x = ( value - min ) / ( max - min );
34667             return x * x * ( 3 - 2 * x );
34668
34669         }
34670
34671         function normalToComponent( normal ) {
34672
34673             var component = ( normal + 1 ) * 0.5;
34674             return component < 0 ? 0 : ( component > 1 ? 1 : component );
34675
34676         }
34677
34678         // Hide anti-alias gaps
34679
34680         function expand( v1, v2 ) {
34681
34682             var x = v2.x - v1.x, y =  v2.y - v1.y,
34683             det = x * x + y * y, idet;
34684
34685             if ( det === 0 ) return;
34686
34687             idet = 1 / Math.sqrt( det );
34688
34689             x *= idet; y *= idet;
34690
34691             v2.x += x; v2.y += y;
34692             v1.x -= x; v1.y -= y;
34693
34694         }
34695     };
34696
34697     // Context cached methods.
34698
34699     function setOpacity( value ) {
34700
34701         if ( _contextGlobalAlpha !== value ) {
34702
34703             _context.globalAlpha = value;
34704             _contextGlobalAlpha = value;
34705
34706         }
34707
34708     }
34709
34710     function setBlending( value ) {
34711
34712         if ( _contextGlobalCompositeOperation !== value ) {
34713
34714             if ( value === THREE.NormalBlending ) {
34715
34716                 _context.globalCompositeOperation = 'source-over';
34717
34718             } else if ( value === THREE.AdditiveBlending ) {
34719
34720                 _context.globalCompositeOperation = 'lighter';
34721
34722             } else if ( value === THREE.SubtractiveBlending ) {
34723
34724                 _context.globalCompositeOperation = 'darker';
34725
34726             }
34727
34728             _contextGlobalCompositeOperation = value;
34729
34730         }
34731
34732     }
34733
34734     function setLineWidth( value ) {
34735
34736         if ( _contextLineWidth !== value ) {
34737
34738             _context.lineWidth = value;
34739             _contextLineWidth = value;
34740
34741         }
34742
34743     }
34744
34745     function setLineCap( value ) {
34746
34747         // "butt", "round", "square"
34748
34749         if ( _contextLineCap !== value ) {
34750
34751             _context.lineCap = value;
34752             _contextLineCap = value;
34753
34754         }
34755
34756     }
34757
34758     function setLineJoin( value ) {
34759
34760         // "round", "bevel", "miter"
34761
34762         if ( _contextLineJoin !== value ) {
34763
34764             _context.lineJoin = value;
34765             _contextLineJoin = value;
34766
34767         }
34768
34769     }
34770
34771     function setStrokeStyle( value ) {
34772
34773         if ( _contextStrokeStyle !== value ) {
34774
34775             _context.strokeStyle = value;
34776             _contextStrokeStyle = value;
34777
34778         }
34779
34780     }
34781
34782     function setFillStyle( value ) {
34783
34784         if ( _contextFillStyle !== value ) {
34785
34786             _context.fillStyle = value;
34787             _contextFillStyle = value;
34788
34789         }
34790
34791     }
34792
34793 };
34794 /**
34795  * @author alteredq / http://alteredqualia.com/
34796  * @author mrdoob / http://mrdoob.com/
34797  * @author mikael emtinger / http://gomo.se/
34798  */
34799
34800 THREE.ShaderChunk = {
34801
34802     // FOG
34803
34804     fog_pars_fragment: [
34805
34806         "#ifdef USE_FOG",
34807
34808             "uniform vec3 fogColor;",
34809
34810             "#ifdef FOG_EXP2",
34811
34812                 "uniform float fogDensity;",
34813
34814             "#else",
34815
34816                 "uniform float fogNear;",
34817                 "uniform float fogFar;",
34818
34819             "#endif",
34820
34821         "#endif"
34822
34823     ].join("\n"),
34824
34825     fog_fragment: [
34826
34827         "#ifdef USE_FOG",
34828
34829             "float depth = gl_FragCoord.z / gl_FragCoord.w;",
34830
34831             "#ifdef FOG_EXP2",
34832
34833                 "const float LOG2 = 1.442695;",
34834                 "float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );",
34835                 "fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );",
34836
34837             "#else",
34838
34839                 "float fogFactor = smoothstep( fogNear, fogFar, depth );",
34840
34841             "#endif",
34842
34843             "gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );",
34844
34845         "#endif"
34846
34847     ].join("\n"),
34848
34849     // ENVIRONMENT MAP
34850
34851     envmap_pars_fragment: [
34852
34853         "#ifdef USE_ENVMAP",
34854
34855             "uniform float reflectivity;",
34856             "uniform samplerCube envMap;",
34857             "uniform float flipEnvMap;",
34858             "uniform int combine;",
34859
34860             "#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )",
34861
34862                 "uniform bool useRefract;",
34863                 "uniform float refractionRatio;",
34864
34865             "#else",
34866
34867                 "varying vec3 vReflect;",
34868
34869             "#endif",
34870
34871         "#endif"
34872
34873     ].join("\n"),
34874
34875     envmap_fragment: [
34876
34877         "#ifdef USE_ENVMAP",
34878
34879             "vec3 reflectVec;",
34880
34881             "#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )",
34882
34883                 "vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",
34884
34885                 "if ( useRefract ) {",
34886
34887                     "reflectVec = refract( cameraToVertex, normal, refractionRatio );",
34888
34889                 "} else { ",
34890
34891                     "reflectVec = reflect( cameraToVertex, normal );",
34892
34893                 "}",
34894
34895             "#else",
34896
34897                 "reflectVec = vReflect;",
34898
34899             "#endif",
34900
34901             "#ifdef DOUBLE_SIDED",
34902
34903                 "float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
34904                 "vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",
34905
34906             "#else",
34907
34908                 "vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",
34909
34910             "#endif",
34911
34912             "#ifdef GAMMA_INPUT",
34913
34914                 "cubeColor.xyz *= cubeColor.xyz;",
34915
34916             "#endif",
34917
34918             "if ( combine == 1 ) {",
34919
34920                 "gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularStrength * reflectivity );",
34921
34922             "} else {",
34923
34924                 "gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * cubeColor.xyz, specularStrength * reflectivity );",
34925
34926             "}",
34927
34928         "#endif"
34929
34930     ].join("\n"),
34931
34932     envmap_pars_vertex: [
34933
34934         "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP )",
34935
34936             "varying vec3 vReflect;",
34937
34938             "uniform float refractionRatio;",
34939             "uniform bool useRefract;",
34940
34941         "#endif"
34942
34943     ].join("\n"),
34944
34945     worldpos_vertex : [
34946
34947         "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )",
34948
34949             "#ifdef USE_SKINNING",
34950
34951                 "vec4 mPosition = modelMatrix * skinned;",
34952
34953             "#endif",
34954
34955             "#if defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )",
34956
34957                 "vec4 mPosition = modelMatrix * vec4( morphed, 1.0 );",
34958
34959             "#endif",
34960
34961             "#if ! defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )",
34962
34963                 "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
34964
34965             "#endif",
34966
34967         "#endif"
34968
34969     ].join("\n"),
34970
34971     envmap_vertex : [
34972
34973         "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP )",
34974
34975             "vec3 nWorld = mat3( modelMatrix[ 0 ].xyz, modelMatrix[ 1 ].xyz, modelMatrix[ 2 ].xyz ) * objectNormal;",
34976
34977             "if ( useRefract ) {",
34978
34979                 "vReflect = refract( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ), refractionRatio );",
34980
34981             "} else {",
34982
34983                 "vReflect = reflect( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ) );",
34984
34985             "}",
34986
34987         "#endif"
34988
34989     ].join("\n"),
34990
34991     // COLOR MAP (particles)
34992
34993     map_particle_pars_fragment: [
34994
34995         "#ifdef USE_MAP",
34996
34997             "uniform sampler2D map;",
34998
34999         "#endif"
35000
35001     ].join("\n"),
35002
35003
35004     map_particle_fragment: [
35005
35006         "#ifdef USE_MAP",
35007
35008             "gl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );",
35009
35010         "#endif"
35011
35012     ].join("\n"),
35013
35014     // COLOR MAP (triangles)
35015
35016     map_pars_vertex: [
35017
35018         "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )",
35019
35020             "varying vec2 vUv;",
35021             "uniform vec4 offsetRepeat;",
35022
35023         "#endif"
35024
35025     ].join("\n"),
35026
35027     map_pars_fragment: [
35028
35029         "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )",
35030
35031             "varying vec2 vUv;",
35032
35033         "#endif",
35034
35035         "#ifdef USE_MAP",
35036
35037             "uniform sampler2D map;",
35038
35039         "#endif",
35040
35041     ].join("\n"),
35042
35043     map_vertex: [
35044
35045         "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )",
35046
35047             "vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
35048
35049         "#endif"
35050
35051     ].join("\n"),
35052
35053     map_fragment: [
35054
35055         "#ifdef USE_MAP",
35056
35057             "#ifdef GAMMA_INPUT",
35058
35059                 "vec4 texelColor = texture2D( map, vUv );",
35060                 "texelColor.xyz *= texelColor.xyz;",
35061
35062                 "gl_FragColor = gl_FragColor * texelColor;",
35063
35064             "#else",
35065
35066                 "gl_FragColor = gl_FragColor * texture2D( map, vUv );",
35067
35068             "#endif",
35069
35070         "#endif"
35071
35072     ].join("\n"),
35073
35074     // LIGHT MAP
35075
35076     lightmap_pars_fragment: [
35077
35078         "#ifdef USE_LIGHTMAP",
35079
35080             "varying vec2 vUv2;",
35081             "uniform sampler2D lightMap;",
35082
35083         "#endif"
35084
35085     ].join("\n"),
35086
35087     lightmap_pars_vertex: [
35088
35089         "#ifdef USE_LIGHTMAP",
35090
35091             "varying vec2 vUv2;",
35092
35093         "#endif"
35094
35095     ].join("\n"),
35096
35097     lightmap_fragment: [
35098
35099         "#ifdef USE_LIGHTMAP",
35100
35101             "gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );",
35102
35103         "#endif"
35104
35105     ].join("\n"),
35106
35107     lightmap_vertex: [
35108
35109         "#ifdef USE_LIGHTMAP",
35110
35111             "vUv2 = uv2;",
35112
35113         "#endif"
35114
35115     ].join("\n"),
35116
35117     // BUMP MAP
35118
35119     bumpmap_pars_fragment: [
35120
35121         "#ifdef USE_BUMPMAP",
35122
35123             "uniform sampler2D bumpMap;",
35124             "uniform float bumpScale;",
35125
35126             // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen
35127             //    http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html
35128
35129             // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
35130
35131             "vec2 dHdxy_fwd() {",
35132
35133                 "vec2 dSTdx = dFdx( vUv );",
35134                 "vec2 dSTdy = dFdy( vUv );",
35135
35136                 "float Hll = bumpScale * texture2D( bumpMap, vUv ).x;",
35137                 "float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;",
35138                 "float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;",
35139
35140                 "return vec2( dBx, dBy );",
35141
35142             "}",
35143
35144             "vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {",
35145
35146                 "vec3 vSigmaX = dFdx( surf_pos );",
35147                 "vec3 vSigmaY = dFdy( surf_pos );",
35148                 "vec3 vN = surf_norm;",        // normalized
35149
35150                 "vec3 R1 = cross( vSigmaY, vN );",
35151                 "vec3 R2 = cross( vN, vSigmaX );",
35152
35153                 "float fDet = dot( vSigmaX, R1 );",
35154
35155                 "vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );",
35156                 "return normalize( abs( fDet ) * surf_norm - vGrad );",
35157
35158             "}",
35159
35160         "#endif"
35161
35162     ].join("\n"),
35163
35164     // NORMAL MAP
35165
35166     normalmap_pars_fragment: [
35167
35168         "#ifdef USE_NORMALMAP",
35169
35170             "uniform sampler2D normalMap;",
35171             "uniform vec2 normalScale;",
35172
35173             // Per-Pixel Tangent Space Normal Mapping
35174             // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html
35175
35176             "vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {",
35177
35178                 "vec3 q0 = dFdx( eye_pos.xyz );",
35179                 "vec3 q1 = dFdy( eye_pos.xyz );",
35180                 "vec2 st0 = dFdx( vUv.st );",
35181                 "vec2 st1 = dFdy( vUv.st );",
35182
35183                 "vec3 S = normalize(  q0 * st1.t - q1 * st0.t );",
35184                 "vec3 T = normalize( -q0 * st1.s + q1 * st0.s );",
35185                 "vec3 N = normalize( surf_norm );",
35186
35187                 "vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;",
35188                 "mapN.xy = normalScale * mapN.xy;",
35189                 "mat3 tsn = mat3( S, T, N );",
35190                 "return normalize( tsn * mapN );",
35191
35192             "}",
35193
35194         "#endif"
35195
35196     ].join("\n"),
35197
35198     // SPECULAR MAP
35199
35200     specularmap_pars_fragment: [
35201
35202         "#ifdef USE_SPECULARMAP",
35203
35204             "uniform sampler2D specularMap;",
35205
35206         "#endif"
35207
35208     ].join("\n"),
35209
35210     specularmap_fragment: [
35211
35212         "float specularStrength;",
35213
35214         "#ifdef USE_SPECULARMAP",
35215
35216             "vec4 texelSpecular = texture2D( specularMap, vUv );",
35217             "specularStrength = texelSpecular.r;",
35218
35219         "#else",
35220
35221             "specularStrength = 1.0;",
35222
35223         "#endif"
35224
35225     ].join("\n"),
35226
35227     // LIGHTS LAMBERT
35228
35229     lights_lambert_pars_vertex: [
35230
35231         "uniform vec3 ambient;",
35232         "uniform vec3 diffuse;",
35233         "uniform vec3 emissive;",
35234
35235         "uniform vec3 ambientLightColor;",
35236
35237         "#if MAX_DIR_LIGHTS > 0",
35238
35239             "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
35240             "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
35241
35242         "#endif",
35243
35244         "#if MAX_HEMI_LIGHTS > 0",
35245
35246             "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
35247             "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
35248             "uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
35249
35250         "#endif",
35251
35252         "#if MAX_POINT_LIGHTS > 0",
35253
35254             "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
35255             "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
35256             "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
35257
35258         "#endif",
35259
35260         "#if MAX_SPOT_LIGHTS > 0",
35261
35262             "uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
35263             "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
35264             "uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
35265             "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
35266             "uniform float spotLightAngle[ MAX_SPOT_LIGHTS ];",
35267             "uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
35268
35269         "#endif",
35270
35271         "#ifdef WRAP_AROUND",
35272
35273             "uniform vec3 wrapRGB;",
35274
35275         "#endif"
35276
35277     ].join("\n"),
35278
35279     lights_lambert_vertex: [
35280
35281         "vLightFront = vec3( 0.0 );",
35282
35283         "#ifdef DOUBLE_SIDED",
35284
35285             "vLightBack = vec3( 0.0 );",
35286
35287         "#endif",
35288
35289         "transformedNormal = normalize( transformedNormal );",
35290
35291         "#if MAX_DIR_LIGHTS > 0",
35292
35293         "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
35294
35295             "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
35296             "vec3 dirVector = normalize( lDirection.xyz );",
35297
35298             "float dotProduct = dot( transformedNormal, dirVector );",
35299             "vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );",
35300
35301             "#ifdef DOUBLE_SIDED",
35302
35303                 "vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
35304
35305                 "#ifdef WRAP_AROUND",
35306
35307                     "vec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
35308
35309                 "#endif",
35310
35311             "#endif",
35312
35313             "#ifdef WRAP_AROUND",
35314
35315                 "vec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
35316                 "directionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );",
35317
35318                 "#ifdef DOUBLE_SIDED",
35319
35320                     "directionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );",
35321
35322                 "#endif",
35323
35324             "#endif",
35325
35326             "vLightFront += directionalLightColor[ i ] * directionalLightWeighting;",
35327
35328             "#ifdef DOUBLE_SIDED",
35329
35330                 "vLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;",
35331
35332             "#endif",
35333
35334         "}",
35335
35336         "#endif",
35337
35338         "#if MAX_POINT_LIGHTS > 0",
35339
35340             "for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
35341
35342                 "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
35343                 "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
35344
35345                 "float lDistance = 1.0;",
35346                 "if ( pointLightDistance[ i ] > 0.0 )",
35347                     "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
35348
35349                 "lVector = normalize( lVector );",
35350                 "float dotProduct = dot( transformedNormal, lVector );",
35351
35352                 "vec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );",
35353
35354                 "#ifdef DOUBLE_SIDED",
35355
35356                     "vec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
35357
35358                     "#ifdef WRAP_AROUND",
35359
35360                         "vec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
35361
35362                     "#endif",
35363
35364                 "#endif",
35365
35366                 "#ifdef WRAP_AROUND",
35367
35368                     "vec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
35369                     "pointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );",
35370
35371                     "#ifdef DOUBLE_SIDED",
35372
35373                         "pointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );",
35374
35375                     "#endif",
35376
35377                 "#endif",
35378
35379                 "vLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;",
35380
35381                 "#ifdef DOUBLE_SIDED",
35382
35383                     "vLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;",
35384
35385                 "#endif",
35386
35387             "}",
35388
35389         "#endif",
35390
35391         "#if MAX_SPOT_LIGHTS > 0",
35392
35393             "for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
35394
35395                 "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
35396                 "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
35397
35398                 "lVector = normalize( lVector );",
35399
35400                 "float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - mPosition.xyz ) );",
35401
35402                 "if ( spotEffect > spotLightAngle[ i ] ) {",
35403
35404                     "spotEffect = pow( spotEffect, spotLightExponent[ i ] );",
35405
35406                     "float lDistance = 1.0;",
35407                     "if ( spotLightDistance[ i ] > 0.0 )",
35408                         "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
35409
35410                     "float dotProduct = dot( transformedNormal, lVector );",
35411                     "vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );",
35412
35413                     "#ifdef DOUBLE_SIDED",
35414
35415                         "vec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
35416
35417                         "#ifdef WRAP_AROUND",
35418
35419                             "vec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
35420
35421                         "#endif",
35422
35423                     "#endif",
35424
35425                     "#ifdef WRAP_AROUND",
35426
35427                         "vec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
35428                         "spotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );",
35429
35430                         "#ifdef DOUBLE_SIDED",
35431
35432                             "spotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );",
35433
35434                         "#endif",
35435
35436                     "#endif",
35437
35438                     "vLightFront += spotLightColor[ i ] * spotLightWeighting * lDistance * spotEffect;",
35439
35440                     "#ifdef DOUBLE_SIDED",
35441
35442                         "vLightBack += spotLightColor[ i ] * spotLightWeightingBack * lDistance * spotEffect;",
35443
35444                     "#endif",
35445
35446                 "}",
35447
35448             "}",
35449
35450         "#endif",
35451
35452         "#if MAX_HEMI_LIGHTS > 0",
35453
35454             "for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
35455
35456                 "vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
35457                 "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
35458
35459                 "lVector = normalize( lVector );",
35460
35461                 "float dotProduct = dot( transformedNormal, lVector );",
35462
35463                 "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
35464                 "float hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;",
35465
35466                 "vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
35467
35468                 "#ifdef DOUBLE_SIDED",
35469
35470                     "vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );",
35471
35472                 "#endif",
35473
35474             "}",
35475
35476         "#endif",
35477
35478         "vLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;",
35479
35480         "#ifdef DOUBLE_SIDED",
35481
35482             "vLightBack = vLightBack * diffuse + ambient * ambientLightColor + emissive;",
35483
35484         "#endif"
35485
35486     ].join("\n"),
35487
35488     // LIGHTS PHONG
35489
35490     lights_phong_pars_vertex: [
35491
35492         "#ifndef PHONG_PER_PIXEL",
35493
35494         "#if MAX_POINT_LIGHTS > 0",
35495
35496             "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
35497             "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
35498
35499             "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
35500
35501         "#endif",
35502
35503         "#if MAX_SPOT_LIGHTS > 0",
35504
35505             "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
35506             "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
35507
35508             "varying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];",
35509
35510         "#endif",
35511
35512         "#endif",
35513
35514         "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )",
35515
35516             "varying vec3 vWorldPosition;",
35517
35518         "#endif"
35519
35520     ].join("\n"),
35521
35522
35523     lights_phong_vertex: [
35524
35525         "#ifndef PHONG_PER_PIXEL",
35526
35527         "#if MAX_POINT_LIGHTS > 0",
35528
35529             "for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
35530
35531                 "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
35532                 "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
35533
35534                 "float lDistance = 1.0;",
35535                 "if ( pointLightDistance[ i ] > 0.0 )",
35536                     "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
35537
35538                 "vPointLight[ i ] = vec4( lVector, lDistance );",
35539
35540             "}",
35541
35542         "#endif",
35543
35544         "#if MAX_SPOT_LIGHTS > 0",
35545
35546             "for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
35547
35548                 "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
35549                 "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
35550
35551                 "float lDistance = 1.0;",
35552                 "if ( spotLightDistance[ i ] > 0.0 )",
35553                     "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
35554
35555                 "vSpotLight[ i ] = vec4( lVector, lDistance );",
35556
35557             "}",
35558
35559         "#endif",
35560
35561         "#endif",
35562
35563         "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )",
35564
35565             "vWorldPosition = mPosition.xyz;",
35566
35567         "#endif"
35568
35569     ].join("\n"),
35570
35571     lights_phong_pars_fragment: [
35572
35573         "uniform vec3 ambientLightColor;",
35574
35575         "#if MAX_DIR_LIGHTS > 0",
35576
35577             "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
35578             "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
35579
35580         "#endif",
35581
35582         "#if MAX_HEMI_LIGHTS > 0",
35583
35584             "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
35585             "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
35586             "uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
35587
35588         "#endif",
35589
35590         "#if MAX_POINT_LIGHTS > 0",
35591
35592             "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
35593
35594             "#ifdef PHONG_PER_PIXEL",
35595
35596                 "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
35597                 "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
35598
35599             "#else",
35600
35601                 "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
35602
35603             "#endif",
35604
35605         "#endif",
35606
35607         "#if MAX_SPOT_LIGHTS > 0",
35608
35609             "uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
35610             "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
35611             "uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
35612             "uniform float spotLightAngle[ MAX_SPOT_LIGHTS ];",
35613             "uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
35614
35615             "#ifdef PHONG_PER_PIXEL",
35616
35617                 "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
35618
35619             "#else",
35620
35621                 "varying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];",
35622
35623             "#endif",
35624
35625         "#endif",
35626
35627         "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )",
35628
35629             "varying vec3 vWorldPosition;",
35630
35631         "#endif",
35632
35633         "#ifdef WRAP_AROUND",
35634
35635             "uniform vec3 wrapRGB;",
35636
35637         "#endif",
35638
35639         "varying vec3 vViewPosition;",
35640         "varying vec3 vNormal;"
35641
35642     ].join("\n"),
35643
35644     lights_phong_fragment: [
35645
35646         "vec3 normal = normalize( vNormal );",
35647         "vec3 viewPosition = normalize( vViewPosition );",
35648
35649         "#ifdef DOUBLE_SIDED",
35650
35651             "normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
35652
35653         "#endif",
35654
35655         "#ifdef USE_NORMALMAP",
35656
35657             "normal = perturbNormal2Arb( -viewPosition, normal );",
35658
35659         "#elif defined( USE_BUMPMAP )",
35660
35661             "normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );",
35662
35663         "#endif",
35664
35665         "#if MAX_POINT_LIGHTS > 0",
35666
35667             "vec3 pointDiffuse  = vec3( 0.0 );",
35668             "vec3 pointSpecular = vec3( 0.0 );",
35669
35670             "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
35671
35672                 "#ifdef PHONG_PER_PIXEL",
35673
35674                     "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
35675                     "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",
35676
35677                     "float lDistance = 1.0;",
35678                     "if ( pointLightDistance[ i ] > 0.0 )",
35679                         "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
35680
35681                     "lVector = normalize( lVector );",
35682
35683                 "#else",
35684
35685                     "vec3 lVector = normalize( vPointLight[ i ].xyz );",
35686                     "float lDistance = vPointLight[ i ].w;",
35687
35688                 "#endif",
35689
35690                 // diffuse
35691
35692                 "float dotProduct = dot( normal, lVector );",
35693
35694                 "#ifdef WRAP_AROUND",
35695
35696                     "float pointDiffuseWeightFull = max( dotProduct, 0.0 );",
35697                     "float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
35698
35699                     "vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );",
35700
35701                 "#else",
35702
35703                     "float pointDiffuseWeight = max( dotProduct, 0.0 );",
35704
35705                 "#endif",
35706
35707                 "pointDiffuse  += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;",
35708
35709                 // specular
35710
35711                 "vec3 pointHalfVector = normalize( lVector + viewPosition );",
35712                 "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
35713                 "float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );",
35714
35715                 "#ifdef PHYSICALLY_BASED_SHADING",
35716
35717                     // 2.0 => 2.0001 is hack to work around ANGLE bug
35718
35719                     "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
35720
35721                     "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, pointHalfVector ), 5.0 );",
35722                     "pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;",
35723
35724                 "#else",
35725
35726                     "pointSpecular += specular * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;",
35727
35728                 "#endif",
35729
35730             "}",
35731
35732         "#endif",
35733
35734         "#if MAX_SPOT_LIGHTS > 0",
35735
35736             "vec3 spotDiffuse  = vec3( 0.0 );",
35737             "vec3 spotSpecular = vec3( 0.0 );",
35738
35739             "for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
35740
35741                 "#ifdef PHONG_PER_PIXEL",
35742
35743                     "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
35744                     "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",
35745
35746                     "float lDistance = 1.0;",
35747                     "if ( spotLightDistance[ i ] > 0.0 )",
35748                         "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
35749
35750                     "lVector = normalize( lVector );",
35751
35752                 "#else",
35753
35754                     "vec3 lVector = normalize( vSpotLight[ i ].xyz );",
35755                     "float lDistance = vSpotLight[ i ].w;",
35756
35757                 "#endif",
35758
35759                 "float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );",
35760
35761                 "if ( spotEffect > spotLightAngle[ i ] ) {",
35762
35763                     "spotEffect = pow( spotEffect, spotLightExponent[ i ] );",
35764
35765                     // diffuse
35766
35767                     "float dotProduct = dot( normal, lVector );",
35768
35769                     "#ifdef WRAP_AROUND",
35770
35771                         "float spotDiffuseWeightFull = max( dotProduct, 0.0 );",
35772                         "float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
35773
35774                         "vec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );",
35775
35776                     "#else",
35777
35778                         "float spotDiffuseWeight = max( dotProduct, 0.0 );",
35779
35780                     "#endif",
35781
35782                     "spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;",
35783
35784                     // specular
35785
35786                     "vec3 spotHalfVector = normalize( lVector + viewPosition );",
35787                     "float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
35788                     "float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );",
35789
35790                     "#ifdef PHYSICALLY_BASED_SHADING",
35791
35792                         // 2.0 => 2.0001 is hack to work around ANGLE bug
35793
35794                         "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
35795
35796                         "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, spotHalfVector ), 5.0 );",
35797                         "spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;",
35798
35799                     "#else",
35800
35801                         "spotSpecular += specular * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * spotEffect;",
35802
35803                     "#endif",
35804
35805                 "}",
35806
35807             "}",
35808
35809         "#endif",
35810
35811         "#if MAX_DIR_LIGHTS > 0",
35812
35813             "vec3 dirDiffuse  = vec3( 0.0 );",
35814             "vec3 dirSpecular = vec3( 0.0 );" ,
35815
35816             "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
35817
35818                 "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
35819                 "vec3 dirVector = normalize( lDirection.xyz );",
35820
35821                 // diffuse
35822
35823                 "float dotProduct = dot( normal, dirVector );",
35824
35825                 "#ifdef WRAP_AROUND",
35826
35827                     "float dirDiffuseWeightFull = max( dotProduct, 0.0 );",
35828                     "float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
35829
35830                     "vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );",
35831
35832                 "#else",
35833
35834                     "float dirDiffuseWeight = max( dotProduct, 0.0 );",
35835
35836                 "#endif",
35837
35838                 "dirDiffuse  += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;",
35839
35840                 // specular
35841
35842                 "vec3 dirHalfVector = normalize( dirVector + viewPosition );",
35843                 "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
35844                 "float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );",
35845
35846                 "#ifdef PHYSICALLY_BASED_SHADING",
35847
35848                     /*
35849                     // fresnel term from skin shader
35850                     "const float F0 = 0.128;",
35851
35852                     "float base = 1.0 - dot( viewPosition, dirHalfVector );",
35853                     "float exponential = pow( base, 5.0 );",
35854
35855                     "float fresnel = exponential + F0 * ( 1.0 - exponential );",
35856                     */
35857
35858                     /*
35859                     // fresnel term from fresnel shader
35860                     "const float mFresnelBias = 0.08;",
35861                     "const float mFresnelScale = 0.3;",
35862                     "const float mFresnelPower = 5.0;",
35863
35864                     "float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );",
35865                     */
35866
35867                     // 2.0 => 2.0001 is hack to work around ANGLE bug
35868
35869                     "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
35870
35871                     //"dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;",
35872
35873                     "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );",
35874                     "dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
35875
35876                 "#else",
35877
35878                     "dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;",
35879
35880                 "#endif",
35881
35882             "}",
35883
35884         "#endif",
35885
35886         "#if MAX_HEMI_LIGHTS > 0",
35887
35888             "vec3 hemiDiffuse  = vec3( 0.0 );",
35889             "vec3 hemiSpecular = vec3( 0.0 );" ,
35890
35891             "for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
35892
35893                 "vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
35894                 "vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
35895
35896                 // diffuse
35897
35898                 "float dotProduct = dot( normal, lVector );",
35899                 "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
35900
35901                 "vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
35902
35903                 "hemiDiffuse += diffuse * hemiColor;",
35904
35905                 // specular (sky light)
35906
35907                 "vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
35908                 "float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
35909                 "float hemiSpecularWeightSky = specularStrength * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );",
35910
35911                 // specular (ground light)
35912
35913                 "vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
35914
35915                 "vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );",
35916                 "float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
35917                 "float hemiSpecularWeightGround = specularStrength * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );",
35918
35919                 "#ifdef PHYSICALLY_BASED_SHADING",
35920
35921                     "float dotProductGround = dot( normal, lVectorGround );",
35922
35923                     // 2.0 => 2.0001 is hack to work around ANGLE bug
35924
35925                     "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
35926
35927                     "vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );",
35928                     "vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
35929                     "hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",
35930
35931                 "#else",
35932
35933                     "hemiSpecular += specular * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;",
35934
35935                 "#endif",
35936
35937             "}",
35938
35939         "#endif",
35940
35941         "vec3 totalDiffuse = vec3( 0.0 );",
35942         "vec3 totalSpecular = vec3( 0.0 );",
35943
35944         "#if MAX_DIR_LIGHTS > 0",
35945
35946             "totalDiffuse += dirDiffuse;",
35947             "totalSpecular += dirSpecular;",
35948
35949         "#endif",
35950
35951         "#if MAX_HEMI_LIGHTS > 0",
35952
35953             "totalDiffuse += hemiDiffuse;",
35954             "totalSpecular += hemiSpecular;",
35955
35956         "#endif",
35957
35958         "#if MAX_POINT_LIGHTS > 0",
35959
35960             "totalDiffuse += pointDiffuse;",
35961             "totalSpecular += pointSpecular;",
35962
35963         "#endif",
35964
35965         "#if MAX_SPOT_LIGHTS > 0",
35966
35967             "totalDiffuse += spotDiffuse;",
35968             "totalSpecular += spotSpecular;",
35969
35970         "#endif",
35971
35972         "#ifdef METAL",
35973
35974             "gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );",
35975
35976         "#else",
35977
35978             "gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;",
35979
35980         "#endif"
35981
35982     ].join("\n"),
35983
35984     // VERTEX COLORS
35985
35986     color_pars_fragment: [
35987
35988         "#ifdef USE_COLOR",
35989
35990             "varying vec3 vColor;",
35991
35992         "#endif"
35993
35994     ].join("\n"),
35995
35996
35997     color_fragment: [
35998
35999         "#ifdef USE_COLOR",
36000
36001             "gl_FragColor = gl_FragColor * vec4( vColor, opacity );",
36002
36003         "#endif"
36004
36005     ].join("\n"),
36006
36007     color_pars_vertex: [
36008
36009         "#ifdef USE_COLOR",
36010
36011             "varying vec3 vColor;",
36012
36013         "#endif"
36014
36015     ].join("\n"),
36016
36017
36018     color_vertex: [
36019
36020         "#ifdef USE_COLOR",
36021
36022             "#ifdef GAMMA_INPUT",
36023
36024                 "vColor = color * color;",
36025
36026             "#else",
36027
36028                 "vColor = color;",
36029
36030             "#endif",
36031
36032         "#endif"
36033
36034     ].join("\n"),
36035
36036     // SKINNING
36037
36038     skinning_pars_vertex: [
36039
36040         "#ifdef USE_SKINNING",
36041
36042             "#ifdef BONE_TEXTURE",
36043
36044                 "uniform sampler2D boneTexture;",
36045
36046                 "mat4 getBoneMatrix( const in float i ) {",
36047
36048                     "float j = i * 4.0;",
36049                     "float x = mod( j, N_BONE_PIXEL_X );",
36050                     "float y = floor( j / N_BONE_PIXEL_X );",
36051
36052                     "const float dx = 1.0 / N_BONE_PIXEL_X;",
36053                     "const float dy = 1.0 / N_BONE_PIXEL_Y;",
36054
36055                     "y = dy * ( y + 0.5 );",
36056
36057                     "vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );",
36058                     "vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );",
36059                     "vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );",
36060                     "vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );",
36061
36062                     "mat4 bone = mat4( v1, v2, v3, v4 );",
36063
36064                     "return bone;",
36065
36066                 "}",
36067
36068             "#else",
36069
36070                 "uniform mat4 boneGlobalMatrices[ MAX_BONES ];",
36071
36072                 "mat4 getBoneMatrix( const in float i ) {",
36073
36074                     "mat4 bone = boneGlobalMatrices[ int(i) ];",
36075                     "return bone;",
36076
36077                 "}",
36078
36079             "#endif",
36080
36081         "#endif"
36082
36083     ].join("\n"),
36084
36085     skinbase_vertex: [
36086
36087         "#ifdef USE_SKINNING",
36088
36089             "mat4 boneMatX = getBoneMatrix( skinIndex.x );",
36090             "mat4 boneMatY = getBoneMatrix( skinIndex.y );",
36091
36092         "#endif"
36093
36094     ].join("\n"),
36095
36096     skinning_vertex: [
36097
36098         "#ifdef USE_SKINNING",
36099
36100             "#ifdef USE_MORPHTARGETS",
36101
36102             "vec4 skinVertex = vec4( morphed, 1.0 );",
36103
36104             "#else",
36105
36106             "vec4 skinVertex = vec4( position, 1.0 );",
36107
36108             "#endif",
36109
36110             "vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
36111             "skinned       += boneMatY * skinVertex * skinWeight.y;",
36112
36113         "#endif"
36114
36115     ].join("\n"),
36116
36117     // MORPHING
36118
36119     morphtarget_pars_vertex: [
36120
36121         "#ifdef USE_MORPHTARGETS",
36122
36123             "#ifndef USE_MORPHNORMALS",
36124
36125             "uniform float morphTargetInfluences[ 8 ];",
36126
36127             "#else",
36128
36129             "uniform float morphTargetInfluences[ 4 ];",
36130
36131             "#endif",
36132
36133         "#endif"
36134
36135     ].join("\n"),
36136
36137     morphtarget_vertex: [
36138
36139         "#ifdef USE_MORPHTARGETS",
36140
36141             "vec3 morphed = vec3( 0.0 );",
36142             "morphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];",
36143             "morphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];",
36144             "morphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];",
36145             "morphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];",
36146
36147             "#ifndef USE_MORPHNORMALS",
36148
36149             "morphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];",
36150             "morphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];",
36151             "morphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];",
36152             "morphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];",
36153
36154             "#endif",
36155
36156             "morphed += position;",
36157
36158         "#endif"
36159
36160     ].join("\n"),
36161
36162     default_vertex : [
36163
36164         "vec4 mvPosition;",
36165
36166         "#ifdef USE_SKINNING",
36167
36168             "mvPosition = modelViewMatrix * skinned;",
36169
36170         "#endif",
36171
36172         "#if !defined( USE_SKINNING ) && defined( USE_MORPHTARGETS )",
36173
36174             "mvPosition = modelViewMatrix * vec4( morphed, 1.0 );",
36175
36176         "#endif",
36177
36178         "#if !defined( USE_SKINNING ) && ! defined( USE_MORPHTARGETS )",
36179
36180             "mvPosition = modelViewMatrix * vec4( position, 1.0 );",
36181
36182         "#endif",
36183
36184         "gl_Position = projectionMatrix * mvPosition;",
36185
36186     ].join("\n"),
36187
36188     morphnormal_vertex: [
36189
36190         "#ifdef USE_MORPHNORMALS",
36191
36192             "vec3 morphedNormal = vec3( 0.0 );",
36193
36194             "morphedNormal +=  ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];",
36195             "morphedNormal +=  ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];",
36196             "morphedNormal +=  ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];",
36197             "morphedNormal +=  ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];",
36198
36199             "morphedNormal += normal;",
36200
36201         "#endif"
36202
36203     ].join("\n"),
36204
36205     skinnormal_vertex: [
36206
36207         "#ifdef USE_SKINNING",
36208
36209             "mat4 skinMatrix = skinWeight.x * boneMatX;",
36210             "skinMatrix     += skinWeight.y * boneMatY;",
36211
36212             "#ifdef USE_MORPHNORMALS",
36213
36214             "vec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );",
36215
36216             "#else",
36217
36218             "vec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );",
36219
36220             "#endif",
36221
36222         "#endif"
36223
36224     ].join("\n"),
36225
36226     defaultnormal_vertex: [
36227
36228         "vec3 objectNormal;",
36229
36230         "#ifdef USE_SKINNING",
36231
36232             "objectNormal = skinnedNormal.xyz;",
36233
36234         "#endif",
36235
36236         "#if !defined( USE_SKINNING ) && defined( USE_MORPHNORMALS )",
36237
36238             "objectNormal = morphedNormal;",
36239
36240         "#endif",
36241
36242         "#if !defined( USE_SKINNING ) && ! defined( USE_MORPHNORMALS )",
36243
36244             "objectNormal = normal;",
36245
36246         "#endif",
36247
36248         "#ifdef FLIP_SIDED",
36249
36250             "objectNormal = -objectNormal;",
36251
36252         "#endif",
36253
36254         "vec3 transformedNormal = normalMatrix * objectNormal;",
36255
36256     ].join("\n"),
36257
36258     // SHADOW MAP
36259
36260     // based on SpiderGL shadow map and Fabien Sanglard's GLSL shadow mapping examples
36261     //  http://spidergl.org/example.php?id=6
36262     //     http://fabiensanglard.net/shadowmapping
36263
36264     shadowmap_pars_fragment: [
36265
36266         "#ifdef USE_SHADOWMAP",
36267
36268             "uniform sampler2D shadowMap[ MAX_SHADOWS ];",
36269             "uniform vec2 shadowMapSize[ MAX_SHADOWS ];",
36270
36271             "uniform float shadowDarkness[ MAX_SHADOWS ];",
36272             "uniform float shadowBias[ MAX_SHADOWS ];",
36273
36274             "varying vec4 vShadowCoord[ MAX_SHADOWS ];",
36275
36276             "float unpackDepth( const in vec4 rgba_depth ) {",
36277
36278                 "const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );",
36279                 "float depth = dot( rgba_depth, bit_shift );",
36280                 "return depth;",
36281
36282             "}",
36283
36284         "#endif"
36285
36286     ].join("\n"),
36287
36288     shadowmap_fragment: [
36289
36290         "#ifdef USE_SHADOWMAP",
36291
36292             "#ifdef SHADOWMAP_DEBUG",
36293
36294                 "vec3 frustumColors[3];",
36295                 "frustumColors[0] = vec3( 1.0, 0.5, 0.0 );",
36296                 "frustumColors[1] = vec3( 0.0, 1.0, 0.8 );",
36297                 "frustumColors[2] = vec3( 0.0, 0.5, 1.0 );",
36298
36299             "#endif",
36300
36301             "#ifdef SHADOWMAP_CASCADE",
36302
36303                 "int inFrustumCount = 0;",
36304
36305             "#endif",
36306
36307             "float fDepth;",
36308             "vec3 shadowColor = vec3( 1.0 );",
36309
36310             "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
36311
36312                 "vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;",
36313
36314                 // "if ( something && something )"          breaks ATI OpenGL shader compiler
36315                 // "if ( all( something, something ) )"  using this instead
36316
36317                 "bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );",
36318                 "bool inFrustum = all( inFrustumVec );",
36319
36320                 // don't shadow pixels outside of light frustum
36321                 // use just first frustum (for cascades)
36322                 // don't shadow pixels behind far plane of light frustum
36323
36324                 "#ifdef SHADOWMAP_CASCADE",
36325
36326                     "inFrustumCount += int( inFrustum );",
36327                     "bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );",
36328
36329                 "#else",
36330
36331                     "bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );",
36332
36333                 "#endif",
36334
36335                 "bool frustumTest = all( frustumTestVec );",
36336
36337                 "if ( frustumTest ) {",
36338
36339                     "shadowCoord.z += shadowBias[ i ];",
36340
36341                     "#ifdef SHADOWMAP_SOFT",
36342
36343                         // Percentage-close filtering
36344                         // (9 pixel kernel)
36345                         // http://fabiensanglard.net/shadowmappingPCF/
36346
36347                         "float shadow = 0.0;",
36348
36349                         /*
36350                         // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL
36351                         // must enroll loop manually
36352
36353                         "for ( float y = -1.25; y <= 1.25; y += 1.25 )",
36354                             "for ( float x = -1.25; x <= 1.25; x += 1.25 ) {",
36355
36356                                 "vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );",
36357
36358                                 // doesn't seem to produce any noticeable visual difference compared to simple "texture2D" lookup
36359                                 //"vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );",
36360
36361                                 "float fDepth = unpackDepth( rgbaDepth );",
36362
36363                                 "if ( fDepth < shadowCoord.z )",
36364                                     "shadow += 1.0;",
36365
36366                         "}",
36367
36368                         "shadow /= 9.0;",
36369
36370                         */
36371
36372                         "const float shadowDelta = 1.0 / 9.0;",
36373
36374                         "float xPixelOffset = 1.0 / shadowMapSize[ i ].x;",
36375                         "float yPixelOffset = 1.0 / shadowMapSize[ i ].y;",
36376
36377                         "float dx0 = -1.25 * xPixelOffset;",
36378                         "float dy0 = -1.25 * yPixelOffset;",
36379                         "float dx1 = 1.25 * xPixelOffset;",
36380                         "float dy1 = 1.25 * yPixelOffset;",
36381
36382                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );",
36383                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36384
36385                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );",
36386                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36387
36388                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );",
36389                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36390
36391                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );",
36392                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36393
36394                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );",
36395                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36396
36397                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );",
36398                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36399
36400                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );",
36401                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36402
36403                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );",
36404                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36405
36406                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );",
36407                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36408
36409                         "shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );",
36410
36411                     "#else",
36412
36413                         "vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );",
36414                         "float fDepth = unpackDepth( rgbaDepth );",
36415
36416                         "if ( fDepth < shadowCoord.z )",
36417
36418                             // spot with multiple shadows is darker
36419
36420                             "shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );",
36421
36422                             // spot with multiple shadows has the same color as single shadow spot
36423
36424                             //"shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );",
36425
36426                     "#endif",
36427
36428                 "}",
36429
36430
36431                 "#ifdef SHADOWMAP_DEBUG",
36432
36433                     "#ifdef SHADOWMAP_CASCADE",
36434
36435                         "if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];",
36436
36437                     "#else",
36438
36439                         "if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];",
36440
36441                     "#endif",
36442
36443                 "#endif",
36444
36445             "}",
36446
36447             "#ifdef GAMMA_OUTPUT",
36448
36449                 "shadowColor *= shadowColor;",
36450
36451             "#endif",
36452
36453             "gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;",
36454
36455         "#endif"
36456
36457     ].join("\n"),
36458
36459     shadowmap_pars_vertex: [
36460
36461         "#ifdef USE_SHADOWMAP",
36462
36463             "varying vec4 vShadowCoord[ MAX_SHADOWS ];",
36464             "uniform mat4 shadowMatrix[ MAX_SHADOWS ];",
36465
36466         "#endif"
36467
36468     ].join("\n"),
36469
36470     shadowmap_vertex: [
36471
36472         "#ifdef USE_SHADOWMAP",
36473
36474             "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
36475
36476                 "vShadowCoord[ i ] = shadowMatrix[ i ] * mPosition;",
36477
36478             "}",
36479
36480         "#endif"
36481
36482     ].join("\n"),
36483
36484     // ALPHATEST
36485
36486     alphatest_fragment: [
36487
36488         "#ifdef ALPHATEST",
36489
36490             "if ( gl_FragColor.a < ALPHATEST ) discard;",
36491
36492         "#endif"
36493
36494     ].join("\n"),
36495
36496     // LINEAR SPACE
36497
36498     linear_to_gamma_fragment: [
36499
36500         "#ifdef GAMMA_OUTPUT",
36501
36502             "gl_FragColor.xyz = sqrt( gl_FragColor.xyz );",
36503
36504         "#endif"
36505
36506     ].join("\n"),
36507
36508
36509 };
36510
36511 THREE.UniformsUtils = {
36512
36513     merge: function ( uniforms ) {
36514
36515         var u, p, tmp, merged = {};
36516
36517         for ( u = 0; u < uniforms.length; u ++ ) {
36518
36519             tmp = this.clone( uniforms[ u ] );
36520
36521             for ( p in tmp ) {
36522
36523                 merged[ p ] = tmp[ p ];
36524
36525             }
36526
36527         }
36528
36529         return merged;
36530
36531     },
36532
36533     clone: function ( uniforms_src ) {
36534
36535         var u, p, parameter, parameter_src, uniforms_dst = {};
36536
36537         for ( u in uniforms_src ) {
36538
36539             uniforms_dst[ u ] = {};
36540
36541             for ( p in uniforms_src[ u ] ) {
36542
36543                 parameter_src = uniforms_src[ u ][ p ];
36544
36545                 if ( parameter_src instanceof THREE.Color ||
36546                      parameter_src instanceof THREE.Vector2 ||
36547                      parameter_src instanceof THREE.Vector3 ||
36548                      parameter_src instanceof THREE.Vector4 ||
36549                      parameter_src instanceof THREE.Matrix4 ||
36550                      parameter_src instanceof THREE.Texture ) {
36551
36552                     uniforms_dst[ u ][ p ] = parameter_src.clone();
36553
36554                 } else if ( parameter_src instanceof Array ) {
36555
36556                     uniforms_dst[ u ][ p ] = parameter_src.slice();
36557
36558                 } else {
36559
36560                     uniforms_dst[ u ][ p ] = parameter_src;
36561
36562                 }
36563
36564             }
36565
36566         }
36567
36568         return uniforms_dst;
36569
36570     }
36571
36572 };
36573
36574 THREE.UniformsLib = {
36575
36576     common: {
36577
36578         "diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
36579         "opacity" : { type: "f", value: 1.0 },
36580
36581         "map" : { type: "t", value: null },
36582         "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
36583
36584         "lightMap" : { type: "t", value: null },
36585         "specularMap" : { type: "t", value: null },
36586
36587         "envMap" : { type: "t", value: null },
36588         "flipEnvMap" : { type: "f", value: -1 },
36589         "useRefract" : { type: "i", value: 0 },
36590         "reflectivity" : { type: "f", value: 1.0 },
36591         "refractionRatio" : { type: "f", value: 0.98 },
36592         "combine" : { type: "i", value: 0 },
36593
36594         "morphTargetInfluences" : { type: "f", value: 0 }
36595
36596     },
36597
36598     bump: {
36599
36600         "bumpMap" : { type: "t", value: null },
36601         "bumpScale" : { type: "f", value: 1 }
36602
36603     },
36604
36605     normalmap: {
36606
36607         "normalMap" : { type: "t", value: null },
36608         "normalScale" : { type: "v2", value: new THREE.Vector2( 1, 1 ) }
36609     },
36610
36611     fog : {
36612
36613         "fogDensity" : { type: "f", value: 0.00025 },
36614         "fogNear" : { type: "f", value: 1 },
36615         "fogFar" : { type: "f", value: 2000 },
36616         "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
36617
36618     },
36619
36620     lights: {
36621
36622         "ambientLightColor" : { type: "fv", value: [] },
36623
36624         "directionalLightDirection" : { type: "fv", value: [] },
36625         "directionalLightColor" : { type: "fv", value: [] },
36626
36627         "hemisphereLightPosition" : { type: "fv", value: [] },
36628         "hemisphereLightSkyColor" : { type: "fv", value: [] },
36629         "hemisphereLightGroundColor" : { type: "fv", value: [] },
36630
36631         "pointLightColor" : { type: "fv", value: [] },
36632         "pointLightPosition" : { type: "fv", value: [] },
36633         "pointLightDistance" : { type: "fv1", value: [] },
36634
36635         "spotLightColor" : { type: "fv", value: [] },
36636         "spotLightPosition" : { type: "fv", value: [] },
36637         "spotLightDirection" : { type: "fv", value: [] },
36638         "spotLightDistance" : { type: "fv1", value: [] },
36639         "spotLightAngle" : { type: "fv1", value: [] },
36640         "spotLightExponent" : { type: "fv1", value: [] }
36641
36642     },
36643
36644     particle: {
36645
36646         "psColor" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
36647         "opacity" : { type: "f", value: 1.0 },
36648         "size" : { type: "f", value: 1.0 },
36649         "scale" : { type: "f", value: 1.0 },
36650         "map" : { type: "t", value: null },
36651
36652         "fogDensity" : { type: "f", value: 0.00025 },
36653         "fogNear" : { type: "f", value: 1 },
36654         "fogFar" : { type: "f", value: 2000 },
36655         "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
36656
36657     },
36658
36659     shadowmap: {
36660
36661         "shadowMap": { type: "tv", value: [] },
36662         "shadowMapSize": { type: "v2v", value: [] },
36663
36664         "shadowBias" : { type: "fv1", value: [] },
36665         "shadowDarkness": { type: "fv1", value: [] },
36666
36667         "shadowMatrix" : { type: "m4v", value: [] },
36668
36669     }
36670
36671 };
36672
36673 THREE.ShaderLib = {
36674
36675     'depth': {
36676
36677         uniforms: {
36678
36679             "mNear": { type: "f", value: 1.0 },
36680             "mFar" : { type: "f", value: 2000.0 },
36681             "opacity" : { type: "f", value: 1.0 }
36682
36683         },
36684
36685         vertexShader: [
36686
36687             "void main() {",
36688
36689                 "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
36690
36691             "}"
36692
36693         ].join("\n"),
36694
36695         fragmentShader: [
36696
36697             "uniform float mNear;",
36698             "uniform float mFar;",
36699             "uniform float opacity;",
36700
36701             "void main() {",
36702
36703                 "float depth = gl_FragCoord.z / gl_FragCoord.w;",
36704                 "float color = 1.0 - smoothstep( mNear, mFar, depth );",
36705                 "gl_FragColor = vec4( vec3( color ), opacity );",
36706
36707             "}"
36708
36709         ].join("\n")
36710
36711     },
36712
36713     'normal': {
36714
36715         uniforms: {
36716
36717             "opacity" : { type: "f", value: 1.0 }
36718
36719         },
36720
36721         vertexShader: [
36722
36723             "varying vec3 vNormal;",
36724
36725             "void main() {",
36726
36727                 "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
36728                 "vNormal = normalMatrix * normal;",
36729
36730                 "gl_Position = projectionMatrix * mvPosition;",
36731
36732             "}"
36733
36734         ].join("\n"),
36735
36736         fragmentShader: [
36737
36738             "uniform float opacity;",
36739             "varying vec3 vNormal;",
36740
36741             "void main() {",
36742
36743                 "gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",
36744
36745             "}"
36746
36747         ].join("\n")
36748
36749     },
36750
36751     'basic': {
36752
36753         uniforms: THREE.UniformsUtils.merge( [
36754
36755             THREE.UniformsLib[ "common" ],
36756             THREE.UniformsLib[ "fog" ],
36757             THREE.UniformsLib[ "shadowmap" ]
36758
36759         ] ),
36760
36761         vertexShader: [
36762
36763             THREE.ShaderChunk[ "map_pars_vertex" ],
36764             THREE.ShaderChunk[ "lightmap_pars_vertex" ],
36765             THREE.ShaderChunk[ "envmap_pars_vertex" ],
36766             THREE.ShaderChunk[ "color_pars_vertex" ],
36767             THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
36768             THREE.ShaderChunk[ "skinning_pars_vertex" ],
36769             THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
36770
36771             "void main() {",
36772
36773                 THREE.ShaderChunk[ "map_vertex" ],
36774                 THREE.ShaderChunk[ "lightmap_vertex" ],
36775                 THREE.ShaderChunk[ "color_vertex" ],
36776
36777                 "#ifdef USE_ENVMAP",
36778
36779                 THREE.ShaderChunk[ "morphnormal_vertex" ],
36780                 THREE.ShaderChunk[ "skinbase_vertex" ],
36781                 THREE.ShaderChunk[ "skinnormal_vertex" ],
36782                 THREE.ShaderChunk[ "defaultnormal_vertex" ],
36783
36784                 "#endif",
36785
36786                 THREE.ShaderChunk[ "morphtarget_vertex" ],
36787                 THREE.ShaderChunk[ "skinning_vertex" ],
36788                 THREE.ShaderChunk[ "default_vertex" ],
36789
36790                 THREE.ShaderChunk[ "worldpos_vertex" ],
36791                 THREE.ShaderChunk[ "envmap_vertex" ],
36792                 THREE.ShaderChunk[ "shadowmap_vertex" ],
36793
36794             "}"
36795
36796         ].join("\n"),
36797
36798         fragmentShader: [
36799
36800             "uniform vec3 diffuse;",
36801             "uniform float opacity;",
36802
36803             THREE.ShaderChunk[ "color_pars_fragment" ],
36804             THREE.ShaderChunk[ "map_pars_fragment" ],
36805             THREE.ShaderChunk[ "lightmap_pars_fragment" ],
36806             THREE.ShaderChunk[ "envmap_pars_fragment" ],
36807             THREE.ShaderChunk[ "fog_pars_fragment" ],
36808             THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
36809             THREE.ShaderChunk[ "specularmap_pars_fragment" ],
36810
36811             "void main() {",
36812
36813                 "gl_FragColor = vec4( diffuse, opacity );",
36814
36815                 THREE.ShaderChunk[ "map_fragment" ],
36816                 THREE.ShaderChunk[ "alphatest_fragment" ],
36817                 THREE.ShaderChunk[ "specularmap_fragment" ],
36818                 THREE.ShaderChunk[ "lightmap_fragment" ],
36819                 THREE.ShaderChunk[ "color_fragment" ],
36820                 THREE.ShaderChunk[ "envmap_fragment" ],
36821                 THREE.ShaderChunk[ "shadowmap_fragment" ],
36822
36823                 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
36824
36825                 THREE.ShaderChunk[ "fog_fragment" ],
36826
36827             "}"
36828
36829         ].join("\n")
36830
36831     },
36832
36833     'lambert': {
36834
36835         uniforms: THREE.UniformsUtils.merge( [
36836
36837             THREE.UniformsLib[ "common" ],
36838             THREE.UniformsLib[ "fog" ],
36839             THREE.UniformsLib[ "lights" ],
36840             THREE.UniformsLib[ "shadowmap" ],
36841
36842             {
36843                 "ambient"  : { type: "c", value: new THREE.Color( 0xffffff ) },
36844                 "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
36845                 "wrapRGB"  : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
36846             }
36847
36848         ] ),
36849
36850         vertexShader: [
36851
36852             "#define LAMBERT",
36853
36854             "varying vec3 vLightFront;",
36855
36856             "#ifdef DOUBLE_SIDED",
36857
36858                 "varying vec3 vLightBack;",
36859
36860             "#endif",
36861
36862             THREE.ShaderChunk[ "map_pars_vertex" ],
36863             THREE.ShaderChunk[ "lightmap_pars_vertex" ],
36864             THREE.ShaderChunk[ "envmap_pars_vertex" ],
36865             THREE.ShaderChunk[ "lights_lambert_pars_vertex" ],
36866             THREE.ShaderChunk[ "color_pars_vertex" ],
36867             THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
36868             THREE.ShaderChunk[ "skinning_pars_vertex" ],
36869             THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
36870
36871             "void main() {",
36872
36873                 THREE.ShaderChunk[ "map_vertex" ],
36874                 THREE.ShaderChunk[ "lightmap_vertex" ],
36875                 THREE.ShaderChunk[ "color_vertex" ],
36876
36877                 THREE.ShaderChunk[ "morphnormal_vertex" ],
36878                 THREE.ShaderChunk[ "skinbase_vertex" ],
36879                 THREE.ShaderChunk[ "skinnormal_vertex" ],
36880                 THREE.ShaderChunk[ "defaultnormal_vertex" ],
36881
36882                 THREE.ShaderChunk[ "morphtarget_vertex" ],
36883                 THREE.ShaderChunk[ "skinning_vertex" ],
36884                 THREE.ShaderChunk[ "default_vertex" ],
36885
36886                 THREE.ShaderChunk[ "worldpos_vertex" ],
36887                 THREE.ShaderChunk[ "envmap_vertex" ],
36888                 THREE.ShaderChunk[ "lights_lambert_vertex" ],
36889                 THREE.ShaderChunk[ "shadowmap_vertex" ],
36890
36891             "}"
36892
36893         ].join("\n"),
36894
36895         fragmentShader: [
36896
36897             "uniform float opacity;",
36898
36899             "varying vec3 vLightFront;",
36900
36901             "#ifdef DOUBLE_SIDED",
36902
36903                 "varying vec3 vLightBack;",
36904
36905             "#endif",
36906
36907             THREE.ShaderChunk[ "color_pars_fragment" ],
36908             THREE.ShaderChunk[ "map_pars_fragment" ],
36909             THREE.ShaderChunk[ "lightmap_pars_fragment" ],
36910             THREE.ShaderChunk[ "envmap_pars_fragment" ],
36911             THREE.ShaderChunk[ "fog_pars_fragment" ],
36912             THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
36913             THREE.ShaderChunk[ "specularmap_pars_fragment" ],
36914
36915             "void main() {",
36916
36917                 "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",
36918
36919                 THREE.ShaderChunk[ "map_fragment" ],
36920                 THREE.ShaderChunk[ "alphatest_fragment" ],
36921                 THREE.ShaderChunk[ "specularmap_fragment" ],
36922
36923                 "#ifdef DOUBLE_SIDED",
36924
36925                     //"float isFront = float( gl_FrontFacing );",
36926                     //"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;",
36927
36928                     "if ( gl_FrontFacing )",
36929                         "gl_FragColor.xyz *= vLightFront;",
36930                     "else",
36931                         "gl_FragColor.xyz *= vLightBack;",
36932
36933                 "#else",
36934
36935                     "gl_FragColor.xyz *= vLightFront;",
36936
36937                 "#endif",
36938
36939                 THREE.ShaderChunk[ "lightmap_fragment" ],
36940                 THREE.ShaderChunk[ "color_fragment" ],
36941                 THREE.ShaderChunk[ "envmap_fragment" ],
36942                 THREE.ShaderChunk[ "shadowmap_fragment" ],
36943
36944                 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
36945
36946                 THREE.ShaderChunk[ "fog_fragment" ],
36947
36948             "}"
36949
36950         ].join("\n")
36951
36952     },
36953
36954     'phong': {
36955
36956         uniforms: THREE.UniformsUtils.merge( [
36957
36958             THREE.UniformsLib[ "common" ],
36959             THREE.UniformsLib[ "bump" ],
36960             THREE.UniformsLib[ "normalmap" ],
36961             THREE.UniformsLib[ "fog" ],
36962             THREE.UniformsLib[ "lights" ],
36963             THREE.UniformsLib[ "shadowmap" ],
36964
36965             {
36966                 "ambient"  : { type: "c", value: new THREE.Color( 0xffffff ) },
36967                 "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
36968                 "specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
36969                 "shininess": { type: "f", value: 30 },
36970                 "wrapRGB"  : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
36971             }
36972
36973         ] ),
36974
36975         vertexShader: [
36976
36977             "#define PHONG",
36978
36979             "varying vec3 vViewPosition;",
36980             "varying vec3 vNormal;",
36981
36982             THREE.ShaderChunk[ "map_pars_vertex" ],
36983             THREE.ShaderChunk[ "lightmap_pars_vertex" ],
36984             THREE.ShaderChunk[ "envmap_pars_vertex" ],
36985             THREE.ShaderChunk[ "lights_phong_pars_vertex" ],
36986             THREE.ShaderChunk[ "color_pars_vertex" ],
36987             THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
36988             THREE.ShaderChunk[ "skinning_pars_vertex" ],
36989             THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
36990
36991             "void main() {",
36992
36993                 THREE.ShaderChunk[ "map_vertex" ],
36994                 THREE.ShaderChunk[ "lightmap_vertex" ],
36995                 THREE.ShaderChunk[ "color_vertex" ],
36996
36997                 THREE.ShaderChunk[ "morphnormal_vertex" ],
36998                 THREE.ShaderChunk[ "skinbase_vertex" ],
36999                 THREE.ShaderChunk[ "skinnormal_vertex" ],
37000                 THREE.ShaderChunk[ "defaultnormal_vertex" ],
37001
37002                 "vNormal = transformedNormal;",
37003
37004                 THREE.ShaderChunk[ "morphtarget_vertex" ],
37005                 THREE.ShaderChunk[ "skinning_vertex" ],
37006                 THREE.ShaderChunk[ "default_vertex" ],
37007
37008                 "vViewPosition = -mvPosition.xyz;",
37009
37010                 THREE.ShaderChunk[ "worldpos_vertex" ],
37011                 THREE.ShaderChunk[ "envmap_vertex" ],
37012                 THREE.ShaderChunk[ "lights_phong_vertex" ],
37013                 THREE.ShaderChunk[ "shadowmap_vertex" ],
37014
37015             "}"
37016
37017         ].join("\n"),
37018
37019         fragmentShader: [
37020
37021             "uniform vec3 diffuse;",
37022             "uniform float opacity;",
37023
37024             "uniform vec3 ambient;",
37025             "uniform vec3 emissive;",
37026             "uniform vec3 specular;",
37027             "uniform float shininess;",
37028
37029             THREE.ShaderChunk[ "color_pars_fragment" ],
37030             THREE.ShaderChunk[ "map_pars_fragment" ],
37031             THREE.ShaderChunk[ "lightmap_pars_fragment" ],
37032             THREE.ShaderChunk[ "envmap_pars_fragment" ],
37033             THREE.ShaderChunk[ "fog_pars_fragment" ],
37034             THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
37035             THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
37036             THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
37037             THREE.ShaderChunk[ "normalmap_pars_fragment" ],
37038             THREE.ShaderChunk[ "specularmap_pars_fragment" ],
37039
37040             "void main() {",
37041
37042                 "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",
37043
37044                 THREE.ShaderChunk[ "map_fragment" ],
37045                 THREE.ShaderChunk[ "alphatest_fragment" ],
37046                 THREE.ShaderChunk[ "specularmap_fragment" ],
37047
37048                 THREE.ShaderChunk[ "lights_phong_fragment" ],
37049
37050                 THREE.ShaderChunk[ "lightmap_fragment" ],
37051                 THREE.ShaderChunk[ "color_fragment" ],
37052                 THREE.ShaderChunk[ "envmap_fragment" ],
37053                 THREE.ShaderChunk[ "shadowmap_fragment" ],
37054
37055                 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
37056
37057                 THREE.ShaderChunk[ "fog_fragment" ],
37058
37059             "}"
37060
37061         ].join("\n")
37062
37063     },
37064
37065     'particle_basic': {
37066
37067         uniforms:  THREE.UniformsUtils.merge( [
37068
37069             THREE.UniformsLib[ "particle" ],
37070             THREE.UniformsLib[ "shadowmap" ]
37071
37072         ] ),
37073
37074         vertexShader: [
37075
37076             "uniform float size;",
37077             "uniform float scale;",
37078
37079             THREE.ShaderChunk[ "color_pars_vertex" ],
37080             THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
37081
37082             "void main() {",
37083
37084                 THREE.ShaderChunk[ "color_vertex" ],
37085
37086                 "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
37087
37088                 "#ifdef USE_SIZEATTENUATION",
37089                     "gl_PointSize = size * ( scale / length( mvPosition.xyz ) );",
37090                 "#else",
37091                     "gl_PointSize = size;",
37092                 "#endif",
37093
37094                 "gl_Position = projectionMatrix * mvPosition;",
37095
37096                 THREE.ShaderChunk[ "worldpos_vertex" ],
37097                 THREE.ShaderChunk[ "shadowmap_vertex" ],
37098
37099             "}"
37100
37101         ].join("\n"),
37102
37103         fragmentShader: [
37104
37105             "uniform vec3 psColor;",
37106             "uniform float opacity;",
37107
37108             THREE.ShaderChunk[ "color_pars_fragment" ],
37109             THREE.ShaderChunk[ "map_particle_pars_fragment" ],
37110             THREE.ShaderChunk[ "fog_pars_fragment" ],
37111             THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
37112
37113             "void main() {",
37114
37115                 "gl_FragColor = vec4( psColor, opacity );",
37116
37117                 THREE.ShaderChunk[ "map_particle_fragment" ],
37118                 THREE.ShaderChunk[ "alphatest_fragment" ],
37119                 THREE.ShaderChunk[ "color_fragment" ],
37120                 THREE.ShaderChunk[ "shadowmap_fragment" ],
37121                 THREE.ShaderChunk[ "fog_fragment" ],
37122
37123             "}"
37124
37125         ].join("\n")
37126
37127     },
37128
37129     // Depth encoding into RGBA texture
37130     //     based on SpiderGL shadow map example
37131     //         http://spidergl.org/example.php?id=6
37132     //     originally from
37133     //        http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD
37134     //     see also here:
37135     //        http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/
37136
37137     'depthRGBA': {
37138
37139         uniforms: {},
37140
37141         vertexShader: [
37142
37143             THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
37144             THREE.ShaderChunk[ "skinning_pars_vertex" ],
37145
37146             "void main() {",
37147
37148                 THREE.ShaderChunk[ "skinbase_vertex" ],
37149                 THREE.ShaderChunk[ "morphtarget_vertex" ],
37150                 THREE.ShaderChunk[ "skinning_vertex" ],
37151                 THREE.ShaderChunk[ "default_vertex" ],
37152
37153             "}"
37154
37155         ].join("\n"),
37156
37157         fragmentShader: [
37158
37159             "vec4 pack_depth( const in float depth ) {",
37160
37161                 "const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );",
37162                 "const vec4 bit_mask  = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );",
37163                 "vec4 res = fract( depth * bit_shift );",
37164                 "res -= res.xxyz * bit_mask;",
37165                 "return res;",
37166
37167             "}",
37168
37169             "void main() {",
37170
37171                 "gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );",
37172
37173                 //"gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z / gl_FragCoord.w );",
37174                 //"float z = ( ( gl_FragCoord.z / gl_FragCoord.w ) - 3.0 ) / ( 4000.0 - 3.0 );",
37175                 //"gl_FragData[ 0 ] = pack_depth( z );",
37176                 //"gl_FragData[ 0 ] = vec4( z, z, z, 1.0 );",
37177
37178             "}"
37179
37180         ].join("\n")
37181
37182     }
37183
37184 };
37185 /**
37186  * @author supereggbert / http://www.paulbrunt.co.uk/
37187  * @author mrdoob / http://mrdoob.com/
37188  * @author alteredq / http://alteredqualia.com/
37189  * @author szimek / https://github.com/szimek/
37190  */
37191
37192 THREE.WebGLRenderer = function ( parameters ) {
37193
37194     console.log( 'THREE.WebGLRenderer', THREE.REVISION );
37195
37196     parameters = parameters || {};
37197
37198     var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
37199
37200     _precision = parameters.precision !== undefined ? parameters.precision : 'highp',
37201
37202     _alpha = parameters.alpha !== undefined ? parameters.alpha : true,
37203     _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
37204     _antialias = parameters.antialias !== undefined ? parameters.antialias : false,
37205     _stencil = parameters.stencil !== undefined ? parameters.stencil : true,
37206     _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
37207
37208     _clearColor = parameters.clearColor !== undefined ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 ),
37209     _clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0,
37210
37211     _maxLights = parameters.maxLights !== undefined ? parameters.maxLights : 4;
37212
37213     // public properties
37214
37215     this.domElement = _canvas;
37216     this.context = null;
37217
37218     // clearing
37219
37220     this.autoClear = true;
37221     this.autoClearColor = true;
37222     this.autoClearDepth = true;
37223     this.autoClearStencil = true;
37224
37225     // scene graph
37226
37227     this.sortObjects = true;
37228
37229     this.autoUpdateObjects = true;
37230     this.autoUpdateScene = true;
37231
37232     // physically based shading
37233
37234     this.gammaInput = false;
37235     this.gammaOutput = false;
37236     this.physicallyBasedShading = false;
37237
37238     // shadow map
37239
37240     this.shadowMapEnabled = false;
37241     this.shadowMapAutoUpdate = true;
37242     this.shadowMapSoft = true;
37243     this.shadowMapCullFrontFaces = true;
37244     this.shadowMapDebug = false;
37245     this.shadowMapCascade = false;
37246
37247     // morphs
37248
37249     this.maxMorphTargets = 8;
37250     this.maxMorphNormals = 4;
37251
37252     // flags
37253
37254     this.autoScaleCubemaps = true;
37255
37256     // custom render plugins
37257
37258     this.renderPluginsPre = [];
37259     this.renderPluginsPost = [];
37260
37261     // info
37262
37263     this.info = {
37264
37265         memory: {
37266
37267             programs: 0,
37268             geometries: 0,
37269             textures: 0
37270
37271         },
37272
37273         render: {
37274
37275             calls: 0,
37276             vertices: 0,
37277             faces: 0,
37278             points: 0
37279
37280         }
37281
37282     };
37283
37284     // internal properties
37285
37286     var _this = this,
37287
37288     _programs = [],
37289     _programs_counter = 0,
37290
37291     // internal state cache
37292
37293     _currentProgram = null,
37294     _currentFramebuffer = null,
37295     _currentMaterialId = -1,
37296     _currentGeometryGroupHash = null,
37297     _currentCamera = null,
37298     _geometryGroupCounter = 0,
37299
37300     _usedTextureUnits = 0,
37301
37302     // GL state cache
37303
37304     _oldDoubleSided = -1,
37305     _oldFlipSided = -1,
37306
37307     _oldBlending = -1,
37308
37309     _oldBlendEquation = -1,
37310     _oldBlendSrc = -1,
37311     _oldBlendDst = -1,
37312
37313     _oldDepthTest = -1,
37314     _oldDepthWrite = -1,
37315
37316     _oldPolygonOffset = null,
37317     _oldPolygonOffsetFactor = null,
37318     _oldPolygonOffsetUnits = null,
37319
37320     _oldLineWidth = null,
37321
37322     _viewportX = 0,
37323     _viewportY = 0,
37324     _viewportWidth = 0,
37325     _viewportHeight = 0,
37326     _currentWidth = 0,
37327     _currentHeight = 0,
37328
37329     // frustum
37330
37331     _frustum = new THREE.Frustum(),
37332
37333      // camera matrices cache
37334
37335     _projScreenMatrix = new THREE.Matrix4(),
37336     _projScreenMatrixPS = new THREE.Matrix4(),
37337
37338     _vector3 = new THREE.Vector4(),
37339
37340     // light arrays cache
37341
37342     _direction = new THREE.Vector3(),
37343
37344     _lightsNeedUpdate = true,
37345
37346     _lights = {
37347
37348         ambient: [ 0, 0, 0 ],
37349         directional: { length: 0, colors: new Array(), positions: new Array() },
37350         point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() },
37351         spot: { length: 0, colors: new Array(), positions: new Array(), distances: new Array(), directions: new Array(), angles: new Array(), exponents: new Array() },
37352         hemi: { length: 0, skyColors: new Array(), groundColors: new Array(), positions: new Array() }
37353
37354     };
37355
37356     // initialize
37357
37358     var _gl;
37359
37360     var _glExtensionTextureFloat;
37361     var _glExtensionStandardDerivatives;
37362     var _glExtensionTextureFilterAnisotropic;
37363     var _glExtensionCompressedTextureS3TC;
37364
37365     initGL();
37366
37367     setDefaultGLState();
37368
37369     this.context = _gl;
37370
37371     // GPU capabilities
37372
37373     var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS );
37374     var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
37375     var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE );
37376     var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
37377
37378     var _maxAnisotropy = _glExtensionTextureFilterAnisotropic ? _gl.getParameter( _glExtensionTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT ) : 0;
37379
37380     var _supportsVertexTextures = ( _maxVertexTextures > 0 );
37381     var _supportsBoneTextures = _supportsVertexTextures && _glExtensionTextureFloat;
37382
37383     var _compressedTextureFormats = _glExtensionCompressedTextureS3TC ? _gl.getParameter( _gl.COMPRESSED_TEXTURE_FORMATS ) : [];
37384
37385     // API
37386
37387     this.getContext = function () {
37388
37389         return _gl;
37390
37391     };
37392
37393     this.supportsVertexTextures = function () {
37394
37395         return _supportsVertexTextures;
37396
37397     };
37398
37399     this.getMaxAnisotropy  = function () {
37400
37401         return _maxAnisotropy;
37402
37403     };
37404
37405     this.setSize = function ( width, height ) {
37406
37407         _canvas.width = width;
37408         _canvas.height = height;
37409
37410         this.setViewport( 0, 0, _canvas.width, _canvas.height );
37411
37412     };
37413
37414     this.setViewport = function ( x, y, width, height ) {
37415
37416         _viewportX = x !== undefined ? x : 0;
37417         _viewportY = y !== undefined ? y : 0;
37418
37419         _viewportWidth = width !== undefined ? width : _canvas.width;
37420         _viewportHeight = height !== undefined ? height : _canvas.height;
37421
37422         _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
37423
37424     };
37425
37426     this.setScissor = function ( x, y, width, height ) {
37427
37428         _gl.scissor( x, y, width, height );
37429
37430     };
37431
37432     this.enableScissorTest = function ( enable ) {
37433
37434         enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
37435
37436     };
37437
37438     // Clearing
37439
37440     this.setClearColorHex = function ( hex, alpha ) {
37441
37442         _clearColor.setHex( hex );
37443         _clearAlpha = alpha;
37444
37445         _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
37446
37447     };
37448
37449     this.setClearColor = function ( color, alpha ) {
37450
37451         _clearColor.copy( color );
37452         _clearAlpha = alpha;
37453
37454         _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
37455
37456     };
37457
37458     this.getClearColor = function () {
37459
37460         return _clearColor;
37461
37462     };
37463
37464     this.getClearAlpha = function () {
37465
37466         return _clearAlpha;
37467
37468     };
37469
37470     this.clear = function ( color, depth, stencil ) {
37471
37472         var bits = 0;
37473
37474         if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
37475         if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
37476         if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
37477
37478         _gl.clear( bits );
37479
37480     };
37481
37482     this.clearTarget = function ( renderTarget, color, depth, stencil ) {
37483
37484         this.setRenderTarget( renderTarget );
37485         this.clear( color, depth, stencil );
37486
37487     };
37488
37489     // Plugins
37490
37491     this.addPostPlugin = function ( plugin ) {
37492
37493         plugin.init( this );
37494         this.renderPluginsPost.push( plugin );
37495
37496     };
37497
37498     this.addPrePlugin = function ( plugin ) {
37499
37500         plugin.init( this );
37501         this.renderPluginsPre.push( plugin );
37502
37503     };
37504
37505     // Deallocation
37506
37507     this.deallocateObject = function ( object ) {
37508
37509         if ( ! object.__webglInit ) return;
37510
37511         object.__webglInit = false;
37512
37513         delete object._modelViewMatrix;
37514         delete object._normalMatrix;
37515
37516         delete object._normalMatrixArray;
37517         delete object._modelViewMatrixArray;
37518         delete object._modelMatrixArray;
37519
37520         if ( object instanceof THREE.Mesh ) {
37521
37522             for ( var g in object.geometry.geometryGroups ) {
37523
37524                 deleteMeshBuffers( object.geometry.geometryGroups[ g ] );
37525
37526             }
37527
37528         } else if ( object instanceof THREE.Ribbon ) {
37529
37530             deleteRibbonBuffers( object.geometry );
37531
37532         } else if ( object instanceof THREE.Line ) {
37533
37534             deleteLineBuffers( object.geometry );
37535
37536         } else if ( object instanceof THREE.ParticleSystem ) {
37537
37538             deleteParticleBuffers( object.geometry );
37539
37540         }
37541
37542     };
37543
37544     this.deallocateTexture = function ( texture ) {
37545
37546         if ( ! texture.__webglInit ) return;
37547
37548         texture.__webglInit = false;
37549         _gl.deleteTexture( texture.__webglTexture );
37550
37551         _this.info.memory.textures --;
37552
37553     };
37554
37555     this.deallocateRenderTarget = function ( renderTarget ) {
37556
37557         if ( !renderTarget || ! renderTarget.__webglTexture ) return;
37558
37559         _gl.deleteTexture( renderTarget.__webglTexture );
37560
37561         if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
37562
37563             for ( var i = 0; i < 6; i ++ ) {
37564
37565                 _gl.deleteFramebuffer( renderTarget.__webglFramebuffer[ i ] );
37566                 _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer[ i ] );
37567
37568             }
37569
37570         } else {
37571
37572             _gl.deleteFramebuffer( renderTarget.__webglFramebuffer );
37573             _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer );
37574
37575         }
37576
37577     };
37578
37579     this.deallocateMaterial = function ( material ) {
37580
37581         var program = material.program;
37582
37583         if ( ! program ) return;
37584
37585         material.program = undefined;
37586
37587         // only deallocate GL program if this was the last use of shared program
37588         // assumed there is only single copy of any program in the _programs list
37589         // (that's how it's constructed)
37590
37591         var i, il, programInfo;
37592         var deleteProgram = false;
37593
37594         for ( i = 0, il = _programs.length; i < il; i ++ ) {
37595
37596             programInfo = _programs[ i ];
37597
37598             if ( programInfo.program === program ) {
37599
37600                 programInfo.usedTimes --;
37601
37602                 if ( programInfo.usedTimes === 0 ) {
37603
37604                     deleteProgram = true;
37605
37606                 }
37607
37608                 break;
37609
37610             }
37611
37612         }
37613
37614         if ( deleteProgram ) {
37615
37616             // avoid using array.splice, this is costlier than creating new array from scratch
37617
37618             var newPrograms = [];
37619
37620             for ( i = 0, il = _programs.length; i < il; i ++ ) {
37621
37622                 programInfo = _programs[ i ];
37623
37624                 if ( programInfo.program !== program ) {
37625
37626                     newPrograms.push( programInfo );
37627
37628                 }
37629
37630             }
37631
37632             _programs = newPrograms;
37633
37634             _gl.deleteProgram( program );
37635
37636             _this.info.memory.programs --;
37637
37638         }
37639
37640     };
37641
37642     // Rendering
37643
37644     this.updateShadowMap = function ( scene, camera ) {
37645
37646         _currentProgram = null;
37647         _oldBlending = -1;
37648         _oldDepthTest = -1;
37649         _oldDepthWrite = -1;
37650         _currentGeometryGroupHash = -1;
37651         _currentMaterialId = -1;
37652         _lightsNeedUpdate = true;
37653         _oldDoubleSided = -1;
37654         _oldFlipSided = -1;
37655
37656         this.shadowMapPlugin.update( scene, camera );
37657
37658     };
37659
37660     // Internal functions
37661
37662     // Buffer allocation
37663
37664     function createParticleBuffers ( geometry ) {
37665
37666         geometry.__webglVertexBuffer = _gl.createBuffer();
37667         geometry.__webglColorBuffer = _gl.createBuffer();
37668
37669         _this.info.memory.geometries ++;
37670
37671     };
37672
37673     function createLineBuffers ( geometry ) {
37674
37675         geometry.__webglVertexBuffer = _gl.createBuffer();
37676         geometry.__webglColorBuffer = _gl.createBuffer();
37677
37678         _this.info.memory.geometries ++;
37679
37680     };
37681
37682     function createRibbonBuffers ( geometry ) {
37683
37684         geometry.__webglVertexBuffer = _gl.createBuffer();
37685         geometry.__webglColorBuffer = _gl.createBuffer();
37686
37687         _this.info.memory.geometries ++;
37688
37689     };
37690
37691     function createMeshBuffers ( geometryGroup ) {
37692
37693         geometryGroup.__webglVertexBuffer = _gl.createBuffer();
37694         geometryGroup.__webglNormalBuffer = _gl.createBuffer();
37695         geometryGroup.__webglTangentBuffer = _gl.createBuffer();
37696         geometryGroup.__webglColorBuffer = _gl.createBuffer();
37697         geometryGroup.__webglUVBuffer = _gl.createBuffer();
37698         geometryGroup.__webglUV2Buffer = _gl.createBuffer();
37699
37700         geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
37701         geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
37702
37703         geometryGroup.__webglFaceBuffer = _gl.createBuffer();
37704         geometryGroup.__webglLineBuffer = _gl.createBuffer();
37705
37706         var m, ml;
37707
37708         if ( geometryGroup.numMorphTargets ) {
37709
37710             geometryGroup.__webglMorphTargetsBuffers = [];
37711
37712             for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
37713
37714                 geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
37715
37716             }
37717
37718         }
37719
37720         if ( geometryGroup.numMorphNormals ) {
37721
37722             geometryGroup.__webglMorphNormalsBuffers = [];
37723
37724             for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
37725
37726                 geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
37727
37728             }
37729
37730         }
37731
37732         _this.info.memory.geometries ++;
37733
37734     };
37735
37736     // Buffer deallocation
37737
37738     function deleteParticleBuffers ( geometry ) {
37739
37740         _gl.deleteBuffer( geometry.__webglVertexBuffer );
37741         _gl.deleteBuffer( geometry.__webglColorBuffer );
37742
37743         _this.info.memory.geometries --;
37744
37745     };
37746
37747     function deleteLineBuffers ( geometry ) {
37748
37749         _gl.deleteBuffer( geometry.__webglVertexBuffer );
37750         _gl.deleteBuffer( geometry.__webglColorBuffer );
37751
37752         _this.info.memory.geometries --;
37753
37754     };
37755
37756     function deleteRibbonBuffers ( geometry ) {
37757
37758         _gl.deleteBuffer( geometry.__webglVertexBuffer );
37759         _gl.deleteBuffer( geometry.__webglColorBuffer );
37760
37761         _this.info.memory.geometries --;
37762
37763     };
37764
37765     function deleteMeshBuffers ( geometryGroup ) {
37766
37767         _gl.deleteBuffer( geometryGroup.__webglVertexBuffer );
37768         _gl.deleteBuffer( geometryGroup.__webglNormalBuffer );
37769         _gl.deleteBuffer( geometryGroup.__webglTangentBuffer );
37770         _gl.deleteBuffer( geometryGroup.__webglColorBuffer );
37771         _gl.deleteBuffer( geometryGroup.__webglUVBuffer );
37772         _gl.deleteBuffer( geometryGroup.__webglUV2Buffer );
37773
37774         _gl.deleteBuffer( geometryGroup.__webglSkinIndicesBuffer );
37775         _gl.deleteBuffer( geometryGroup.__webglSkinWeightsBuffer );
37776
37777         _gl.deleteBuffer( geometryGroup.__webglFaceBuffer );
37778         _gl.deleteBuffer( geometryGroup.__webglLineBuffer );
37779
37780         var m, ml;
37781
37782         if ( geometryGroup.numMorphTargets ) {
37783
37784             for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
37785
37786                 _gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
37787
37788             }
37789
37790         }
37791
37792         if ( geometryGroup.numMorphNormals ) {
37793
37794             for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
37795
37796                 _gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
37797
37798             }
37799
37800         }
37801
37802
37803         if ( geometryGroup.__webglCustomAttributesList ) {
37804
37805             for ( var id in geometryGroup.__webglCustomAttributesList ) {
37806
37807                 _gl.deleteBuffer( geometryGroup.__webglCustomAttributesList[ id ].buffer );
37808
37809             }
37810
37811         }
37812
37813         _this.info.memory.geometries --;
37814
37815     };
37816
37817     // Buffer initialization
37818
37819     function initCustomAttributes ( geometry, object ) {
37820
37821         var nvertices = geometry.vertices.length;
37822
37823         var material = object.material;
37824
37825         if ( material.attributes ) {
37826
37827             if ( geometry.__webglCustomAttributesList === undefined ) {
37828
37829                 geometry.__webglCustomAttributesList = [];
37830
37831             }
37832
37833             for ( var a in material.attributes ) {
37834
37835                 var attribute = material.attributes[ a ];
37836
37837                 if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
37838
37839                     attribute.__webglInitialized = true;
37840
37841                     var size = 1;        // "f" and "i"
37842
37843                     if ( attribute.type === "v2" ) size = 2;
37844                     else if ( attribute.type === "v3" ) size = 3;
37845                     else if ( attribute.type === "v4" ) size = 4;
37846                     else if ( attribute.type === "c"  ) size = 3;
37847
37848                     attribute.size = size;
37849
37850                     attribute.array = new Float32Array( nvertices * size );
37851
37852                     attribute.buffer = _gl.createBuffer();
37853                     attribute.buffer.belongsToAttribute = a;
37854
37855                     attribute.needsUpdate = true;
37856
37857                 }
37858
37859                 geometry.__webglCustomAttributesList.push( attribute );
37860
37861             }
37862
37863         }
37864
37865     };
37866
37867     function initParticleBuffers ( geometry, object ) {
37868
37869         var nvertices = geometry.vertices.length;
37870
37871         geometry.__vertexArray = new Float32Array( nvertices * 3 );
37872         geometry.__colorArray = new Float32Array( nvertices * 3 );
37873
37874         geometry.__sortArray = [];
37875
37876         geometry.__webglParticleCount = nvertices;
37877
37878         initCustomAttributes ( geometry, object );
37879
37880     };
37881
37882     function initLineBuffers ( geometry, object ) {
37883
37884         var nvertices = geometry.vertices.length;
37885
37886         geometry.__vertexArray = new Float32Array( nvertices * 3 );
37887         geometry.__colorArray = new Float32Array( nvertices * 3 );
37888
37889         geometry.__webglLineCount = nvertices;
37890
37891         initCustomAttributes ( geometry, object );
37892
37893     };
37894
37895     function initRibbonBuffers ( geometry ) {
37896
37897         var nvertices = geometry.vertices.length;
37898
37899         geometry.__vertexArray = new Float32Array( nvertices * 3 );
37900         geometry.__colorArray = new Float32Array( nvertices * 3 );
37901
37902         geometry.__webglVertexCount = nvertices;
37903
37904     };
37905
37906     function initMeshBuffers ( geometryGroup, object ) {
37907
37908         var geometry = object.geometry,
37909             faces3 = geometryGroup.faces3,
37910             faces4 = geometryGroup.faces4,
37911
37912             nvertices = faces3.length * 3 + faces4.length * 4,
37913             ntris     = faces3.length * 1 + faces4.length * 2,
37914             nlines    = faces3.length * 3 + faces4.length * 4,
37915
37916             material = getBufferMaterial( object, geometryGroup ),
37917
37918             uvType = bufferGuessUVType( material ),
37919             normalType = bufferGuessNormalType( material ),
37920             vertexColorType = bufferGuessVertexColorType( material );
37921
37922         //console.log( "uvType", uvType, "normalType", normalType, "vertexColorType", vertexColorType, object, geometryGroup, material );
37923
37924         geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
37925
37926         if ( normalType ) {
37927
37928             geometryGroup.__normalArray = new Float32Array( nvertices * 3 );
37929
37930         }
37931
37932         if ( geometry.hasTangents ) {
37933
37934             geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
37935
37936         }
37937
37938         if ( vertexColorType ) {
37939
37940             geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
37941
37942         }
37943
37944         if ( uvType ) {
37945
37946             if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
37947
37948                 geometryGroup.__uvArray = new Float32Array( nvertices * 2 );
37949
37950             }
37951
37952             if ( geometry.faceUvs.length > 1 || geometry.faceVertexUvs.length > 1 ) {
37953
37954                 geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );
37955
37956             }
37957
37958         }
37959
37960         if ( object.geometry.skinWeights.length && object.geometry.skinIndices.length ) {
37961
37962             geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
37963             geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );
37964
37965         }
37966
37967         geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
37968         geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
37969
37970         var m, ml;
37971
37972         if ( geometryGroup.numMorphTargets ) {
37973
37974             geometryGroup.__morphTargetsArrays = [];
37975
37976             for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
37977
37978                 geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
37979
37980             }
37981
37982         }
37983
37984         if ( geometryGroup.numMorphNormals ) {
37985
37986             geometryGroup.__morphNormalsArrays = [];
37987
37988             for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
37989
37990                 geometryGroup.__morphNormalsArrays.push( new Float32Array( nvertices * 3 ) );
37991
37992             }
37993
37994         }
37995
37996         geometryGroup.__webglFaceCount = ntris * 3;
37997         geometryGroup.__webglLineCount = nlines * 2;
37998
37999
38000         // custom attributes
38001
38002         if ( material.attributes ) {
38003
38004             if ( geometryGroup.__webglCustomAttributesList === undefined ) {
38005
38006                 geometryGroup.__webglCustomAttributesList = [];
38007
38008             }
38009
38010             for ( var a in material.attributes ) {
38011
38012                 // Do a shallow copy of the attribute object so different geometryGroup chunks use different
38013                 // attribute buffers which are correctly indexed in the setMeshBuffers function
38014
38015                 var originalAttribute = material.attributes[ a ];
38016
38017                 var attribute = {};
38018
38019                 for ( var property in originalAttribute ) {
38020
38021                     attribute[ property ] = originalAttribute[ property ];
38022
38023                 }
38024
38025                 if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
38026
38027                     attribute.__webglInitialized = true;
38028
38029                     var size = 1;        // "f" and "i"
38030
38031                     if( attribute.type === "v2" ) size = 2;
38032                     else if( attribute.type === "v3" ) size = 3;
38033                     else if( attribute.type === "v4" ) size = 4;
38034                     else if( attribute.type === "c"  ) size = 3;
38035
38036                     attribute.size = size;
38037
38038                     attribute.array = new Float32Array( nvertices * size );
38039
38040                     attribute.buffer = _gl.createBuffer();
38041                     attribute.buffer.belongsToAttribute = a;
38042
38043                     originalAttribute.needsUpdate = true;
38044                     attribute.__original = originalAttribute;
38045
38046                 }
38047
38048                 geometryGroup.__webglCustomAttributesList.push( attribute );
38049
38050             }
38051
38052         }
38053
38054         geometryGroup.__inittedArrays = true;
38055
38056     };
38057
38058     function getBufferMaterial( object, geometryGroup ) {
38059
38060         if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
38061
38062             return object.material;
38063
38064         } else if ( geometryGroup.materialIndex >= 0 ) {
38065
38066             return object.geometry.materials[ geometryGroup.materialIndex ];
38067
38068         }
38069
38070     };
38071
38072     function materialNeedsSmoothNormals ( material ) {
38073
38074         return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
38075
38076     };
38077
38078     function bufferGuessNormalType ( material ) {
38079
38080         // only MeshBasicMaterial and MeshDepthMaterial don't need normals
38081
38082         if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) {
38083
38084             return false;
38085
38086         }
38087
38088         if ( materialNeedsSmoothNormals( material ) ) {
38089
38090             return THREE.SmoothShading;
38091
38092         } else {
38093
38094             return THREE.FlatShading;
38095
38096         }
38097
38098     };
38099
38100     function bufferGuessVertexColorType ( material ) {
38101
38102         if ( material.vertexColors ) {
38103
38104             return material.vertexColors;
38105
38106         }
38107
38108         return false;
38109
38110     };
38111
38112     function bufferGuessUVType ( material ) {
38113
38114         // material must use some texture to require uvs
38115
38116         if ( material.map || material.lightMap || material.bumpMap || material.normalMap || material.specularMap || material instanceof THREE.ShaderMaterial ) {
38117
38118             return true;
38119
38120         }
38121
38122         return false;
38123
38124     };
38125
38126     //
38127
38128     function initDirectBuffers( geometry ) {
38129
38130         var a, attribute, type;
38131
38132         for ( a in geometry.attributes ) {
38133
38134             if ( a === "index" ) {
38135
38136                 type = _gl.ELEMENT_ARRAY_BUFFER;
38137
38138             } else {
38139
38140                 type = _gl.ARRAY_BUFFER;
38141
38142             }
38143
38144             attribute = geometry.attributes[ a ];
38145
38146             attribute.buffer = _gl.createBuffer();
38147
38148             _gl.bindBuffer( type, attribute.buffer );
38149             _gl.bufferData( type, attribute.array, _gl.STATIC_DRAW );
38150
38151         }
38152
38153     };
38154
38155     // Buffer setting
38156
38157     function setParticleBuffers ( geometry, hint, object ) {
38158
38159         var v, c, vertex, offset, index, color,
38160
38161         vertices = geometry.vertices,
38162         vl = vertices.length,
38163
38164         colors = geometry.colors,
38165         cl = colors.length,
38166
38167         vertexArray = geometry.__vertexArray,
38168         colorArray = geometry.__colorArray,
38169
38170         sortArray = geometry.__sortArray,
38171
38172         dirtyVertices = geometry.verticesNeedUpdate,
38173         dirtyElements = geometry.elementsNeedUpdate,
38174         dirtyColors = geometry.colorsNeedUpdate,
38175
38176         customAttributes = geometry.__webglCustomAttributesList,
38177         i, il,
38178         a, ca, cal, value,
38179         customAttribute;
38180
38181         if ( object.sortParticles ) {
38182
38183             _projScreenMatrixPS.copy( _projScreenMatrix );
38184             _projScreenMatrixPS.multiplySelf( object.matrixWorld );
38185
38186             for ( v = 0; v < vl; v ++ ) {
38187
38188                 vertex = vertices[ v ];
38189
38190                 _vector3.copy( vertex );
38191                 _projScreenMatrixPS.multiplyVector3( _vector3 );
38192
38193                 sortArray[ v ] = [ _vector3.z, v ];
38194
38195             }
38196
38197             sortArray.sort( function( a, b ) { return b[ 0 ] - a[ 0 ]; } );
38198
38199             for ( v = 0; v < vl; v ++ ) {
38200
38201                 vertex = vertices[ sortArray[v][1] ];
38202
38203                 offset = v * 3;
38204
38205                 vertexArray[ offset ]     = vertex.x;
38206                 vertexArray[ offset + 1 ] = vertex.y;
38207                 vertexArray[ offset + 2 ] = vertex.z;
38208
38209             }
38210
38211             for ( c = 0; c < cl; c ++ ) {
38212
38213                 offset = c * 3;
38214
38215                 color = colors[ sortArray[c][1] ];
38216
38217                 colorArray[ offset ]     = color.r;
38218                 colorArray[ offset + 1 ] = color.g;
38219                 colorArray[ offset + 2 ] = color.b;
38220
38221             }
38222
38223             if ( customAttributes ) {
38224
38225                 for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
38226
38227                     customAttribute = customAttributes[ i ];
38228
38229                     if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue;
38230
38231                     offset = 0;
38232
38233                     cal = customAttribute.value.length;
38234
38235                     if ( customAttribute.size === 1 ) {
38236
38237                         for ( ca = 0; ca < cal; ca ++ ) {
38238
38239                             index = sortArray[ ca ][ 1 ];
38240
38241                             customAttribute.array[ ca ] = customAttribute.value[ index ];
38242
38243                         }
38244
38245                     } else if ( customAttribute.size === 2 ) {
38246
38247                         for ( ca = 0; ca < cal; ca ++ ) {
38248
38249                             index = sortArray[ ca ][ 1 ];
38250
38251                             value = customAttribute.value[ index ];
38252
38253                             customAttribute.array[ offset ]     = value.x;
38254                             customAttribute.array[ offset + 1 ] = value.y;
38255
38256                             offset += 2;
38257
38258                         }
38259
38260                     } else if ( customAttribute.size === 3 ) {
38261
38262                         if ( customAttribute.type === "c" ) {
38263
38264                             for ( ca = 0; ca < cal; ca ++ ) {
38265
38266                                 index = sortArray[ ca ][ 1 ];
38267
38268                                 value = customAttribute.value[ index ];
38269
38270                                 customAttribute.array[ offset ]     = value.r;
38271                                 customAttribute.array[ offset + 1 ] = value.g;
38272                                 customAttribute.array[ offset + 2 ] = value.b;
38273
38274                                 offset += 3;
38275
38276                             }
38277
38278                         } else {
38279
38280                             for ( ca = 0; ca < cal; ca ++ ) {
38281
38282                                 index = sortArray[ ca ][ 1 ];
38283
38284                                 value = customAttribute.value[ index ];
38285
38286                                 customAttribute.array[ offset ]     = value.x;
38287                                 customAttribute.array[ offset + 1 ] = value.y;
38288                                 customAttribute.array[ offset + 2 ] = value.z;
38289
38290                                 offset += 3;
38291
38292                             }
38293
38294                         }
38295
38296                     } else if ( customAttribute.size === 4 ) {
38297
38298                         for ( ca = 0; ca < cal; ca ++ ) {
38299
38300                             index = sortArray[ ca ][ 1 ];
38301
38302                             value = customAttribute.value[ index ];
38303
38304                             customAttribute.array[ offset ]      = value.x;
38305                             customAttribute.array[ offset + 1  ] = value.y;
38306                             customAttribute.array[ offset + 2  ] = value.z;
38307                             customAttribute.array[ offset + 3  ] = value.w;
38308
38309                             offset += 4;
38310
38311                         }
38312
38313                     }
38314
38315                 }
38316
38317             }
38318
38319         } else {
38320
38321             if ( dirtyVertices ) {
38322
38323                 for ( v = 0; v < vl; v ++ ) {
38324
38325                     vertex = vertices[ v ];
38326
38327                     offset = v * 3;
38328
38329                     vertexArray[ offset ]     = vertex.x;
38330                     vertexArray[ offset + 1 ] = vertex.y;
38331                     vertexArray[ offset + 2 ] = vertex.z;
38332
38333                 }
38334
38335             }
38336
38337             if ( dirtyColors ) {
38338
38339                 for ( c = 0; c < cl; c ++ ) {
38340
38341                     color = colors[ c ];
38342
38343                     offset = c * 3;
38344
38345                     colorArray[ offset ]     = color.r;
38346                     colorArray[ offset + 1 ] = color.g;
38347                     colorArray[ offset + 2 ] = color.b;
38348
38349                 }
38350
38351             }
38352
38353             if ( customAttributes ) {
38354
38355                 for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
38356
38357                     customAttribute = customAttributes[ i ];
38358
38359                     if ( customAttribute.needsUpdate &&
38360                          ( customAttribute.boundTo === undefined ||
38361                            customAttribute.boundTo === "vertices") ) {
38362
38363                         cal = customAttribute.value.length;
38364
38365                         offset = 0;
38366
38367                         if ( customAttribute.size === 1 ) {
38368
38369                             for ( ca = 0; ca < cal; ca ++ ) {
38370
38371                                 customAttribute.array[ ca ] = customAttribute.value[ ca ];
38372
38373                             }
38374
38375                         } else if ( customAttribute.size === 2 ) {
38376
38377                             for ( ca = 0; ca < cal; ca ++ ) {
38378
38379                                 value = customAttribute.value[ ca ];
38380
38381                                 customAttribute.array[ offset ]     = value.x;
38382                                 customAttribute.array[ offset + 1 ] = value.y;
38383
38384                                 offset += 2;
38385
38386                             }
38387
38388                         } else if ( customAttribute.size === 3 ) {
38389
38390                             if ( customAttribute.type === "c" ) {
38391
38392                                 for ( ca = 0; ca < cal; ca ++ ) {
38393
38394                                     value = customAttribute.value[ ca ];
38395
38396                                     customAttribute.array[ offset ]     = value.r;
38397                                     customAttribute.array[ offset + 1 ] = value.g;
38398                                     customAttribute.array[ offset + 2 ] = value.b;
38399
38400                                     offset += 3;
38401
38402                                 }
38403
38404                             } else {
38405
38406                                 for ( ca = 0; ca < cal; ca ++ ) {
38407
38408                                     value = customAttribute.value[ ca ];
38409
38410                                     customAttribute.array[ offset ]     = value.x;
38411                                     customAttribute.array[ offset + 1 ] = value.y;
38412                                     customAttribute.array[ offset + 2 ] = value.z;
38413
38414                                     offset += 3;
38415
38416                                 }
38417
38418                             }
38419
38420                         } else if ( customAttribute.size === 4 ) {
38421
38422                             for ( ca = 0; ca < cal; ca ++ ) {
38423
38424                                 value = customAttribute.value[ ca ];
38425
38426                                 customAttribute.array[ offset ]      = value.x;
38427                                 customAttribute.array[ offset + 1  ] = value.y;
38428                                 customAttribute.array[ offset + 2  ] = value.z;
38429                                 customAttribute.array[ offset + 3  ] = value.w;
38430
38431                                 offset += 4;
38432
38433                             }
38434
38435                         }
38436
38437                     }
38438
38439                 }
38440
38441             }
38442
38443         }
38444
38445         if ( dirtyVertices || object.sortParticles ) {
38446
38447             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
38448             _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
38449
38450         }
38451
38452         if ( dirtyColors || object.sortParticles ) {
38453
38454             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
38455             _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
38456
38457         }
38458
38459         if ( customAttributes ) {
38460
38461             for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
38462
38463                 customAttribute = customAttributes[ i ];
38464
38465                 if ( customAttribute.needsUpdate || object.sortParticles ) {
38466
38467                     _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
38468                     _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
38469
38470                 }
38471
38472             }
38473
38474         }
38475
38476
38477     };
38478
38479     function setLineBuffers ( geometry, hint ) {
38480
38481         var v, c, vertex, offset, color,
38482
38483         vertices = geometry.vertices,
38484         colors = geometry.colors,
38485         vl = vertices.length,
38486         cl = colors.length,
38487
38488         vertexArray = geometry.__vertexArray,
38489         colorArray = geometry.__colorArray,
38490
38491         dirtyVertices = geometry.verticesNeedUpdate,
38492         dirtyColors = geometry.colorsNeedUpdate,
38493
38494         customAttributes = geometry.__webglCustomAttributesList,
38495
38496         i, il,
38497         a, ca, cal, value,
38498         customAttribute;
38499
38500         if ( dirtyVertices ) {
38501
38502             for ( v = 0; v < vl; v ++ ) {
38503
38504                 vertex = vertices[ v ];
38505
38506                 offset = v * 3;
38507
38508                 vertexArray[ offset ]     = vertex.x;
38509                 vertexArray[ offset + 1 ] = vertex.y;
38510                 vertexArray[ offset + 2 ] = vertex.z;
38511
38512             }
38513
38514             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
38515             _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
38516
38517         }
38518
38519         if ( dirtyColors ) {
38520
38521             for ( c = 0; c < cl; c ++ ) {
38522
38523                 color = colors[ c ];
38524
38525                 offset = c * 3;
38526
38527                 colorArray[ offset ]     = color.r;
38528                 colorArray[ offset + 1 ] = color.g;
38529                 colorArray[ offset + 2 ] = color.b;
38530
38531             }
38532
38533             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
38534             _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
38535
38536         }
38537
38538         if ( customAttributes ) {
38539
38540             for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
38541
38542                 customAttribute = customAttributes[ i ];
38543
38544                 if ( customAttribute.needsUpdate &&
38545                      ( customAttribute.boundTo === undefined ||
38546                        customAttribute.boundTo === "vertices" ) ) {
38547
38548                     offset = 0;
38549
38550                     cal = customAttribute.value.length;
38551
38552                     if ( customAttribute.size === 1 ) {
38553
38554                         for ( ca = 0; ca < cal; ca ++ ) {
38555
38556                             customAttribute.array[ ca ] = customAttribute.value[ ca ];
38557
38558                         }
38559
38560                     } else if ( customAttribute.size === 2 ) {
38561
38562                         for ( ca = 0; ca < cal; ca ++ ) {
38563
38564                             value = customAttribute.value[ ca ];
38565
38566                             customAttribute.array[ offset ]     = value.x;
38567                             customAttribute.array[ offset + 1 ] = value.y;
38568
38569                             offset += 2;
38570
38571                         }
38572
38573                     } else if ( customAttribute.size === 3 ) {
38574
38575                         if ( customAttribute.type === "c" ) {
38576
38577                             for ( ca = 0; ca < cal; ca ++ ) {
38578
38579                                 value = customAttribute.value[ ca ];
38580
38581                                 customAttribute.array[ offset ]     = value.r;
38582                                 customAttribute.array[ offset + 1 ] = value.g;
38583                                 customAttribute.array[ offset + 2 ] = value.b;
38584
38585                                 offset += 3;
38586
38587                             }
38588
38589                         } else {
38590
38591                             for ( ca = 0; ca < cal; ca ++ ) {
38592
38593                                 value = customAttribute.value[ ca ];
38594
38595                                 customAttribute.array[ offset ]     = value.x;
38596                                 customAttribute.array[ offset + 1 ] = value.y;
38597                                 customAttribute.array[ offset + 2 ] = value.z;
38598
38599                                 offset += 3;
38600
38601                             }
38602
38603                         }
38604
38605                     } else if ( customAttribute.size === 4 ) {
38606
38607                         for ( ca = 0; ca < cal; ca ++ ) {
38608
38609                             value = customAttribute.value[ ca ];
38610
38611                             customAttribute.array[ offset ]      = value.x;
38612                             customAttribute.array[ offset + 1  ] = value.y;
38613                             customAttribute.array[ offset + 2  ] = value.z;
38614                             customAttribute.array[ offset + 3  ] = value.w;
38615
38616                             offset += 4;
38617
38618                         }
38619
38620                     }
38621
38622                     _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
38623                     _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
38624
38625                 }
38626
38627             }
38628
38629         }
38630
38631     };
38632
38633     function setRibbonBuffers ( geometry, hint ) {
38634
38635         var v, c, vertex, offset, color,
38636
38637         vertices = geometry.vertices,
38638         colors = geometry.colors,
38639         vl = vertices.length,
38640         cl = colors.length,
38641
38642         vertexArray = geometry.__vertexArray,
38643         colorArray = geometry.__colorArray,
38644
38645         dirtyVertices = geometry.verticesNeedUpdate,
38646         dirtyColors = geometry.colorsNeedUpdate;
38647
38648         if ( dirtyVertices ) {
38649
38650             for ( v = 0; v < vl; v ++ ) {
38651
38652                 vertex = vertices[ v ];
38653
38654                 offset = v * 3;
38655
38656                 vertexArray[ offset ]     = vertex.x;
38657                 vertexArray[ offset + 1 ] = vertex.y;
38658                 vertexArray[ offset + 2 ] = vertex.z;
38659
38660             }
38661
38662             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
38663             _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
38664
38665         }
38666
38667         if ( dirtyColors ) {
38668
38669             for ( c = 0; c < cl; c ++ ) {
38670
38671                 color = colors[ c ];
38672
38673                 offset = c * 3;
38674
38675                 colorArray[ offset ]     = color.r;
38676                 colorArray[ offset + 1 ] = color.g;
38677                 colorArray[ offset + 2 ] = color.b;
38678
38679             }
38680
38681             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
38682             _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
38683
38684         }
38685
38686     };
38687
38688     function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
38689
38690         if ( ! geometryGroup.__inittedArrays ) {
38691
38692             // console.log( object );
38693             return;
38694
38695         }
38696
38697         var normalType = bufferGuessNormalType( material ),
38698         vertexColorType = bufferGuessVertexColorType( material ),
38699         uvType = bufferGuessUVType( material ),
38700
38701         needsSmoothNormals = ( normalType === THREE.SmoothShading );
38702
38703         var f, fl, fi, face,
38704         vertexNormals, faceNormal, normal,
38705         vertexColors, faceColor,
38706         vertexTangents,
38707         uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
38708         c1, c2, c3, c4,
38709         sw1, sw2, sw3, sw4,
38710         si1, si2, si3, si4,
38711         sa1, sa2, sa3, sa4,
38712         sb1, sb2, sb3, sb4,
38713         m, ml, i, il,
38714         vn, uvi, uv2i,
38715         vk, vkl, vka,
38716         nka, chf, faceVertexNormals,
38717         a,
38718
38719         vertexIndex = 0,
38720
38721         offset = 0,
38722         offset_uv = 0,
38723         offset_uv2 = 0,
38724         offset_face = 0,
38725         offset_normal = 0,
38726         offset_tangent = 0,
38727         offset_line = 0,
38728         offset_color = 0,
38729         offset_skin = 0,
38730         offset_morphTarget = 0,
38731         offset_custom = 0,
38732         offset_customSrc = 0,
38733
38734         value,
38735
38736         vertexArray = geometryGroup.__vertexArray,
38737         uvArray = geometryGroup.__uvArray,
38738         uv2Array = geometryGroup.__uv2Array,
38739         normalArray = geometryGroup.__normalArray,
38740         tangentArray = geometryGroup.__tangentArray,
38741         colorArray = geometryGroup.__colorArray,
38742
38743         skinIndexArray = geometryGroup.__skinIndexArray,
38744         skinWeightArray = geometryGroup.__skinWeightArray,
38745
38746         morphTargetsArrays = geometryGroup.__morphTargetsArrays,
38747         morphNormalsArrays = geometryGroup.__morphNormalsArrays,
38748
38749         customAttributes = geometryGroup.__webglCustomAttributesList,
38750         customAttribute,
38751
38752         faceArray = geometryGroup.__faceArray,
38753         lineArray = geometryGroup.__lineArray,
38754
38755         geometry = object.geometry, // this is shared for all chunks
38756
38757         dirtyVertices = geometry.verticesNeedUpdate,
38758         dirtyElements = geometry.elementsNeedUpdate,
38759         dirtyUvs = geometry.uvsNeedUpdate,
38760         dirtyNormals = geometry.normalsNeedUpdate,
38761         dirtyTangents = geometry.tangentsNeedUpdate,
38762         dirtyColors = geometry.colorsNeedUpdate,
38763         dirtyMorphTargets = geometry.morphTargetsNeedUpdate,
38764
38765         vertices = geometry.vertices,
38766         chunk_faces3 = geometryGroup.faces3,
38767         chunk_faces4 = geometryGroup.faces4,
38768         obj_faces = geometry.faces,
38769
38770         obj_uvs  = geometry.faceVertexUvs[ 0 ],
38771         obj_uvs2 = geometry.faceVertexUvs[ 1 ],
38772
38773         obj_colors = geometry.colors,
38774
38775         obj_skinIndices = geometry.skinIndices,
38776         obj_skinWeights = geometry.skinWeights,
38777
38778         morphTargets = geometry.morphTargets,
38779         morphNormals = geometry.morphNormals;
38780
38781         if ( dirtyVertices ) {
38782
38783             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
38784
38785                 face = obj_faces[ chunk_faces3[ f ] ];
38786
38787                 v1 = vertices[ face.a ];
38788                 v2 = vertices[ face.b ];
38789                 v3 = vertices[ face.c ];
38790
38791                 vertexArray[ offset ]     = v1.x;
38792                 vertexArray[ offset + 1 ] = v1.y;
38793                 vertexArray[ offset + 2 ] = v1.z;
38794
38795                 vertexArray[ offset + 3 ] = v2.x;
38796                 vertexArray[ offset + 4 ] = v2.y;
38797                 vertexArray[ offset + 5 ] = v2.z;
38798
38799                 vertexArray[ offset + 6 ] = v3.x;
38800                 vertexArray[ offset + 7 ] = v3.y;
38801                 vertexArray[ offset + 8 ] = v3.z;
38802
38803                 offset += 9;
38804
38805             }
38806
38807             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
38808
38809                 face = obj_faces[ chunk_faces4[ f ] ];
38810
38811                 v1 = vertices[ face.a ];
38812                 v2 = vertices[ face.b ];
38813                 v3 = vertices[ face.c ];
38814                 v4 = vertices[ face.d ];
38815
38816                 vertexArray[ offset ]     = v1.x;
38817                 vertexArray[ offset + 1 ] = v1.y;
38818                 vertexArray[ offset + 2 ] = v1.z;
38819
38820                 vertexArray[ offset + 3 ] = v2.x;
38821                 vertexArray[ offset + 4 ] = v2.y;
38822                 vertexArray[ offset + 5 ] = v2.z;
38823
38824                 vertexArray[ offset + 6 ] = v3.x;
38825                 vertexArray[ offset + 7 ] = v3.y;
38826                 vertexArray[ offset + 8 ] = v3.z;
38827
38828                 vertexArray[ offset + 9 ]  = v4.x;
38829                 vertexArray[ offset + 10 ] = v4.y;
38830                 vertexArray[ offset + 11 ] = v4.z;
38831
38832                 offset += 12;
38833
38834             }
38835
38836             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
38837             _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
38838
38839         }
38840
38841         if ( dirtyMorphTargets ) {
38842
38843             for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
38844
38845                 offset_morphTarget = 0;
38846
38847                 for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
38848
38849                     chf = chunk_faces3[ f ];
38850                     face = obj_faces[ chf ];
38851
38852                     // morph positions
38853
38854                     v1 = morphTargets[ vk ].vertices[ face.a ];
38855                     v2 = morphTargets[ vk ].vertices[ face.b ];
38856                     v3 = morphTargets[ vk ].vertices[ face.c ];
38857
38858                     vka = morphTargetsArrays[ vk ];
38859
38860                     vka[ offset_morphTarget ]       = v1.x;
38861                     vka[ offset_morphTarget + 1 ] = v1.y;
38862                     vka[ offset_morphTarget + 2 ] = v1.z;
38863
38864                     vka[ offset_morphTarget + 3 ] = v2.x;
38865                     vka[ offset_morphTarget + 4 ] = v2.y;
38866                     vka[ offset_morphTarget + 5 ] = v2.z;
38867
38868                     vka[ offset_morphTarget + 6 ] = v3.x;
38869                     vka[ offset_morphTarget + 7 ] = v3.y;
38870                     vka[ offset_morphTarget + 8 ] = v3.z;
38871
38872                     // morph normals
38873
38874                     if ( material.morphNormals ) {
38875
38876                         if ( needsSmoothNormals ) {
38877
38878                             faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];
38879
38880                             n1 = faceVertexNormals.a;
38881                             n2 = faceVertexNormals.b;
38882                             n3 = faceVertexNormals.c;
38883
38884                         } else {
38885
38886                             n1 = morphNormals[ vk ].faceNormals[ chf ];
38887                             n2 = n1;
38888                             n3 = n1;
38889
38890                         }
38891
38892                         nka = morphNormalsArrays[ vk ];
38893
38894                         nka[ offset_morphTarget ]       = n1.x;
38895                         nka[ offset_morphTarget + 1 ] = n1.y;
38896                         nka[ offset_morphTarget + 2 ] = n1.z;
38897
38898                         nka[ offset_morphTarget + 3 ] = n2.x;
38899                         nka[ offset_morphTarget + 4 ] = n2.y;
38900                         nka[ offset_morphTarget + 5 ] = n2.z;
38901
38902                         nka[ offset_morphTarget + 6 ] = n3.x;
38903                         nka[ offset_morphTarget + 7 ] = n3.y;
38904                         nka[ offset_morphTarget + 8 ] = n3.z;
38905
38906                     }
38907
38908                     //
38909
38910                     offset_morphTarget += 9;
38911
38912                 }
38913
38914                 for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
38915
38916                     chf = chunk_faces4[ f ];
38917                     face = obj_faces[ chf ];
38918
38919                     // morph positions
38920
38921                     v1 = morphTargets[ vk ].vertices[ face.a ];
38922                     v2 = morphTargets[ vk ].vertices[ face.b ];
38923                     v3 = morphTargets[ vk ].vertices[ face.c ];
38924                     v4 = morphTargets[ vk ].vertices[ face.d ];
38925
38926                     vka = morphTargetsArrays[ vk ];
38927
38928                     vka[ offset_morphTarget ]       = v1.x;
38929                     vka[ offset_morphTarget + 1 ] = v1.y;
38930                     vka[ offset_morphTarget + 2 ] = v1.z;
38931
38932                     vka[ offset_morphTarget + 3 ] = v2.x;
38933                     vka[ offset_morphTarget + 4 ] = v2.y;
38934                     vka[ offset_morphTarget + 5 ] = v2.z;
38935
38936                     vka[ offset_morphTarget + 6 ] = v3.x;
38937                     vka[ offset_morphTarget + 7 ] = v3.y;
38938                     vka[ offset_morphTarget + 8 ] = v3.z;
38939
38940                     vka[ offset_morphTarget + 9 ]  = v4.x;
38941                     vka[ offset_morphTarget + 10 ] = v4.y;
38942                     vka[ offset_morphTarget + 11 ] = v4.z;
38943
38944                     // morph normals
38945
38946                     if ( material.morphNormals ) {
38947
38948                         if ( needsSmoothNormals ) {
38949
38950                             faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];
38951
38952                             n1 = faceVertexNormals.a;
38953                             n2 = faceVertexNormals.b;
38954                             n3 = faceVertexNormals.c;
38955                             n4 = faceVertexNormals.d;
38956
38957                         } else {
38958
38959                             n1 = morphNormals[ vk ].faceNormals[ chf ];
38960                             n2 = n1;
38961                             n3 = n1;
38962                             n4 = n1;
38963
38964                         }
38965
38966                         nka = morphNormalsArrays[ vk ];
38967
38968                         nka[ offset_morphTarget ]       = n1.x;
38969                         nka[ offset_morphTarget + 1 ] = n1.y;
38970                         nka[ offset_morphTarget + 2 ] = n1.z;
38971
38972                         nka[ offset_morphTarget + 3 ] = n2.x;
38973                         nka[ offset_morphTarget + 4 ] = n2.y;
38974                         nka[ offset_morphTarget + 5 ] = n2.z;
38975
38976                         nka[ offset_morphTarget + 6 ] = n3.x;
38977                         nka[ offset_morphTarget + 7 ] = n3.y;
38978                         nka[ offset_morphTarget + 8 ] = n3.z;
38979
38980                         nka[ offset_morphTarget + 9 ]  = n4.x;
38981                         nka[ offset_morphTarget + 10 ] = n4.y;
38982                         nka[ offset_morphTarget + 11 ] = n4.z;
38983
38984                     }
38985
38986                     //
38987
38988                     offset_morphTarget += 12;
38989
38990                 }
38991
38992                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ vk ] );
38993                 _gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
38994
38995                 if ( material.morphNormals ) {
38996
38997                     _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ vk ] );
38998                     _gl.bufferData( _gl.ARRAY_BUFFER, morphNormalsArrays[ vk ], hint );
38999
39000                 }
39001
39002             }
39003
39004         }
39005
39006         if ( obj_skinWeights.length ) {
39007
39008             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39009
39010                 face = obj_faces[ chunk_faces3[ f ]    ];
39011
39012                 // weights
39013
39014                 sw1 = obj_skinWeights[ face.a ];
39015                 sw2 = obj_skinWeights[ face.b ];
39016                 sw3 = obj_skinWeights[ face.c ];
39017
39018                 skinWeightArray[ offset_skin ]     = sw1.x;
39019                 skinWeightArray[ offset_skin + 1 ] = sw1.y;
39020                 skinWeightArray[ offset_skin + 2 ] = sw1.z;
39021                 skinWeightArray[ offset_skin + 3 ] = sw1.w;
39022
39023                 skinWeightArray[ offset_skin + 4 ] = sw2.x;
39024                 skinWeightArray[ offset_skin + 5 ] = sw2.y;
39025                 skinWeightArray[ offset_skin + 6 ] = sw2.z;
39026                 skinWeightArray[ offset_skin + 7 ] = sw2.w;
39027
39028                 skinWeightArray[ offset_skin + 8 ]  = sw3.x;
39029                 skinWeightArray[ offset_skin + 9 ]  = sw3.y;
39030                 skinWeightArray[ offset_skin + 10 ] = sw3.z;
39031                 skinWeightArray[ offset_skin + 11 ] = sw3.w;
39032
39033                 // indices
39034
39035                 si1 = obj_skinIndices[ face.a ];
39036                 si2 = obj_skinIndices[ face.b ];
39037                 si3 = obj_skinIndices[ face.c ];
39038
39039                 skinIndexArray[ offset_skin ]     = si1.x;
39040                 skinIndexArray[ offset_skin + 1 ] = si1.y;
39041                 skinIndexArray[ offset_skin + 2 ] = si1.z;
39042                 skinIndexArray[ offset_skin + 3 ] = si1.w;
39043
39044                 skinIndexArray[ offset_skin + 4 ] = si2.x;
39045                 skinIndexArray[ offset_skin + 5 ] = si2.y;
39046                 skinIndexArray[ offset_skin + 6 ] = si2.z;
39047                 skinIndexArray[ offset_skin + 7 ] = si2.w;
39048
39049                 skinIndexArray[ offset_skin + 8 ]  = si3.x;
39050                 skinIndexArray[ offset_skin + 9 ]  = si3.y;
39051                 skinIndexArray[ offset_skin + 10 ] = si3.z;
39052                 skinIndexArray[ offset_skin + 11 ] = si3.w;
39053
39054                 offset_skin += 12;
39055
39056             }
39057
39058             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39059
39060                 face = obj_faces[ chunk_faces4[ f ] ];
39061
39062                 // weights
39063
39064                 sw1 = obj_skinWeights[ face.a ];
39065                 sw2 = obj_skinWeights[ face.b ];
39066                 sw3 = obj_skinWeights[ face.c ];
39067                 sw4 = obj_skinWeights[ face.d ];
39068
39069                 skinWeightArray[ offset_skin ]     = sw1.x;
39070                 skinWeightArray[ offset_skin + 1 ] = sw1.y;
39071                 skinWeightArray[ offset_skin + 2 ] = sw1.z;
39072                 skinWeightArray[ offset_skin + 3 ] = sw1.w;
39073
39074                 skinWeightArray[ offset_skin + 4 ] = sw2.x;
39075                 skinWeightArray[ offset_skin + 5 ] = sw2.y;
39076                 skinWeightArray[ offset_skin + 6 ] = sw2.z;
39077                 skinWeightArray[ offset_skin + 7 ] = sw2.w;
39078
39079                 skinWeightArray[ offset_skin + 8 ]  = sw3.x;
39080                 skinWeightArray[ offset_skin + 9 ]  = sw3.y;
39081                 skinWeightArray[ offset_skin + 10 ] = sw3.z;
39082                 skinWeightArray[ offset_skin + 11 ] = sw3.w;
39083
39084                 skinWeightArray[ offset_skin + 12 ] = sw4.x;
39085                 skinWeightArray[ offset_skin + 13 ] = sw4.y;
39086                 skinWeightArray[ offset_skin + 14 ] = sw4.z;
39087                 skinWeightArray[ offset_skin + 15 ] = sw4.w;
39088
39089                 // indices
39090
39091                 si1 = obj_skinIndices[ face.a ];
39092                 si2 = obj_skinIndices[ face.b ];
39093                 si3 = obj_skinIndices[ face.c ];
39094                 si4 = obj_skinIndices[ face.d ];
39095
39096                 skinIndexArray[ offset_skin ]     = si1.x;
39097                 skinIndexArray[ offset_skin + 1 ] = si1.y;
39098                 skinIndexArray[ offset_skin + 2 ] = si1.z;
39099                 skinIndexArray[ offset_skin + 3 ] = si1.w;
39100
39101                 skinIndexArray[ offset_skin + 4 ] = si2.x;
39102                 skinIndexArray[ offset_skin + 5 ] = si2.y;
39103                 skinIndexArray[ offset_skin + 6 ] = si2.z;
39104                 skinIndexArray[ offset_skin + 7 ] = si2.w;
39105
39106                 skinIndexArray[ offset_skin + 8 ]  = si3.x;
39107                 skinIndexArray[ offset_skin + 9 ]  = si3.y;
39108                 skinIndexArray[ offset_skin + 10 ] = si3.z;
39109                 skinIndexArray[ offset_skin + 11 ] = si3.w;
39110
39111                 skinIndexArray[ offset_skin + 12 ] = si4.x;
39112                 skinIndexArray[ offset_skin + 13 ] = si4.y;
39113                 skinIndexArray[ offset_skin + 14 ] = si4.z;
39114                 skinIndexArray[ offset_skin + 15 ] = si4.w;
39115
39116                 offset_skin += 16;
39117
39118             }
39119
39120             if ( offset_skin > 0 ) {
39121
39122                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
39123                 _gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );
39124
39125                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
39126                 _gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
39127
39128             }
39129
39130         }
39131
39132         if ( dirtyColors && vertexColorType ) {
39133
39134             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39135
39136                 face = obj_faces[ chunk_faces3[ f ]    ];
39137
39138                 vertexColors = face.vertexColors;
39139                 faceColor = face.color;
39140
39141                 if ( vertexColors.length === 3 && vertexColorType === THREE.VertexColors ) {
39142
39143                     c1 = vertexColors[ 0 ];
39144                     c2 = vertexColors[ 1 ];
39145                     c3 = vertexColors[ 2 ];
39146
39147                 } else {
39148
39149                     c1 = faceColor;
39150                     c2 = faceColor;
39151                     c3 = faceColor;
39152
39153                 }
39154
39155                 colorArray[ offset_color ]     = c1.r;
39156                 colorArray[ offset_color + 1 ] = c1.g;
39157                 colorArray[ offset_color + 2 ] = c1.b;
39158
39159                 colorArray[ offset_color + 3 ] = c2.r;
39160                 colorArray[ offset_color + 4 ] = c2.g;
39161                 colorArray[ offset_color + 5 ] = c2.b;
39162
39163                 colorArray[ offset_color + 6 ] = c3.r;
39164                 colorArray[ offset_color + 7 ] = c3.g;
39165                 colorArray[ offset_color + 8 ] = c3.b;
39166
39167                 offset_color += 9;
39168
39169             }
39170
39171             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39172
39173                 face = obj_faces[ chunk_faces4[ f ] ];
39174
39175                 vertexColors = face.vertexColors;
39176                 faceColor = face.color;
39177
39178                 if ( vertexColors.length === 4 && vertexColorType === THREE.VertexColors ) {
39179
39180                     c1 = vertexColors[ 0 ];
39181                     c2 = vertexColors[ 1 ];
39182                     c3 = vertexColors[ 2 ];
39183                     c4 = vertexColors[ 3 ];
39184
39185                 } else {
39186
39187                     c1 = faceColor;
39188                     c2 = faceColor;
39189                     c3 = faceColor;
39190                     c4 = faceColor;
39191
39192                 }
39193
39194                 colorArray[ offset_color ]     = c1.r;
39195                 colorArray[ offset_color + 1 ] = c1.g;
39196                 colorArray[ offset_color + 2 ] = c1.b;
39197
39198                 colorArray[ offset_color + 3 ] = c2.r;
39199                 colorArray[ offset_color + 4 ] = c2.g;
39200                 colorArray[ offset_color + 5 ] = c2.b;
39201
39202                 colorArray[ offset_color + 6 ] = c3.r;
39203                 colorArray[ offset_color + 7 ] = c3.g;
39204                 colorArray[ offset_color + 8 ] = c3.b;
39205
39206                 colorArray[ offset_color + 9 ]  = c4.r;
39207                 colorArray[ offset_color + 10 ] = c4.g;
39208                 colorArray[ offset_color + 11 ] = c4.b;
39209
39210                 offset_color += 12;
39211
39212             }
39213
39214             if ( offset_color > 0 ) {
39215
39216                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
39217                 _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
39218
39219             }
39220
39221         }
39222
39223         if ( dirtyTangents && geometry.hasTangents ) {
39224
39225             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39226
39227                 face = obj_faces[ chunk_faces3[ f ]    ];
39228
39229                 vertexTangents = face.vertexTangents;
39230
39231                 t1 = vertexTangents[ 0 ];
39232                 t2 = vertexTangents[ 1 ];
39233                 t3 = vertexTangents[ 2 ];
39234
39235                 tangentArray[ offset_tangent ]     = t1.x;
39236                 tangentArray[ offset_tangent + 1 ] = t1.y;
39237                 tangentArray[ offset_tangent + 2 ] = t1.z;
39238                 tangentArray[ offset_tangent + 3 ] = t1.w;
39239
39240                 tangentArray[ offset_tangent + 4 ] = t2.x;
39241                 tangentArray[ offset_tangent + 5 ] = t2.y;
39242                 tangentArray[ offset_tangent + 6 ] = t2.z;
39243                 tangentArray[ offset_tangent + 7 ] = t2.w;
39244
39245                 tangentArray[ offset_tangent + 8 ]  = t3.x;
39246                 tangentArray[ offset_tangent + 9 ]  = t3.y;
39247                 tangentArray[ offset_tangent + 10 ] = t3.z;
39248                 tangentArray[ offset_tangent + 11 ] = t3.w;
39249
39250                 offset_tangent += 12;
39251
39252             }
39253
39254             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39255
39256                 face = obj_faces[ chunk_faces4[ f ] ];
39257
39258                 vertexTangents = face.vertexTangents;
39259
39260                 t1 = vertexTangents[ 0 ];
39261                 t2 = vertexTangents[ 1 ];
39262                 t3 = vertexTangents[ 2 ];
39263                 t4 = vertexTangents[ 3 ];
39264
39265                 tangentArray[ offset_tangent ]     = t1.x;
39266                 tangentArray[ offset_tangent + 1 ] = t1.y;
39267                 tangentArray[ offset_tangent + 2 ] = t1.z;
39268                 tangentArray[ offset_tangent + 3 ] = t1.w;
39269
39270                 tangentArray[ offset_tangent + 4 ] = t2.x;
39271                 tangentArray[ offset_tangent + 5 ] = t2.y;
39272                 tangentArray[ offset_tangent + 6 ] = t2.z;
39273                 tangentArray[ offset_tangent + 7 ] = t2.w;
39274
39275                 tangentArray[ offset_tangent + 8 ]  = t3.x;
39276                 tangentArray[ offset_tangent + 9 ]  = t3.y;
39277                 tangentArray[ offset_tangent + 10 ] = t3.z;
39278                 tangentArray[ offset_tangent + 11 ] = t3.w;
39279
39280                 tangentArray[ offset_tangent + 12 ] = t4.x;
39281                 tangentArray[ offset_tangent + 13 ] = t4.y;
39282                 tangentArray[ offset_tangent + 14 ] = t4.z;
39283                 tangentArray[ offset_tangent + 15 ] = t4.w;
39284
39285                 offset_tangent += 16;
39286
39287             }
39288
39289             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
39290             _gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
39291
39292         }
39293
39294         if ( dirtyNormals && normalType ) {
39295
39296             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39297
39298                 face = obj_faces[ chunk_faces3[ f ]    ];
39299
39300                 vertexNormals = face.vertexNormals;
39301                 faceNormal = face.normal;
39302
39303                 if ( vertexNormals.length === 3 && needsSmoothNormals ) {
39304
39305                     for ( i = 0; i < 3; i ++ ) {
39306
39307                         vn = vertexNormals[ i ];
39308
39309                         normalArray[ offset_normal ]     = vn.x;
39310                         normalArray[ offset_normal + 1 ] = vn.y;
39311                         normalArray[ offset_normal + 2 ] = vn.z;
39312
39313                         offset_normal += 3;
39314
39315                     }
39316
39317                 } else {
39318
39319                     for ( i = 0; i < 3; i ++ ) {
39320
39321                         normalArray[ offset_normal ]     = faceNormal.x;
39322                         normalArray[ offset_normal + 1 ] = faceNormal.y;
39323                         normalArray[ offset_normal + 2 ] = faceNormal.z;
39324
39325                         offset_normal += 3;
39326
39327                     }
39328
39329                 }
39330
39331             }
39332
39333             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39334
39335                 face = obj_faces[ chunk_faces4[ f ] ];
39336
39337                 vertexNormals = face.vertexNormals;
39338                 faceNormal = face.normal;
39339
39340                 if ( vertexNormals.length === 4 && needsSmoothNormals ) {
39341
39342                     for ( i = 0; i < 4; i ++ ) {
39343
39344                         vn = vertexNormals[ i ];
39345
39346                         normalArray[ offset_normal ]     = vn.x;
39347                         normalArray[ offset_normal + 1 ] = vn.y;
39348                         normalArray[ offset_normal + 2 ] = vn.z;
39349
39350                         offset_normal += 3;
39351
39352                     }
39353
39354                 } else {
39355
39356                     for ( i = 0; i < 4; i ++ ) {
39357
39358                         normalArray[ offset_normal ]     = faceNormal.x;
39359                         normalArray[ offset_normal + 1 ] = faceNormal.y;
39360                         normalArray[ offset_normal + 2 ] = faceNormal.z;
39361
39362                         offset_normal += 3;
39363
39364                     }
39365
39366                 }
39367
39368             }
39369
39370             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
39371             _gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
39372
39373         }
39374
39375         if ( dirtyUvs && obj_uvs && uvType ) {
39376
39377             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39378
39379                 fi = chunk_faces3[ f ];
39380
39381                 face = obj_faces[ fi ];
39382                 uv = obj_uvs[ fi ];
39383
39384                 if ( uv === undefined ) continue;
39385
39386                 for ( i = 0; i < 3; i ++ ) {
39387
39388                     uvi = uv[ i ];
39389
39390                     uvArray[ offset_uv ]     = uvi.u;
39391                     uvArray[ offset_uv + 1 ] = uvi.v;
39392
39393                     offset_uv += 2;
39394
39395                 }
39396
39397             }
39398
39399             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39400
39401                 fi = chunk_faces4[ f ];
39402
39403                 face = obj_faces[ fi ];
39404                 uv = obj_uvs[ fi ];
39405
39406                 if ( uv === undefined ) continue;
39407
39408                 for ( i = 0; i < 4; i ++ ) {
39409
39410                     uvi = uv[ i ];
39411
39412                     uvArray[ offset_uv ]     = uvi.u;
39413                     uvArray[ offset_uv + 1 ] = uvi.v;
39414
39415                     offset_uv += 2;
39416
39417                 }
39418
39419             }
39420
39421             if ( offset_uv > 0 ) {
39422
39423                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
39424                 _gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
39425
39426             }
39427
39428         }
39429
39430         if ( dirtyUvs && obj_uvs2 && uvType ) {
39431
39432             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39433
39434                 fi = chunk_faces3[ f ];
39435
39436                 face = obj_faces[ fi ];
39437                 uv2 = obj_uvs2[ fi ];
39438
39439                 if ( uv2 === undefined ) continue;
39440
39441                 for ( i = 0; i < 3; i ++ ) {
39442
39443                     uv2i = uv2[ i ];
39444
39445                     uv2Array[ offset_uv2 ]     = uv2i.u;
39446                     uv2Array[ offset_uv2 + 1 ] = uv2i.v;
39447
39448                     offset_uv2 += 2;
39449
39450                 }
39451
39452             }
39453
39454             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39455
39456                 fi = chunk_faces4[ f ];
39457
39458                 face = obj_faces[ fi ];
39459                 uv2 = obj_uvs2[ fi ];
39460
39461                 if ( uv2 === undefined ) continue;
39462
39463                 for ( i = 0; i < 4; i ++ ) {
39464
39465                     uv2i = uv2[ i ];
39466
39467                     uv2Array[ offset_uv2 ]     = uv2i.u;
39468                     uv2Array[ offset_uv2 + 1 ] = uv2i.v;
39469
39470                     offset_uv2 += 2;
39471
39472                 }
39473
39474             }
39475
39476             if ( offset_uv2 > 0 ) {
39477
39478                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
39479                 _gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
39480
39481             }
39482
39483         }
39484
39485         if ( dirtyElements ) {
39486
39487             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39488
39489                 face = obj_faces[ chunk_faces3[ f ]    ];
39490
39491                 faceArray[ offset_face ]      = vertexIndex;
39492                 faceArray[ offset_face + 1 ] = vertexIndex + 1;
39493                 faceArray[ offset_face + 2 ] = vertexIndex + 2;
39494
39495                 offset_face += 3;
39496
39497                 lineArray[ offset_line ]     = vertexIndex;
39498                 lineArray[ offset_line + 1 ] = vertexIndex + 1;
39499
39500                 lineArray[ offset_line + 2 ] = vertexIndex;
39501                 lineArray[ offset_line + 3 ] = vertexIndex + 2;
39502
39503                 lineArray[ offset_line + 4 ] = vertexIndex + 1;
39504                 lineArray[ offset_line + 5 ] = vertexIndex + 2;
39505
39506                 offset_line += 6;
39507
39508                 vertexIndex += 3;
39509
39510             }
39511
39512             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39513
39514                 face = obj_faces[ chunk_faces4[ f ] ];
39515
39516                 faceArray[ offset_face ]     = vertexIndex;
39517                 faceArray[ offset_face + 1 ] = vertexIndex + 1;
39518                 faceArray[ offset_face + 2 ] = vertexIndex + 3;
39519
39520                 faceArray[ offset_face + 3 ] = vertexIndex + 1;
39521                 faceArray[ offset_face + 4 ] = vertexIndex + 2;
39522                 faceArray[ offset_face + 5 ] = vertexIndex + 3;
39523
39524                 offset_face += 6;
39525
39526                 lineArray[ offset_line ]     = vertexIndex;
39527                 lineArray[ offset_line + 1 ] = vertexIndex + 1;
39528
39529                 lineArray[ offset_line + 2 ] = vertexIndex;
39530                 lineArray[ offset_line + 3 ] = vertexIndex + 3;
39531
39532                 lineArray[ offset_line + 4 ] = vertexIndex + 1;
39533                 lineArray[ offset_line + 5 ] = vertexIndex + 2;
39534
39535                 lineArray[ offset_line + 6 ] = vertexIndex + 2;
39536                 lineArray[ offset_line + 7 ] = vertexIndex + 3;
39537
39538                 offset_line += 8;
39539
39540                 vertexIndex += 4;
39541
39542             }
39543
39544             _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
39545             _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
39546
39547             _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
39548             _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
39549
39550         }
39551
39552         if ( customAttributes ) {
39553
39554             for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
39555
39556                 customAttribute = customAttributes[ i ];
39557
39558                 if ( ! customAttribute.__original.needsUpdate ) continue;
39559
39560                 offset_custom = 0;
39561                 offset_customSrc = 0;
39562
39563                 if ( customAttribute.size === 1 ) {
39564
39565                     if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
39566
39567                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39568
39569                             face = obj_faces[ chunk_faces3[ f ]    ];
39570
39571                             customAttribute.array[ offset_custom ]        = customAttribute.value[ face.a ];
39572                             customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
39573                             customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
39574
39575                             offset_custom += 3;
39576
39577                         }
39578
39579                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39580
39581                             face = obj_faces[ chunk_faces4[ f ] ];
39582
39583                             customAttribute.array[ offset_custom ]        = customAttribute.value[ face.a ];
39584                             customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
39585                             customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
39586                             customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ face.d ];
39587
39588                             offset_custom += 4;
39589
39590                         }
39591
39592                     } else if ( customAttribute.boundTo === "faces" ) {
39593
39594                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39595
39596                             value = customAttribute.value[ chunk_faces3[ f ] ];
39597
39598                             customAttribute.array[ offset_custom ]        = value;
39599                             customAttribute.array[ offset_custom + 1 ] = value;
39600                             customAttribute.array[ offset_custom + 2 ] = value;
39601
39602                             offset_custom += 3;
39603
39604                         }
39605
39606                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39607
39608                             value = customAttribute.value[ chunk_faces4[ f ] ];
39609
39610                             customAttribute.array[ offset_custom ]        = value;
39611                             customAttribute.array[ offset_custom + 1 ] = value;
39612                             customAttribute.array[ offset_custom + 2 ] = value;
39613                             customAttribute.array[ offset_custom + 3 ] = value;
39614
39615                             offset_custom += 4;
39616
39617                         }
39618
39619                     }
39620
39621                 } else if ( customAttribute.size === 2 ) {
39622
39623                     if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
39624
39625                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39626
39627                             face = obj_faces[ chunk_faces3[ f ]    ];
39628
39629                             v1 = customAttribute.value[ face.a ];
39630                             v2 = customAttribute.value[ face.b ];
39631                             v3 = customAttribute.value[ face.c ];
39632
39633                             customAttribute.array[ offset_custom ]        = v1.x;
39634                             customAttribute.array[ offset_custom + 1 ] = v1.y;
39635
39636                             customAttribute.array[ offset_custom + 2 ] = v2.x;
39637                             customAttribute.array[ offset_custom + 3 ] = v2.y;
39638
39639                             customAttribute.array[ offset_custom + 4 ] = v3.x;
39640                             customAttribute.array[ offset_custom + 5 ] = v3.y;
39641
39642                             offset_custom += 6;
39643
39644                         }
39645
39646                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39647
39648                             face = obj_faces[ chunk_faces4[ f ] ];
39649
39650                             v1 = customAttribute.value[ face.a ];
39651                             v2 = customAttribute.value[ face.b ];
39652                             v3 = customAttribute.value[ face.c ];
39653                             v4 = customAttribute.value[ face.d ];
39654
39655                             customAttribute.array[ offset_custom ]        = v1.x;
39656                             customAttribute.array[ offset_custom + 1 ] = v1.y;
39657
39658                             customAttribute.array[ offset_custom + 2 ] = v2.x;
39659                             customAttribute.array[ offset_custom + 3 ] = v2.y;
39660
39661                             customAttribute.array[ offset_custom + 4 ] = v3.x;
39662                             customAttribute.array[ offset_custom + 5 ] = v3.y;
39663
39664                             customAttribute.array[ offset_custom + 6 ] = v4.x;
39665                             customAttribute.array[ offset_custom + 7 ] = v4.y;
39666
39667                             offset_custom += 8;
39668
39669                         }
39670
39671                     } else if ( customAttribute.boundTo === "faces" ) {
39672
39673                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39674
39675                             value = customAttribute.value[ chunk_faces3[ f ] ];
39676
39677                             v1 = value;
39678                             v2 = value;
39679                             v3 = value;
39680
39681                             customAttribute.array[ offset_custom ]        = v1.x;
39682                             customAttribute.array[ offset_custom + 1 ] = v1.y;
39683
39684                             customAttribute.array[ offset_custom + 2 ] = v2.x;
39685                             customAttribute.array[ offset_custom + 3 ] = v2.y;
39686
39687                             customAttribute.array[ offset_custom + 4 ] = v3.x;
39688                             customAttribute.array[ offset_custom + 5 ] = v3.y;
39689
39690                             offset_custom += 6;
39691
39692                         }
39693
39694                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39695
39696                             value = customAttribute.value[ chunk_faces4[ f ] ];
39697
39698                             v1 = value;
39699                             v2 = value;
39700                             v3 = value;
39701                             v4 = value;
39702
39703                             customAttribute.array[ offset_custom ]        = v1.x;
39704                             customAttribute.array[ offset_custom + 1 ] = v1.y;
39705
39706                             customAttribute.array[ offset_custom + 2 ] = v2.x;
39707                             customAttribute.array[ offset_custom + 3 ] = v2.y;
39708
39709                             customAttribute.array[ offset_custom + 4 ] = v3.x;
39710                             customAttribute.array[ offset_custom + 5 ] = v3.y;
39711
39712                             customAttribute.array[ offset_custom + 6 ] = v4.x;
39713                             customAttribute.array[ offset_custom + 7 ] = v4.y;
39714
39715                             offset_custom += 8;
39716
39717                         }
39718
39719                     }
39720
39721                 } else if ( customAttribute.size === 3 ) {
39722
39723                     var pp;
39724
39725                     if ( customAttribute.type === "c" ) {
39726
39727                         pp = [ "r", "g", "b" ];
39728
39729                     } else {
39730
39731                         pp = [ "x", "y", "z" ];
39732
39733                     }
39734
39735                     if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
39736
39737                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39738
39739                             face = obj_faces[ chunk_faces3[ f ]    ];
39740
39741                             v1 = customAttribute.value[ face.a ];
39742                             v2 = customAttribute.value[ face.b ];
39743                             v3 = customAttribute.value[ face.c ];
39744
39745                             customAttribute.array[ offset_custom ]        = v1[ pp[ 0 ] ];
39746                             customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
39747                             customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
39748
39749                             customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
39750                             customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
39751                             customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
39752
39753                             customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
39754                             customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
39755                             customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
39756
39757                             offset_custom += 9;
39758
39759                         }
39760
39761                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39762
39763                             face = obj_faces[ chunk_faces4[ f ] ];
39764
39765                             v1 = customAttribute.value[ face.a ];
39766                             v2 = customAttribute.value[ face.b ];
39767                             v3 = customAttribute.value[ face.c ];
39768                             v4 = customAttribute.value[ face.d ];
39769
39770                             customAttribute.array[ offset_custom  ]     = v1[ pp[ 0 ] ];
39771                             customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
39772                             customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
39773
39774                             customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
39775                             customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
39776                             customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
39777
39778                             customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
39779                             customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
39780                             customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
39781
39782                             customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
39783                             customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
39784                             customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
39785
39786                             offset_custom += 12;
39787
39788                         }
39789
39790                     } else if ( customAttribute.boundTo === "faces" ) {
39791
39792                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39793
39794                             value = customAttribute.value[ chunk_faces3[ f ] ];
39795
39796                             v1 = value;
39797                             v2 = value;
39798                             v3 = value;
39799
39800                             customAttribute.array[ offset_custom ]        = v1[ pp[ 0 ] ];
39801                             customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
39802                             customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
39803
39804                             customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
39805                             customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
39806                             customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
39807
39808                             customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
39809                             customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
39810                             customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
39811
39812                             offset_custom += 9;
39813
39814                         }
39815
39816                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39817
39818                             value = customAttribute.value[ chunk_faces4[ f ] ];
39819
39820                             v1 = value;
39821                             v2 = value;
39822                             v3 = value;
39823                             v4 = value;
39824
39825                             customAttribute.array[ offset_custom  ]     = v1[ pp[ 0 ] ];
39826                             customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
39827                             customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
39828
39829                             customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
39830                             customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
39831                             customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
39832
39833                             customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
39834                             customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
39835                             customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
39836
39837                             customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
39838                             customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
39839                             customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
39840
39841                             offset_custom += 12;
39842
39843                         }
39844
39845                     } else if ( customAttribute.boundTo === "faceVertices" ) {
39846
39847                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39848
39849                             value = customAttribute.value[ chunk_faces3[ f ] ];
39850
39851                             v1 = value[ 0 ];
39852                             v2 = value[ 1 ];
39853                             v3 = value[ 2 ];
39854
39855                             customAttribute.array[ offset_custom ]        = v1[ pp[ 0 ] ];
39856                             customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
39857                             customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
39858
39859                             customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
39860                             customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
39861                             customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
39862
39863                             customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
39864                             customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
39865                             customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
39866
39867                             offset_custom += 9;
39868
39869                         }
39870
39871                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39872
39873                             value = customAttribute.value[ chunk_faces4[ f ] ];
39874
39875                             v1 = value[ 0 ];
39876                             v2 = value[ 1 ];
39877                             v3 = value[ 2 ];
39878                             v4 = value[ 3 ];
39879
39880                             customAttribute.array[ offset_custom  ]     = v1[ pp[ 0 ] ];
39881                             customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
39882                             customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
39883
39884                             customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
39885                             customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
39886                             customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
39887
39888                             customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
39889                             customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
39890                             customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
39891
39892                             customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
39893                             customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
39894                             customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
39895
39896                             offset_custom += 12;
39897
39898                         }
39899
39900                     }
39901
39902                 } else if ( customAttribute.size === 4 ) {
39903
39904                     if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
39905
39906                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39907
39908                             face = obj_faces[ chunk_faces3[ f ]    ];
39909
39910                             v1 = customAttribute.value[ face.a ];
39911                             v2 = customAttribute.value[ face.b ];
39912                             v3 = customAttribute.value[ face.c ];
39913
39914                             customAttribute.array[ offset_custom  ]     = v1.x;
39915                             customAttribute.array[ offset_custom + 1  ] = v1.y;
39916                             customAttribute.array[ offset_custom + 2  ] = v1.z;
39917                             customAttribute.array[ offset_custom + 3  ] = v1.w;
39918
39919                             customAttribute.array[ offset_custom + 4  ] = v2.x;
39920                             customAttribute.array[ offset_custom + 5  ] = v2.y;
39921                             customAttribute.array[ offset_custom + 6  ] = v2.z;
39922                             customAttribute.array[ offset_custom + 7  ] = v2.w;
39923
39924                             customAttribute.array[ offset_custom + 8  ] = v3.x;
39925                             customAttribute.array[ offset_custom + 9  ] = v3.y;
39926                             customAttribute.array[ offset_custom + 10 ] = v3.z;
39927                             customAttribute.array[ offset_custom + 11 ] = v3.w;
39928
39929                             offset_custom += 12;
39930
39931                         }
39932
39933                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39934
39935                             face = obj_faces[ chunk_faces4[ f ] ];
39936
39937                             v1 = customAttribute.value[ face.a ];
39938                             v2 = customAttribute.value[ face.b ];
39939                             v3 = customAttribute.value[ face.c ];
39940                             v4 = customAttribute.value[ face.d ];
39941
39942                             customAttribute.array[ offset_custom  ]     = v1.x;
39943                             customAttribute.array[ offset_custom + 1  ] = v1.y;
39944                             customAttribute.array[ offset_custom + 2  ] = v1.z;
39945                             customAttribute.array[ offset_custom + 3  ] = v1.w;
39946
39947                             customAttribute.array[ offset_custom + 4  ] = v2.x;
39948                             customAttribute.array[ offset_custom + 5  ] = v2.y;
39949                             customAttribute.array[ offset_custom + 6  ] = v2.z;
39950                             customAttribute.array[ offset_custom + 7  ] = v2.w;
39951
39952                             customAttribute.array[ offset_custom + 8  ] = v3.x;
39953                             customAttribute.array[ offset_custom + 9  ] = v3.y;
39954                             customAttribute.array[ offset_custom + 10 ] = v3.z;
39955                             customAttribute.array[ offset_custom + 11 ] = v3.w;
39956
39957                             customAttribute.array[ offset_custom + 12 ] = v4.x;
39958                             customAttribute.array[ offset_custom + 13 ] = v4.y;
39959                             customAttribute.array[ offset_custom + 14 ] = v4.z;
39960                             customAttribute.array[ offset_custom + 15 ] = v4.w;
39961
39962                             offset_custom += 16;
39963
39964                         }
39965
39966                     } else if ( customAttribute.boundTo === "faces" ) {
39967
39968                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39969
39970                             value = customAttribute.value[ chunk_faces3[ f ] ];
39971
39972                             v1 = value;
39973                             v2 = value;
39974                             v3 = value;
39975
39976                             customAttribute.array[ offset_custom  ]     = v1.x;
39977                             customAttribute.array[ offset_custom + 1  ] = v1.y;
39978                             customAttribute.array[ offset_custom + 2  ] = v1.z;
39979                             customAttribute.array[ offset_custom + 3  ] = v1.w;
39980
39981                             customAttribute.array[ offset_custom + 4  ] = v2.x;
39982                             customAttribute.array[ offset_custom + 5  ] = v2.y;
39983                             customAttribute.array[ offset_custom + 6  ] = v2.z;
39984                             customAttribute.array[ offset_custom + 7  ] = v2.w;
39985
39986                             customAttribute.array[ offset_custom + 8  ] = v3.x;
39987                             customAttribute.array[ offset_custom + 9  ] = v3.y;
39988                             customAttribute.array[ offset_custom + 10 ] = v3.z;
39989                             customAttribute.array[ offset_custom + 11 ] = v3.w;
39990
39991                             offset_custom += 12;
39992
39993                         }
39994
39995                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39996
39997                             value = customAttribute.value[ chunk_faces4[ f ] ];
39998
39999                             v1 = value;
40000                             v2 = value;
40001                             v3 = value;
40002                             v4 = value;
40003
40004                             customAttribute.array[ offset_custom  ]     = v1.x;
40005                             customAttribute.array[ offset_custom + 1  ] = v1.y;
40006                             customAttribute.array[ offset_custom + 2  ] = v1.z;
40007                             customAttribute.array[ offset_custom + 3  ] = v1.w;
40008
40009                             customAttribute.array[ offset_custom + 4  ] = v2.x;
40010                             customAttribute.array[ offset_custom + 5  ] = v2.y;
40011                             customAttribute.array[ offset_custom + 6  ] = v2.z;
40012                             customAttribute.array[ offset_custom + 7  ] = v2.w;
40013
40014                             customAttribute.array[ offset_custom + 8  ] = v3.x;
40015                             customAttribute.array[ offset_custom + 9  ] = v3.y;
40016                             customAttribute.array[ offset_custom + 10 ] = v3.z;
40017                             customAttribute.array[ offset_custom + 11 ] = v3.w;
40018
40019                             customAttribute.array[ offset_custom + 12 ] = v4.x;
40020                             customAttribute.array[ offset_custom + 13 ] = v4.y;
40021                             customAttribute.array[ offset_custom + 14 ] = v4.z;
40022                             customAttribute.array[ offset_custom + 15 ] = v4.w;
40023
40024                             offset_custom += 16;
40025
40026                         }
40027
40028                     } else if ( customAttribute.boundTo === "faceVertices" ) {
40029
40030                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
40031
40032                             value = customAttribute.value[ chunk_faces3[ f ] ];
40033
40034                             v1 = value[ 0 ];
40035                             v2 = value[ 1 ];
40036                             v3 = value[ 2 ];
40037
40038                             customAttribute.array[ offset_custom  ]     = v1.x;
40039                             customAttribute.array[ offset_custom + 1  ] = v1.y;
40040                             customAttribute.array[ offset_custom + 2  ] = v1.z;
40041                             customAttribute.array[ offset_custom + 3  ] = v1.w;
40042
40043                             customAttribute.array[ offset_custom + 4  ] = v2.x;
40044                             customAttribute.array[ offset_custom + 5  ] = v2.y;
40045                             customAttribute.array[ offset_custom + 6  ] = v2.z;
40046                             customAttribute.array[ offset_custom + 7  ] = v2.w;
40047
40048                             customAttribute.array[ offset_custom + 8  ] = v3.x;
40049                             customAttribute.array[ offset_custom + 9  ] = v3.y;
40050                             customAttribute.array[ offset_custom + 10 ] = v3.z;
40051                             customAttribute.array[ offset_custom + 11 ] = v3.w;
40052
40053                             offset_custom += 12;
40054
40055                         }
40056
40057                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
40058
40059                             value = customAttribute.value[ chunk_faces4[ f ] ];
40060
40061                             v1 = value[ 0 ];
40062                             v2 = value[ 1 ];
40063                             v3 = value[ 2 ];
40064                             v4 = value[ 3 ];
40065
40066                             customAttribute.array[ offset_custom  ]     = v1.x;
40067                             customAttribute.array[ offset_custom + 1  ] = v1.y;
40068                             customAttribute.array[ offset_custom + 2  ] = v1.z;
40069                             customAttribute.array[ offset_custom + 3  ] = v1.w;
40070
40071                             customAttribute.array[ offset_custom + 4  ] = v2.x;
40072                             customAttribute.array[ offset_custom + 5  ] = v2.y;
40073                             customAttribute.array[ offset_custom + 6  ] = v2.z;
40074                             customAttribute.array[ offset_custom + 7  ] = v2.w;
40075
40076                             customAttribute.array[ offset_custom + 8  ] = v3.x;
40077                             customAttribute.array[ offset_custom + 9  ] = v3.y;
40078                             customAttribute.array[ offset_custom + 10 ] = v3.z;
40079                             customAttribute.array[ offset_custom + 11 ] = v3.w;
40080
40081                             customAttribute.array[ offset_custom + 12 ] = v4.x;
40082                             customAttribute.array[ offset_custom + 13 ] = v4.y;
40083                             customAttribute.array[ offset_custom + 14 ] = v4.z;
40084                             customAttribute.array[ offset_custom + 15 ] = v4.w;
40085
40086                             offset_custom += 16;
40087
40088                         }
40089
40090                     }
40091
40092                 }
40093
40094                 _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
40095                 _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
40096
40097             }
40098
40099         }
40100
40101         if ( dispose ) {
40102
40103             delete geometryGroup.__inittedArrays;
40104             delete geometryGroup.__colorArray;
40105             delete geometryGroup.__normalArray;
40106             delete geometryGroup.__tangentArray;
40107             delete geometryGroup.__uvArray;
40108             delete geometryGroup.__uv2Array;
40109             delete geometryGroup.__faceArray;
40110             delete geometryGroup.__vertexArray;
40111             delete geometryGroup.__lineArray;
40112             delete geometryGroup.__skinIndexArray;
40113             delete geometryGroup.__skinWeightArray;
40114
40115         }
40116
40117     };
40118
40119     function setDirectBuffers ( geometry, hint, dispose ) {
40120
40121         var attributes = geometry.attributes;
40122
40123         var index = attributes[ "index" ];
40124         var position = attributes[ "position" ];
40125         var normal = attributes[ "normal" ];
40126         var uv = attributes[ "uv" ];
40127         var color = attributes[ "color" ];
40128         var tangent = attributes[ "tangent" ];
40129
40130         if ( geometry.elementsNeedUpdate && index !== undefined ) {
40131
40132             _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
40133             _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, index.array, hint );
40134
40135         }
40136
40137         if ( geometry.verticesNeedUpdate && position !== undefined ) {
40138
40139             _gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
40140             _gl.bufferData( _gl.ARRAY_BUFFER, position.array, hint );
40141
40142         }
40143
40144         if ( geometry.normalsNeedUpdate && normal !== undefined ) {
40145
40146             _gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
40147             _gl.bufferData( _gl.ARRAY_BUFFER, normal.array, hint );
40148
40149         }
40150
40151         if ( geometry.uvsNeedUpdate && uv !== undefined ) {
40152
40153             _gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
40154             _gl.bufferData( _gl.ARRAY_BUFFER, uv.array, hint );
40155
40156         }
40157
40158         if ( geometry.colorsNeedUpdate && color !== undefined ) {
40159
40160             _gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
40161             _gl.bufferData( _gl.ARRAY_BUFFER, color.array, hint );
40162
40163         }
40164
40165         if ( geometry.tangentsNeedUpdate && tangent !== undefined ) {
40166
40167             _gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
40168             _gl.bufferData( _gl.ARRAY_BUFFER, tangent.array, hint );
40169
40170         }
40171
40172         if ( dispose ) {
40173
40174             for ( var i in geometry.attributes ) {
40175
40176                 delete geometry.attributes[ i ].array;
40177
40178             }
40179
40180         }
40181
40182     };
40183
40184     // Buffer rendering
40185
40186     this.renderBufferImmediate = function ( object, program, material ) {
40187
40188         if ( object.hasPositions && ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
40189         if ( object.hasNormals && ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
40190         if ( object.hasUvs && ! object.__webglUvBuffer ) object.__webglUvBuffer = _gl.createBuffer();
40191         if ( object.hasColors && ! object.__webglColorBuffer ) object.__webglColorBuffer = _gl.createBuffer();
40192
40193         if ( object.hasPositions ) {
40194
40195             _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer );
40196             _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
40197             _gl.enableVertexAttribArray( program.attributes.position );
40198             _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 );
40199
40200         }
40201
40202         if ( object.hasNormals ) {
40203
40204             _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
40205
40206             if ( material.shading === THREE.FlatShading ) {
40207
40208                 var nx, ny, nz,
40209                     nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
40210                     normalArray,
40211                     i, il = object.count * 3;
40212
40213                 for( i = 0; i < il; i += 9 ) {
40214
40215                     normalArray = object.normalArray;
40216
40217                     nax  = normalArray[ i ];
40218                     nay  = normalArray[ i + 1 ];
40219                     naz  = normalArray[ i + 2 ];
40220
40221                     nbx  = normalArray[ i + 3 ];
40222                     nby  = normalArray[ i + 4 ];
40223                     nbz  = normalArray[ i + 5 ];
40224
40225                     ncx  = normalArray[ i + 6 ];
40226                     ncy  = normalArray[ i + 7 ];
40227                     ncz  = normalArray[ i + 8 ];
40228
40229                     nx = ( nax + nbx + ncx ) / 3;
40230                     ny = ( nay + nby + ncy ) / 3;
40231                     nz = ( naz + nbz + ncz ) / 3;
40232
40233                     normalArray[ i ]      = nx;
40234                     normalArray[ i + 1 ] = ny;
40235                     normalArray[ i + 2 ] = nz;
40236
40237                     normalArray[ i + 3 ] = nx;
40238                     normalArray[ i + 4 ] = ny;
40239                     normalArray[ i + 5 ] = nz;
40240
40241                     normalArray[ i + 6 ] = nx;
40242                     normalArray[ i + 7 ] = ny;
40243                     normalArray[ i + 8 ] = nz;
40244
40245                 }
40246
40247             }
40248
40249             _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
40250             _gl.enableVertexAttribArray( program.attributes.normal );
40251             _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
40252
40253         }
40254
40255         if ( object.hasUvs && material.map ) {
40256
40257             _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglUvBuffer );
40258             _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
40259             _gl.enableVertexAttribArray( program.attributes.uv );
40260             _gl.vertexAttribPointer( program.attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
40261
40262         }
40263
40264         if ( object.hasColors && material.vertexColors !== THREE.NoColors ) {
40265
40266             _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglColorBuffer );
40267             _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
40268             _gl.enableVertexAttribArray( program.attributes.color );
40269             _gl.vertexAttribPointer( program.attributes.color, 3, _gl.FLOAT, false, 0, 0 );
40270
40271         }
40272
40273         _gl.drawArrays( _gl.TRIANGLES, 0, object.count );
40274
40275         object.count = 0;
40276
40277     };
40278
40279     this.renderBufferDirect = function ( camera, lights, fog, material, geometry, object ) {
40280
40281         if ( material.visible === false ) return;
40282
40283         var program, attributes, linewidth, primitives, a, attribute;
40284
40285         program = setProgram( camera, lights, fog, material, object );
40286
40287         attributes = program.attributes;
40288
40289         var updateBuffers = false,
40290             wireframeBit = material.wireframe ? 1 : 0,
40291             geometryHash = ( geometry.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
40292
40293         if ( geometryHash !== _currentGeometryGroupHash ) {
40294
40295             _currentGeometryGroupHash = geometryHash;
40296             updateBuffers = true;
40297
40298         }
40299
40300         // render mesh
40301
40302         if ( object instanceof THREE.Mesh ) {
40303
40304             var offsets = geometry.offsets;
40305
40306             // if there is more than 1 chunk
40307             // must set attribute pointers to use new offsets for each chunk
40308             // even if geometry and materials didn't change
40309
40310             if ( offsets.length > 1 ) updateBuffers = true;
40311
40312             for ( var i = 0, il = offsets.length; i < il; ++ i ) {
40313
40314                 var startIndex = offsets[ i ].index;
40315
40316                 if ( updateBuffers ) {
40317
40318                     // vertices
40319
40320                     var position = geometry.attributes[ "position" ];
40321                     var positionSize = position.itemSize;
40322
40323                     _gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
40324                     _gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, startIndex * positionSize * 4 ); // 4 bytes per Float32
40325
40326                     // normals
40327
40328                     var normal = geometry.attributes[ "normal" ];
40329
40330                     if ( attributes.normal >= 0 && normal ) {
40331
40332                         var normalSize = normal.itemSize;
40333
40334                         _gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
40335                         _gl.vertexAttribPointer( attributes.normal, normalSize, _gl.FLOAT, false, 0, startIndex * normalSize * 4 );
40336
40337                     }
40338
40339                     // uvs
40340
40341                     var uv = geometry.attributes[ "uv" ];
40342
40343                     if ( attributes.uv >= 0 && uv ) {
40344
40345                         if ( uv.buffer ) {
40346
40347                             var uvSize = uv.itemSize;
40348
40349                             _gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
40350                             _gl.vertexAttribPointer( attributes.uv, uvSize, _gl.FLOAT, false, 0, startIndex * uvSize * 4 );
40351
40352                             _gl.enableVertexAttribArray( attributes.uv );
40353
40354                         } else {
40355
40356                             _gl.disableVertexAttribArray( attributes.uv );
40357
40358                         }
40359
40360                     }
40361
40362                     // colors
40363
40364                     var color = geometry.attributes[ "color" ];
40365
40366                     if ( attributes.color >= 0 && color ) {
40367
40368                         var colorSize = color.itemSize;
40369
40370                         _gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
40371                         _gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, startIndex * colorSize * 4 );
40372
40373                     }
40374
40375                     // tangents
40376
40377                     var tangent = geometry.attributes[ "tangent" ];
40378
40379                     if ( attributes.tangent >= 0 && tangent ) {
40380
40381                         var tangentSize = tangent.itemSize;
40382
40383                         _gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
40384                         _gl.vertexAttribPointer( attributes.tangent, tangentSize, _gl.FLOAT, false, 0, startIndex * tangentSize * 4 );
40385
40386                     }
40387
40388                     // indices
40389
40390                     var index = geometry.attributes[ "index" ];
40391
40392                     _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
40393
40394                 }
40395
40396                 // render indexed triangles
40397
40398                 _gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 bytes per Uint16
40399
40400                 _this.info.render.calls ++;
40401                 _this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
40402                 _this.info.render.faces += offsets[ i ].count / 3;
40403
40404             }
40405
40406         // render particles
40407
40408         } else if ( object instanceof THREE.ParticleSystem ) {
40409
40410             if ( updateBuffers ) {
40411
40412                 // vertices
40413
40414                 var position = geometry.attributes[ "position" ];
40415                 var positionSize = position.itemSize;
40416
40417                 _gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
40418                 _gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, 0 );
40419
40420                 // colors
40421
40422                 var color = geometry.attributes[ "color" ];
40423
40424                 if ( attributes.color >= 0 && color ) {
40425
40426                     var colorSize = color.itemSize;
40427
40428                     _gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
40429                     _gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, 0 );
40430
40431                 }
40432
40433                 // render particles
40434
40435                 _gl.drawArrays( _gl.POINTS, 0, position.numItems / 3 );
40436
40437                 _this.info.render.calls ++;
40438                 _this.info.render.points += position.numItems / 3;
40439
40440             }
40441
40442         }
40443
40444     };
40445
40446     this.renderBuffer = function ( camera, lights, fog, material, geometryGroup, object ) {
40447
40448         if ( material.visible === false ) return;
40449
40450         var program, attributes, linewidth, primitives, a, attribute, i, il;
40451
40452         program = setProgram( camera, lights, fog, material, object );
40453
40454         attributes = program.attributes;
40455
40456         var updateBuffers = false,
40457             wireframeBit = material.wireframe ? 1 : 0,
40458             geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
40459
40460         if ( geometryGroupHash !== _currentGeometryGroupHash ) {
40461
40462             _currentGeometryGroupHash = geometryGroupHash;
40463             updateBuffers = true;
40464
40465         }
40466
40467         // vertices
40468
40469         if ( !material.morphTargets && attributes.position >= 0 ) {
40470
40471             if ( updateBuffers ) {
40472
40473                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
40474                 _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
40475
40476             }
40477
40478         } else {
40479
40480             if ( object.morphTargetBase ) {
40481
40482                 setupMorphTargets( material, geometryGroup, object );
40483
40484             }
40485
40486         }
40487
40488
40489         if ( updateBuffers ) {
40490
40491             // custom attributes
40492
40493             // Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
40494
40495             if ( geometryGroup.__webglCustomAttributesList ) {
40496
40497                 for ( i = 0, il = geometryGroup.__webglCustomAttributesList.length; i < il; i ++ ) {
40498
40499                     attribute = geometryGroup.__webglCustomAttributesList[ i ];
40500
40501                     if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
40502
40503                         _gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
40504                         _gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
40505
40506                     }
40507
40508                 }
40509
40510             }
40511
40512
40513             // colors
40514
40515             if ( attributes.color >= 0 ) {
40516
40517                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
40518                 _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
40519
40520             }
40521
40522             // normals
40523
40524             if ( attributes.normal >= 0 ) {
40525
40526                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
40527                 _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
40528
40529             }
40530
40531             // tangents
40532
40533             if ( attributes.tangent >= 0 ) {
40534
40535                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
40536                 _gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
40537
40538             }
40539
40540             // uvs
40541
40542             if ( attributes.uv >= 0 ) {
40543
40544                 if ( geometryGroup.__webglUVBuffer ) {
40545
40546                     _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
40547                     _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
40548
40549                     _gl.enableVertexAttribArray( attributes.uv );
40550
40551                 } else {
40552
40553                     _gl.disableVertexAttribArray( attributes.uv );
40554
40555                 }
40556
40557             }
40558
40559             if ( attributes.uv2 >= 0 ) {
40560
40561                 if ( geometryGroup.__webglUV2Buffer ) {
40562
40563                     _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
40564                     _gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
40565
40566                     _gl.enableVertexAttribArray( attributes.uv2 );
40567
40568                 } else {
40569
40570                     _gl.disableVertexAttribArray( attributes.uv2 );
40571
40572                 }
40573
40574             }
40575
40576             if ( material.skinning &&
40577                  attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
40578
40579                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
40580                 _gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
40581
40582                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
40583                 _gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
40584
40585             }
40586
40587         }
40588
40589         // render mesh
40590
40591         if ( object instanceof THREE.Mesh ) {
40592
40593             // wireframe
40594
40595             if ( material.wireframe ) {
40596
40597                 setLineWidth( material.wireframeLinewidth );
40598
40599                 if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
40600                 _gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
40601
40602             // triangles
40603
40604             } else {
40605
40606                 if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
40607                 _gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
40608
40609             }
40610
40611             _this.info.render.calls ++;
40612             _this.info.render.vertices += geometryGroup.__webglFaceCount;
40613             _this.info.render.faces += geometryGroup.__webglFaceCount / 3;
40614
40615         // render lines
40616
40617         } else if ( object instanceof THREE.Line ) {
40618
40619             primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
40620
40621             setLineWidth( material.linewidth );
40622
40623             _gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
40624
40625             _this.info.render.calls ++;
40626
40627         // render particles
40628
40629         } else if ( object instanceof THREE.ParticleSystem ) {
40630
40631             _gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
40632
40633             _this.info.render.calls ++;
40634             _this.info.render.points += geometryGroup.__webglParticleCount;
40635
40636         // render ribbon
40637
40638         } else if ( object instanceof THREE.Ribbon ) {
40639
40640             _gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
40641
40642             _this.info.render.calls ++;
40643
40644         }
40645
40646     };
40647
40648     function setupMorphTargets ( material, geometryGroup, object ) {
40649
40650         // set base
40651
40652         var attributes = material.program.attributes;
40653
40654         if ( object.morphTargetBase !== -1 ) {
40655
40656             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
40657             _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
40658
40659         } else if ( attributes.position >= 0 ) {
40660
40661             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
40662             _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
40663
40664         }
40665
40666         if ( object.morphTargetForcedOrder.length ) {
40667
40668             // set forced order
40669
40670             var m = 0;
40671             var order = object.morphTargetForcedOrder;
40672             var influences = object.morphTargetInfluences;
40673
40674             while ( m < material.numSupportedMorphTargets && m < order.length ) {
40675
40676                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
40677                 _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
40678
40679                 if ( material.morphNormals ) {
40680
40681                     _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ order[ m ] ] );
40682                     _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
40683
40684                 }
40685
40686                 object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];
40687
40688                 m ++;
40689             }
40690
40691         } else {
40692
40693             // find the most influencing
40694
40695             var influence, activeInfluenceIndices = [];
40696             var influences = object.morphTargetInfluences;
40697             var i, il = influences.length;
40698
40699             for ( i = 0; i < il; i ++ ) {
40700
40701                 influence = influences[ i ];
40702
40703                 if ( influence > 0 ) {
40704
40705                     activeInfluenceIndices.push( [ i, influence ] );
40706
40707                 }
40708
40709             }
40710
40711             if ( activeInfluenceIndices.length > material.numSupportedMorphTargets ) {
40712
40713                 activeInfluenceIndices.sort( numericalSort );
40714                 activeInfluenceIndices.length = material.numSupportedMorphTargets;
40715
40716             } else if ( activeInfluenceIndices.length > material.numSupportedMorphNormals ) {
40717
40718                 activeInfluenceIndices.sort( numericalSort );
40719
40720             } else if ( activeInfluenceIndices.length === 0 ) {
40721
40722                 activeInfluenceIndices.push( [ 0, 0 ] );
40723
40724             };
40725
40726             var influenceIndex, m = 0;
40727
40728             while ( m < material.numSupportedMorphTargets ) {
40729
40730                 if ( activeInfluenceIndices[ m ] ) {
40731
40732                     influenceIndex = activeInfluenceIndices[ m ][ 0 ];
40733
40734                     _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] );
40735
40736                     _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
40737
40738                     if ( material.morphNormals ) {
40739
40740                         _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ influenceIndex ] );
40741                         _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
40742
40743                     }
40744
40745                     object.__webglMorphTargetInfluences[ m ] = influences[ influenceIndex ];
40746
40747                 } else {
40748
40749                     _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
40750
40751                     if ( material.morphNormals ) {
40752
40753                         _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
40754
40755                     }
40756
40757                     object.__webglMorphTargetInfluences[ m ] = 0;
40758
40759                 }
40760
40761                 m ++;
40762
40763             }
40764
40765         }
40766
40767         // load updated influences uniform
40768
40769         if ( material.program.uniforms.morphTargetInfluences !== null ) {
40770
40771             _gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
40772
40773         }
40774
40775     };
40776
40777     // Sorting
40778
40779     function painterSort ( a, b ) {
40780
40781         return b.z - a.z;
40782
40783     };
40784
40785     function numericalSort ( a, b ) {
40786
40787         return b[ 1 ] - a[ 1 ];
40788
40789     };
40790
40791
40792     // Rendering
40793
40794     this.render = function ( scene, camera, renderTarget, forceClear ) {
40795
40796         if ( camera instanceof THREE.Camera === false ) {
40797
40798             console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
40799             return;
40800
40801         }
40802
40803         var i, il,
40804
40805         webglObject, object,
40806         renderList,
40807
40808         lights = scene.__lights,
40809         fog = scene.fog;
40810
40811         // reset caching for this frame
40812
40813         _currentMaterialId = -1;
40814         _lightsNeedUpdate = true;
40815
40816         // update scene graph
40817
40818         if ( this.autoUpdateScene ) scene.updateMatrixWorld();
40819
40820         // update camera matrices and frustum
40821
40822         if ( camera.parent === undefined ) camera.updateMatrixWorld();
40823
40824         if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
40825         if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
40826
40827         camera.matrixWorldInverse.getInverse( camera.matrixWorld );
40828
40829         camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );
40830         camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
40831
40832         _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
40833         _frustum.setFromMatrix( _projScreenMatrix );
40834
40835         // update WebGL objects
40836
40837         if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );
40838
40839         // custom render plugins (pre pass)
40840
40841         renderPlugins( this.renderPluginsPre, scene, camera );
40842
40843         //
40844
40845         _this.info.render.calls = 0;
40846         _this.info.render.vertices = 0;
40847         _this.info.render.faces = 0;
40848         _this.info.render.points = 0;
40849
40850         this.setRenderTarget( renderTarget );
40851
40852         if ( this.autoClear || forceClear ) {
40853
40854             this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
40855
40856         }
40857
40858         // set matrices for regular objects (frustum culled)
40859
40860         renderList = scene.__webglObjects;
40861
40862         for ( i = 0, il = renderList.length; i < il; i ++ ) {
40863
40864             webglObject = renderList[ i ];
40865             object = webglObject.object;
40866
40867             webglObject.render = false;
40868
40869             if ( object.visible ) {
40870
40871                 if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
40872
40873                     //object.matrixWorld.flattenToArray( object._modelMatrixArray );
40874
40875                     setupMatrices( object, camera );
40876
40877                     unrollBufferMaterial( webglObject );
40878
40879                     webglObject.render = true;
40880
40881                     if ( this.sortObjects === true ) {
40882
40883                         if ( object.renderDepth !== null ) {
40884
40885                             webglObject.z = object.renderDepth;
40886
40887                         } else {
40888
40889                             _vector3.copy( object.matrixWorld.getPosition() );
40890                             _projScreenMatrix.multiplyVector3( _vector3 );
40891
40892                             webglObject.z = _vector3.z;
40893
40894                         }
40895
40896                     }
40897
40898                 }
40899
40900             }
40901
40902         }
40903
40904         if ( this.sortObjects ) {
40905
40906             renderList.sort( painterSort );
40907
40908         }
40909
40910         // set matrices for immediate objects
40911
40912         renderList = scene.__webglObjectsImmediate;
40913
40914         for ( i = 0, il = renderList.length; i < il; i ++ ) {
40915
40916             webglObject = renderList[ i ];
40917             object = webglObject.object;
40918
40919             if ( object.visible ) {
40920
40921                 /*
40922                 if ( object.matrixAutoUpdate ) {
40923
40924                     object.matrixWorld.flattenToArray( object._modelMatrixArray );
40925
40926                 }
40927                 */
40928
40929                 setupMatrices( object, camera );
40930
40931                 unrollImmediateBufferMaterial( webglObject );
40932
40933             }
40934
40935         }
40936
40937         if ( scene.overrideMaterial ) {
40938
40939             var material = scene.overrideMaterial;
40940
40941             this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
40942             this.setDepthTest( material.depthTest );
40943             this.setDepthWrite( material.depthWrite );
40944             setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
40945
40946             renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
40947             renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
40948
40949         } else {
40950
40951             // opaque pass (front-to-back order)
40952
40953             this.setBlending( THREE.NormalBlending );
40954
40955             renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
40956             renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
40957
40958             // transparent pass (back-to-front order)
40959
40960             renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
40961             renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
40962
40963         }
40964
40965         // custom render plugins (post pass)
40966
40967         renderPlugins( this.renderPluginsPost, scene, camera );
40968
40969
40970         // Generate mipmap if we're using any kind of mipmap filtering
40971
40972         if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
40973
40974             updateRenderTargetMipmap( renderTarget );
40975
40976         }
40977
40978         // Ensure depth buffer writing is enabled so it can be cleared on next render
40979
40980         this.setDepthTest( true );
40981         this.setDepthWrite( true );
40982
40983         // _gl.finish();
40984
40985     };
40986
40987     function renderPlugins( plugins, scene, camera ) {
40988
40989         if ( ! plugins.length ) return;
40990
40991         for ( var i = 0, il = plugins.length; i < il; i ++ ) {
40992
40993             // reset state for plugin (to start from clean slate)
40994
40995             _currentProgram = null;
40996             _currentCamera = null;
40997
40998             _oldBlending = -1;
40999             _oldDepthTest = -1;
41000             _oldDepthWrite = -1;
41001             _oldDoubleSided = -1;
41002             _oldFlipSided = -1;
41003             _currentGeometryGroupHash = -1;
41004             _currentMaterialId = -1;
41005
41006             _lightsNeedUpdate = true;
41007
41008             plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
41009
41010             // reset state after plugin (anything could have changed)
41011
41012             _currentProgram = null;
41013             _currentCamera = null;
41014
41015             _oldBlending = -1;
41016             _oldDepthTest = -1;
41017             _oldDepthWrite = -1;
41018             _oldDoubleSided = -1;
41019             _oldFlipSided = -1;
41020             _currentGeometryGroupHash = -1;
41021             _currentMaterialId = -1;
41022
41023             _lightsNeedUpdate = true;
41024
41025         }
41026
41027     };
41028
41029     function renderObjects ( renderList, reverse, materialType, camera, lights, fog, useBlending, overrideMaterial ) {
41030
41031         var webglObject, object, buffer, material, start, end, delta;
41032
41033         if ( reverse ) {
41034
41035             start = renderList.length - 1;
41036             end = -1;
41037             delta = -1;
41038
41039         } else {
41040
41041             start = 0;
41042             end = renderList.length;
41043             delta = 1;
41044         }
41045
41046         for ( var i = start; i !== end; i += delta ) {
41047
41048             webglObject = renderList[ i ];
41049
41050             if ( webglObject.render ) {
41051
41052                 object = webglObject.object;
41053                 buffer = webglObject.buffer;
41054
41055                 if ( overrideMaterial ) {
41056
41057                     material = overrideMaterial;
41058
41059                 } else {
41060
41061                     material = webglObject[ materialType ];
41062
41063                     if ( ! material ) continue;
41064
41065                     if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
41066
41067                     _this.setDepthTest( material.depthTest );
41068                     _this.setDepthWrite( material.depthWrite );
41069                     setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
41070
41071                 }
41072
41073                 _this.setMaterialFaces( material );
41074
41075                 if ( buffer instanceof THREE.BufferGeometry ) {
41076
41077                     _this.renderBufferDirect( camera, lights, fog, material, buffer, object );
41078
41079                 } else {
41080
41081                     _this.renderBuffer( camera, lights, fog, material, buffer, object );
41082
41083                 }
41084
41085             }
41086
41087         }
41088
41089     };
41090
41091     function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, useBlending, overrideMaterial ) {
41092
41093         var webglObject, object, material, program;
41094
41095         for ( var i = 0, il = renderList.length; i < il; i ++ ) {
41096
41097             webglObject = renderList[ i ];
41098             object = webglObject.object;
41099
41100             if ( object.visible ) {
41101
41102                 if ( overrideMaterial ) {
41103
41104                     material = overrideMaterial;
41105
41106                 } else {
41107
41108                     material = webglObject[ materialType ];
41109
41110                     if ( ! material ) continue;
41111
41112                     if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
41113
41114                     _this.setDepthTest( material.depthTest );
41115                     _this.setDepthWrite( material.depthWrite );
41116                     setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
41117
41118                 }
41119
41120                 _this.renderImmediateObject( camera, lights, fog, material, object );
41121
41122             }
41123
41124         }
41125
41126     };
41127
41128     this.renderImmediateObject = function ( camera, lights, fog, material, object ) {
41129
41130         var program = setProgram( camera, lights, fog, material, object );
41131
41132         _currentGeometryGroupHash = -1;
41133
41134         _this.setMaterialFaces( material );
41135
41136         if ( object.immediateRenderCallback ) {
41137
41138             object.immediateRenderCallback( program, _gl, _frustum );
41139
41140         } else {
41141
41142             object.render( function( object ) { _this.renderBufferImmediate( object, program, material ); } );
41143
41144         }
41145
41146     };
41147
41148     function unrollImmediateBufferMaterial ( globject ) {
41149
41150         var object = globject.object,
41151             material = object.material;
41152
41153         if ( material.transparent ) {
41154
41155             globject.transparent = material;
41156             globject.opaque = null;
41157
41158         } else {
41159
41160             globject.opaque = material;
41161             globject.transparent = null;
41162
41163         }
41164
41165     };
41166
41167     function unrollBufferMaterial ( globject ) {
41168
41169         var object = globject.object,
41170             buffer = globject.buffer,
41171             material, materialIndex, meshMaterial;
41172
41173         meshMaterial = object.material;
41174
41175         if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
41176
41177             materialIndex = buffer.materialIndex;
41178
41179             if ( materialIndex >= 0 ) {
41180
41181                 material = object.geometry.materials[ materialIndex ];
41182
41183                 if ( material.transparent ) {
41184
41185                     globject.transparent = material;
41186                     globject.opaque = null;
41187
41188                 } else {
41189
41190                     globject.opaque = material;
41191                     globject.transparent = null;
41192
41193                 }
41194
41195             }
41196
41197         } else {
41198
41199             material = meshMaterial;
41200
41201             if ( material ) {
41202
41203                 if ( material.transparent ) {
41204
41205                     globject.transparent = material;
41206                     globject.opaque = null;
41207
41208                 } else {
41209
41210                     globject.opaque = material;
41211                     globject.transparent = null;
41212
41213                 }
41214
41215             }
41216
41217         }
41218
41219     };
41220
41221     // Geometry splitting
41222
41223     function sortFacesByMaterial ( geometry ) {
41224
41225         var f, fl, face, materialIndex, vertices,
41226             materialHash, groupHash,
41227             hash_map = {};
41228
41229         var numMorphTargets = geometry.morphTargets.length;
41230         var numMorphNormals = geometry.morphNormals.length;
41231
41232         geometry.geometryGroups = {};
41233
41234         for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
41235
41236             face = geometry.faces[ f ];
41237             materialIndex = face.materialIndex;
41238
41239             materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
41240
41241             if ( hash_map[ materialHash ] === undefined ) {
41242
41243                 hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
41244
41245             }
41246
41247             groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
41248
41249             if ( geometry.geometryGroups[ groupHash ] === undefined ) {
41250
41251                 geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
41252
41253             }
41254
41255             vertices = face instanceof THREE.Face3 ? 3 : 4;
41256
41257             if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) {
41258
41259                 hash_map[ materialHash ].counter += 1;
41260                 groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
41261
41262                 if ( geometry.geometryGroups[ groupHash ] === undefined ) {
41263
41264                     geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
41265
41266                 }
41267
41268             }
41269
41270             if ( face instanceof THREE.Face3 ) {
41271
41272                 geometry.geometryGroups[ groupHash ].faces3.push( f );
41273
41274             } else {
41275
41276                 geometry.geometryGroups[ groupHash ].faces4.push( f );
41277
41278             }
41279
41280             geometry.geometryGroups[ groupHash ].vertices += vertices;
41281
41282         }
41283
41284         geometry.geometryGroupsList = [];
41285
41286         for ( var g in geometry.geometryGroups ) {
41287
41288             geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
41289
41290             geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
41291
41292         }
41293
41294     };
41295
41296     // Objects refresh
41297
41298     this.initWebGLObjects = function ( scene ) {
41299
41300         if ( !scene.__webglObjects ) {
41301
41302             scene.__webglObjects = [];
41303             scene.__webglObjectsImmediate = [];
41304             scene.__webglSprites = [];
41305             scene.__webglFlares = [];
41306
41307         }
41308
41309         while ( scene.__objectsAdded.length ) {
41310
41311             addObject( scene.__objectsAdded[ 0 ], scene );
41312             scene.__objectsAdded.splice( 0, 1 );
41313
41314         }
41315
41316         while ( scene.__objectsRemoved.length ) {
41317
41318             removeObject( scene.__objectsRemoved[ 0 ], scene );
41319             scene.__objectsRemoved.splice( 0, 1 );
41320
41321         }
41322
41323         // update must be called after objects adding / removal
41324
41325         for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) {
41326
41327             updateObject( scene.__webglObjects[ o ].object );
41328
41329         }
41330
41331     };
41332
41333     // Objects adding
41334
41335     function addObject ( object, scene ) {
41336
41337         var g, geometry, geometryGroup;
41338
41339         if ( ! object.__webglInit ) {
41340
41341             object.__webglInit = true;
41342
41343             object._modelViewMatrix = new THREE.Matrix4();
41344             object._normalMatrix = new THREE.Matrix3();
41345
41346             if ( object instanceof THREE.Mesh ) {
41347
41348                 geometry = object.geometry;
41349
41350                 if ( geometry instanceof THREE.Geometry ) {
41351
41352                     if ( geometry.geometryGroups === undefined ) {
41353
41354                         sortFacesByMaterial( geometry );
41355
41356                     }
41357
41358                     // create separate VBOs per geometry chunk
41359
41360                     for ( g in geometry.geometryGroups ) {
41361
41362                         geometryGroup = geometry.geometryGroups[ g ];
41363
41364                         // initialise VBO on the first access
41365
41366                         if ( ! geometryGroup.__webglVertexBuffer ) {
41367
41368                             createMeshBuffers( geometryGroup );
41369                             initMeshBuffers( geometryGroup, object );
41370
41371                             geometry.verticesNeedUpdate = true;
41372                             geometry.morphTargetsNeedUpdate = true;
41373                             geometry.elementsNeedUpdate = true;
41374                             geometry.uvsNeedUpdate = true;
41375                             geometry.normalsNeedUpdate = true;
41376                             geometry.tangentsNeedUpdate = true;
41377                             geometry.colorsNeedUpdate = true;
41378
41379                         }
41380
41381                     }
41382
41383                 } else if ( geometry instanceof THREE.BufferGeometry ) {
41384
41385                     initDirectBuffers( geometry );
41386
41387                 }
41388
41389             } else if ( object instanceof THREE.Ribbon ) {
41390
41391                 geometry = object.geometry;
41392
41393                 if( ! geometry.__webglVertexBuffer ) {
41394
41395                     createRibbonBuffers( geometry );
41396                     initRibbonBuffers( geometry );
41397
41398                     geometry.verticesNeedUpdate = true;
41399                     geometry.colorsNeedUpdate = true;
41400
41401                 }
41402
41403             } else if ( object instanceof THREE.Line ) {
41404
41405                 geometry = object.geometry;
41406
41407                 if( ! geometry.__webglVertexBuffer ) {
41408
41409                     createLineBuffers( geometry );
41410                     initLineBuffers( geometry, object );
41411
41412                     geometry.verticesNeedUpdate = true;
41413                     geometry.colorsNeedUpdate = true;
41414
41415                 }
41416
41417             } else if ( object instanceof THREE.ParticleSystem ) {
41418
41419                 geometry = object.geometry;
41420
41421                 if ( ! geometry.__webglVertexBuffer ) {
41422
41423                     if ( geometry instanceof THREE.Geometry ) {
41424
41425                         createParticleBuffers( geometry );
41426                         initParticleBuffers( geometry, object );
41427
41428                         geometry.verticesNeedUpdate = true;
41429                         geometry.colorsNeedUpdate = true;
41430
41431                     } else if ( geometry instanceof THREE.BufferGeometry ) {
41432
41433                         initDirectBuffers( geometry );
41434
41435                     }
41436
41437
41438                 }
41439
41440             }
41441
41442         }
41443
41444         if ( ! object.__webglActive ) {
41445
41446             if ( object instanceof THREE.Mesh ) {
41447
41448                 geometry = object.geometry;
41449
41450                 if ( geometry instanceof THREE.BufferGeometry ) {
41451
41452                     addBuffer( scene.__webglObjects, geometry, object );
41453
41454                 } else {
41455
41456                     for ( g in geometry.geometryGroups ) {
41457
41458                         geometryGroup = geometry.geometryGroups[ g ];
41459
41460                         addBuffer( scene.__webglObjects, geometryGroup, object );
41461
41462                     }
41463
41464                 }
41465
41466             } else if ( object instanceof THREE.Ribbon ||
41467                         object instanceof THREE.Line ||
41468                         object instanceof THREE.ParticleSystem ) {
41469
41470                 geometry = object.geometry;
41471                 addBuffer( scene.__webglObjects, geometry, object );
41472
41473             } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
41474
41475                 addBufferImmediate( scene.__webglObjectsImmediate, object );
41476
41477             } else if ( object instanceof THREE.Sprite ) {
41478
41479                 scene.__webglSprites.push( object );
41480
41481             } else if ( object instanceof THREE.LensFlare ) {
41482
41483                 scene.__webglFlares.push( object );
41484
41485             }
41486
41487             object.__webglActive = true;
41488
41489         }
41490
41491     };
41492
41493     function addBuffer ( objlist, buffer, object ) {
41494
41495         objlist.push(
41496             {
41497                 buffer: buffer,
41498                 object: object,
41499                 opaque: null,
41500                 transparent: null
41501             }
41502         );
41503
41504     };
41505
41506     function addBufferImmediate ( objlist, object ) {
41507
41508         objlist.push(
41509             {
41510                 object: object,
41511                 opaque: null,
41512                 transparent: null
41513             }
41514         );
41515
41516     };
41517
41518     // Objects updates
41519
41520     function updateObject ( object ) {
41521
41522         var geometry = object.geometry,
41523             geometryGroup, customAttributesDirty, material;
41524
41525         if ( object instanceof THREE.Mesh ) {
41526
41527             if ( geometry instanceof THREE.BufferGeometry ) {
41528
41529                 if ( geometry.verticesNeedUpdate || geometry.elementsNeedUpdate ||
41530                      geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
41531                      geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate ) {
41532
41533                     setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
41534
41535                 }
41536
41537                 geometry.verticesNeedUpdate = false;
41538                 geometry.elementsNeedUpdate = false;
41539                 geometry.uvsNeedUpdate = false;
41540                 geometry.normalsNeedUpdate = false;
41541                 geometry.colorsNeedUpdate = false;
41542                 geometry.tangentsNeedUpdate = false;
41543
41544             } else {
41545
41546                 // check all geometry groups
41547
41548                 for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {
41549
41550                     geometryGroup = geometry.geometryGroupsList[ i ];
41551
41552                     material = getBufferMaterial( object, geometryGroup );
41553
41554                     customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
41555
41556                     if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
41557                          geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
41558                          geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
41559
41560                         setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic, material );
41561
41562                     }
41563
41564                 }
41565
41566                 geometry.verticesNeedUpdate = false;
41567                 geometry.morphTargetsNeedUpdate = false;
41568                 geometry.elementsNeedUpdate = false;
41569                 geometry.uvsNeedUpdate = false;
41570                 geometry.normalsNeedUpdate = false;
41571                 geometry.colorsNeedUpdate = false;
41572                 geometry.tangentsNeedUpdate = false;
41573
41574                 material.attributes && clearCustomAttributes( material );
41575
41576             }
41577
41578         } else if ( object instanceof THREE.Ribbon ) {
41579
41580             if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
41581
41582                 setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
41583
41584             }
41585
41586             geometry.verticesNeedUpdate = false;
41587             geometry.colorsNeedUpdate = false;
41588
41589         } else if ( object instanceof THREE.Line ) {
41590
41591             material = getBufferMaterial( object, geometryGroup );
41592
41593             customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
41594
41595             if ( geometry.verticesNeedUpdate ||  geometry.colorsNeedUpdate || customAttributesDirty ) {
41596
41597                 setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
41598
41599             }
41600
41601             geometry.verticesNeedUpdate = false;
41602             geometry.colorsNeedUpdate = false;
41603
41604             material.attributes && clearCustomAttributes( material );
41605
41606         } else if ( object instanceof THREE.ParticleSystem ) {
41607
41608             if ( geometry instanceof THREE.BufferGeometry ) {
41609
41610                 if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
41611
41612                     setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
41613
41614                 }
41615
41616                 geometry.verticesNeedUpdate = false;
41617                 geometry.colorsNeedUpdate = false;
41618
41619             } else {
41620
41621                 material = getBufferMaterial( object, geometryGroup );
41622
41623                 customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
41624
41625                 if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {
41626
41627                     setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
41628
41629                 }
41630
41631                 geometry.verticesNeedUpdate = false;
41632                 geometry.colorsNeedUpdate = false;
41633
41634                 material.attributes && clearCustomAttributes( material );
41635
41636             }
41637
41638         }
41639
41640     };
41641
41642     // Objects updates - custom attributes check
41643
41644     function areCustomAttributesDirty ( material ) {
41645
41646         for ( var a in material.attributes ) {
41647
41648             if ( material.attributes[ a ].needsUpdate ) return true;
41649
41650         }
41651
41652         return false;
41653
41654     };
41655
41656     function clearCustomAttributes ( material ) {
41657
41658         for ( var a in material.attributes ) {
41659
41660             material.attributes[ a ].needsUpdate = false;
41661
41662         }
41663
41664     };
41665
41666     // Objects removal
41667
41668     function removeObject ( object, scene ) {
41669
41670         if ( object instanceof THREE.Mesh  ||
41671              object instanceof THREE.ParticleSystem ||
41672              object instanceof THREE.Ribbon ||
41673              object instanceof THREE.Line ) {
41674
41675             removeInstances( scene.__webglObjects, object );
41676
41677         } else if ( object instanceof THREE.Sprite ) {
41678
41679             removeInstancesDirect( scene.__webglSprites, object );
41680
41681         } else if ( object instanceof THREE.LensFlare ) {
41682
41683             removeInstancesDirect( scene.__webglFlares, object );
41684
41685         } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
41686
41687             removeInstances( scene.__webglObjectsImmediate, object );
41688
41689         }
41690
41691         object.__webglActive = false;
41692
41693     };
41694
41695     function removeInstances ( objlist, object ) {
41696
41697         for ( var o = objlist.length - 1; o >= 0; o -- ) {
41698
41699             if ( objlist[ o ].object === object ) {
41700
41701                 objlist.splice( o, 1 );
41702
41703             }
41704
41705         }
41706
41707     };
41708
41709     function removeInstancesDirect ( objlist, object ) {
41710
41711         for ( var o = objlist.length - 1; o >= 0; o -- ) {
41712
41713             if ( objlist[ o ] === object ) {
41714
41715                 objlist.splice( o, 1 );
41716
41717             }
41718
41719         }
41720
41721     };
41722
41723     // Materials
41724
41725     this.initMaterial = function ( material, lights, fog, object ) {
41726
41727         var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
41728
41729         if ( material instanceof THREE.MeshDepthMaterial ) {
41730
41731             shaderID = 'depth';
41732
41733         } else if ( material instanceof THREE.MeshNormalMaterial ) {
41734
41735             shaderID = 'normal';
41736
41737         } else if ( material instanceof THREE.MeshBasicMaterial ) {
41738
41739             shaderID = 'basic';
41740
41741         } else if ( material instanceof THREE.MeshLambertMaterial ) {
41742
41743             shaderID = 'lambert';
41744
41745         } else if ( material instanceof THREE.MeshPhongMaterial ) {
41746
41747             shaderID = 'phong';
41748
41749         } else if ( material instanceof THREE.LineBasicMaterial ) {
41750
41751             shaderID = 'basic';
41752
41753         } else if ( material instanceof THREE.ParticleBasicMaterial ) {
41754
41755             shaderID = 'particle_basic';
41756
41757         }
41758
41759         if ( shaderID ) {
41760
41761             setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
41762
41763         }
41764
41765         // heuristics to create shader parameters according to lights in the scene
41766         // (not to blow over maxLights budget)
41767
41768         maxLightCount = allocateLights( lights );
41769
41770         maxShadows = allocateShadows( lights );
41771
41772         maxBones = allocateBones( object );
41773
41774         parameters = {
41775
41776             map: !!material.map,
41777             envMap: !!material.envMap,
41778             lightMap: !!material.lightMap,
41779             bumpMap: !!material.bumpMap,
41780             normalMap: !!material.normalMap,
41781             specularMap: !!material.specularMap,
41782
41783             vertexColors: material.vertexColors,
41784
41785             fog: fog,
41786             useFog: material.fog,
41787
41788             sizeAttenuation: material.sizeAttenuation,
41789
41790             skinning: material.skinning,
41791             maxBones: maxBones,
41792             useVertexTexture: _supportsBoneTextures && object && object.useVertexTexture,
41793             boneTextureWidth: object && object.boneTextureWidth,
41794             boneTextureHeight: object && object.boneTextureHeight,
41795
41796             morphTargets: material.morphTargets,
41797             morphNormals: material.morphNormals,
41798             maxMorphTargets: this.maxMorphTargets,
41799             maxMorphNormals: this.maxMorphNormals,
41800
41801             maxDirLights: maxLightCount.directional,
41802             maxPointLights: maxLightCount.point,
41803             maxSpotLights: maxLightCount.spot,
41804             maxHemiLights: maxLightCount.hemi,
41805
41806             maxShadows: maxShadows,
41807             shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
41808             shadowMapSoft: this.shadowMapSoft,
41809             shadowMapDebug: this.shadowMapDebug,
41810             shadowMapCascade: this.shadowMapCascade,
41811
41812             alphaTest: material.alphaTest,
41813             metal: material.metal,
41814             perPixel: material.perPixel,
41815             wrapAround: material.wrapAround,
41816             doubleSided: material.side === THREE.DoubleSide,
41817             flipSided: material.side === THREE.BackSide
41818
41819         };
41820
41821         material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
41822
41823         var attributes = material.program.attributes;
41824
41825         if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
41826         if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
41827         if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
41828         if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
41829
41830         if ( material.skinning &&
41831              attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
41832
41833             _gl.enableVertexAttribArray( attributes.skinIndex );
41834             _gl.enableVertexAttribArray( attributes.skinWeight );
41835
41836         }
41837
41838         if ( material.attributes ) {
41839
41840             for ( a in material.attributes ) {
41841
41842                 if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
41843
41844             }
41845
41846         }
41847
41848         if ( material.morphTargets ) {
41849
41850             material.numSupportedMorphTargets = 0;
41851
41852             var id, base = "morphTarget";
41853
41854             for ( i = 0; i < this.maxMorphTargets; i ++ ) {
41855
41856                 id = base + i;
41857
41858                 if ( attributes[ id ] >= 0 ) {
41859
41860                     _gl.enableVertexAttribArray( attributes[ id ] );
41861                     material.numSupportedMorphTargets ++;
41862
41863                 }
41864
41865             }
41866
41867         }
41868
41869         if ( material.morphNormals ) {
41870
41871             material.numSupportedMorphNormals = 0;
41872
41873             var id, base = "morphNormal";
41874
41875             for ( i = 0; i < this.maxMorphNormals; i ++ ) {
41876
41877                 id = base + i;
41878
41879                 if ( attributes[ id ] >= 0 ) {
41880
41881                     _gl.enableVertexAttribArray( attributes[ id ] );
41882                     material.numSupportedMorphNormals ++;
41883
41884                 }
41885
41886             }
41887
41888         }
41889
41890         material.uniformsList = [];
41891
41892         for ( u in material.uniforms ) {
41893
41894             material.uniformsList.push( [ material.uniforms[ u ], u ] );
41895
41896         }
41897
41898     };
41899
41900     function setMaterialShaders( material, shaders ) {
41901
41902         material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
41903         material.vertexShader = shaders.vertexShader;
41904         material.fragmentShader = shaders.fragmentShader;
41905
41906     };
41907
41908     function setProgram( camera, lights, fog, material, object ) {
41909
41910         _usedTextureUnits = 0;
41911
41912         if ( material.needsUpdate ) {
41913
41914             if ( material.program ) _this.deallocateMaterial( material );
41915
41916             _this.initMaterial( material, lights, fog, object );
41917             material.needsUpdate = false;
41918
41919         }
41920
41921         if ( material.morphTargets ) {
41922
41923             if ( ! object.__webglMorphTargetInfluences ) {
41924
41925                 object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
41926
41927             }
41928
41929         }
41930
41931         var refreshMaterial = false;
41932
41933         var program = material.program,
41934             p_uniforms = program.uniforms,
41935             m_uniforms = material.uniforms;
41936
41937         if ( program !== _currentProgram ) {
41938
41939             _gl.useProgram( program );
41940             _currentProgram = program;
41941
41942             refreshMaterial = true;
41943
41944         }
41945
41946         if ( material.id !== _currentMaterialId ) {
41947
41948             _currentMaterialId = material.id;
41949             refreshMaterial = true;
41950
41951         }
41952
41953         if ( refreshMaterial || camera !== _currentCamera ) {
41954
41955             _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera._projectionMatrixArray );
41956
41957             if ( camera !== _currentCamera ) _currentCamera = camera;
41958
41959         }
41960
41961         // skinning uniforms must be set even if material didn't change
41962         // auto-setting of texture unit for bone texture must go before other textures
41963         // not sure why, but otherwise weird things happen
41964
41965         if ( material.skinning ) {
41966
41967             if ( _supportsBoneTextures && object.useVertexTexture ) {
41968
41969                 if ( p_uniforms.boneTexture !== null ) {
41970
41971                     var textureUnit = getTextureUnit();
41972
41973                     _gl.uniform1i( p_uniforms.boneTexture, textureUnit );
41974                     _this.setTexture( object.boneTexture, textureUnit );
41975
41976                 }
41977
41978             } else {
41979
41980                 if ( p_uniforms.boneGlobalMatrices !== null ) {
41981
41982                     _gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
41983
41984                 }
41985
41986             }
41987
41988         }
41989
41990         if ( refreshMaterial ) {
41991
41992             // refresh uniforms common to several materials
41993
41994             if ( fog && material.fog ) {
41995
41996                 refreshUniformsFog( m_uniforms, fog );
41997
41998             }
41999
42000             if ( material instanceof THREE.MeshPhongMaterial ||
42001                  material instanceof THREE.MeshLambertMaterial ||
42002                  material.lights ) {
42003
42004                 if ( _lightsNeedUpdate ) {
42005
42006                     setupLights( program, lights );
42007                     _lightsNeedUpdate = false;
42008
42009                 }
42010
42011                 refreshUniformsLights( m_uniforms, _lights );
42012
42013             }
42014
42015             if ( material instanceof THREE.MeshBasicMaterial ||
42016                  material instanceof THREE.MeshLambertMaterial ||
42017                  material instanceof THREE.MeshPhongMaterial ) {
42018
42019                 refreshUniformsCommon( m_uniforms, material );
42020
42021             }
42022
42023             // refresh single material specific uniforms
42024
42025             if ( material instanceof THREE.LineBasicMaterial ) {
42026
42027                 refreshUniformsLine( m_uniforms, material );
42028
42029             } else if ( material instanceof THREE.ParticleBasicMaterial ) {
42030
42031                 refreshUniformsParticle( m_uniforms, material );
42032
42033             } else if ( material instanceof THREE.MeshPhongMaterial ) {
42034
42035                 refreshUniformsPhong( m_uniforms, material );
42036
42037             } else if ( material instanceof THREE.MeshLambertMaterial ) {
42038
42039                 refreshUniformsLambert( m_uniforms, material );
42040
42041             } else if ( material instanceof THREE.MeshDepthMaterial ) {
42042
42043                 m_uniforms.mNear.value = camera.near;
42044                 m_uniforms.mFar.value = camera.far;
42045                 m_uniforms.opacity.value = material.opacity;
42046
42047             } else if ( material instanceof THREE.MeshNormalMaterial ) {
42048
42049                 m_uniforms.opacity.value = material.opacity;
42050
42051             }
42052
42053             if ( object.receiveShadow && ! material._shadowPass ) {
42054
42055                 refreshUniformsShadow( m_uniforms, lights );
42056
42057             }
42058
42059             // load common uniforms
42060
42061             loadUniformsGeneric( program, material.uniformsList );
42062
42063             // load material specific uniforms
42064             // (shader material also gets them for the sake of genericity)
42065
42066             if ( material instanceof THREE.ShaderMaterial ||
42067                  material instanceof THREE.MeshPhongMaterial ||
42068                  material.envMap ) {
42069
42070                 if ( p_uniforms.cameraPosition !== null ) {
42071
42072                     var position = camera.matrixWorld.getPosition();
42073                     _gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
42074
42075                 }
42076
42077             }
42078
42079             if ( material instanceof THREE.MeshPhongMaterial ||
42080                  material instanceof THREE.MeshLambertMaterial ||
42081                  material instanceof THREE.ShaderMaterial ||
42082                  material.skinning ) {
42083
42084                 if ( p_uniforms.viewMatrix !== null ) {
42085
42086                     _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera._viewMatrixArray );
42087
42088                 }
42089
42090             }
42091
42092         }
42093
42094         loadUniformsMatrices( p_uniforms, object );
42095
42096         if ( p_uniforms.modelMatrix !== null ) {
42097
42098             _gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements );
42099
42100         }
42101
42102         return program;
42103
42104     };
42105
42106     // Uniforms (refresh uniforms objects)
42107
42108     function refreshUniformsCommon ( uniforms, material ) {
42109
42110         uniforms.opacity.value = material.opacity;
42111
42112         if ( _this.gammaInput ) {
42113
42114             uniforms.diffuse.value.copyGammaToLinear( material.color );
42115
42116         } else {
42117
42118             uniforms.diffuse.value = material.color;
42119
42120         }
42121
42122         uniforms.map.value = material.map;
42123         uniforms.lightMap.value = material.lightMap;
42124         uniforms.specularMap.value = material.specularMap;
42125
42126         if ( material.bumpMap ) {
42127
42128             uniforms.bumpMap.value = material.bumpMap;
42129             uniforms.bumpScale.value = material.bumpScale;
42130
42131         }
42132
42133         if ( material.normalMap ) {
42134
42135             uniforms.normalMap.value = material.normalMap;
42136             uniforms.normalScale.value.copy( material.normalScale );
42137
42138         }
42139
42140         // uv repeat and offset setting priorities
42141         //    1. color map
42142         //    2. specular map
42143         //    3. normal map
42144         //    4. bump map
42145
42146         var uvScaleMap;
42147
42148         if ( material.map ) {
42149
42150             uvScaleMap = material.map;
42151
42152         } else if ( material.specularMap ) {
42153
42154             uvScaleMap = material.specularMap;
42155
42156         } else if ( material.normalMap ) {
42157
42158             uvScaleMap = material.normalMap;
42159
42160         } else if ( material.bumpMap ) {
42161
42162             uvScaleMap = material.bumpMap;
42163
42164         }
42165
42166         if ( uvScaleMap !== undefined ) {
42167
42168             var offset = uvScaleMap.offset;
42169             var repeat = uvScaleMap.repeat;
42170
42171             uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
42172
42173         }
42174
42175         uniforms.envMap.value = material.envMap;
42176         uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
42177
42178         if ( _this.gammaInput ) {
42179
42180             //uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
42181             uniforms.reflectivity.value = material.reflectivity;
42182
42183         } else {
42184
42185             uniforms.reflectivity.value = material.reflectivity;
42186
42187         }
42188
42189         uniforms.refractionRatio.value = material.refractionRatio;
42190         uniforms.combine.value = material.combine;
42191         uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
42192
42193     };
42194
42195     function refreshUniformsLine ( uniforms, material ) {
42196
42197         uniforms.diffuse.value = material.color;
42198         uniforms.opacity.value = material.opacity;
42199
42200     };
42201
42202     function refreshUniformsParticle ( uniforms, material ) {
42203
42204         uniforms.psColor.value = material.color;
42205         uniforms.opacity.value = material.opacity;
42206         uniforms.size.value = material.size;
42207         uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
42208
42209         uniforms.map.value = material.map;
42210
42211     };
42212
42213     function refreshUniformsFog ( uniforms, fog ) {
42214
42215         uniforms.fogColor.value = fog.color;
42216
42217         if ( fog instanceof THREE.Fog ) {
42218
42219             uniforms.fogNear.value = fog.near;
42220             uniforms.fogFar.value = fog.far;
42221
42222         } else if ( fog instanceof THREE.FogExp2 ) {
42223
42224             uniforms.fogDensity.value = fog.density;
42225
42226         }
42227
42228     };
42229
42230     function refreshUniformsPhong ( uniforms, material ) {
42231
42232         uniforms.shininess.value = material.shininess;
42233
42234         if ( _this.gammaInput ) {
42235
42236             uniforms.ambient.value.copyGammaToLinear( material.ambient );
42237             uniforms.emissive.value.copyGammaToLinear( material.emissive );
42238             uniforms.specular.value.copyGammaToLinear( material.specular );
42239
42240         } else {
42241
42242             uniforms.ambient.value = material.ambient;
42243             uniforms.emissive.value = material.emissive;
42244             uniforms.specular.value = material.specular;
42245
42246         }
42247
42248         if ( material.wrapAround ) {
42249
42250             uniforms.wrapRGB.value.copy( material.wrapRGB );
42251
42252         }
42253
42254     };
42255
42256     function refreshUniformsLambert ( uniforms, material ) {
42257
42258         if ( _this.gammaInput ) {
42259
42260             uniforms.ambient.value.copyGammaToLinear( material.ambient );
42261             uniforms.emissive.value.copyGammaToLinear( material.emissive );
42262
42263         } else {
42264
42265             uniforms.ambient.value = material.ambient;
42266             uniforms.emissive.value = material.emissive;
42267
42268         }
42269
42270         if ( material.wrapAround ) {
42271
42272             uniforms.wrapRGB.value.copy( material.wrapRGB );
42273
42274         }
42275
42276     };
42277
42278     function refreshUniformsLights ( uniforms, lights ) {
42279
42280         uniforms.ambientLightColor.value = lights.ambient;
42281
42282         uniforms.directionalLightColor.value = lights.directional.colors;
42283         uniforms.directionalLightDirection.value = lights.directional.positions;
42284
42285         uniforms.pointLightColor.value = lights.point.colors;
42286         uniforms.pointLightPosition.value = lights.point.positions;
42287         uniforms.pointLightDistance.value = lights.point.distances;
42288
42289         uniforms.spotLightColor.value = lights.spot.colors;
42290         uniforms.spotLightPosition.value = lights.spot.positions;
42291         uniforms.spotLightDistance.value = lights.spot.distances;
42292         uniforms.spotLightDirection.value = lights.spot.directions;
42293         uniforms.spotLightAngle.value = lights.spot.angles;
42294         uniforms.spotLightExponent.value = lights.spot.exponents;
42295
42296         uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
42297         uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
42298         uniforms.hemisphereLightPosition.value = lights.hemi.positions;
42299
42300     };
42301
42302     function refreshUniformsShadow ( uniforms, lights ) {
42303
42304         if ( uniforms.shadowMatrix ) {
42305
42306             var j = 0;
42307
42308             for ( var i = 0, il = lights.length; i < il; i ++ ) {
42309
42310                 var light = lights[ i ];
42311
42312                 if ( ! light.castShadow ) continue;
42313
42314                 if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
42315
42316                     uniforms.shadowMap.value[ j ] = light.shadowMap;
42317                     uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
42318
42319                     uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;
42320
42321                     uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
42322                     uniforms.shadowBias.value[ j ] = light.shadowBias;
42323
42324                     j ++;
42325
42326                 }
42327
42328             }
42329
42330         }
42331
42332     };
42333
42334     // Uniforms (load to GPU)
42335
42336     function loadUniformsMatrices ( uniforms, object ) {
42337
42338         _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements );
42339
42340         if ( uniforms.normalMatrix ) {
42341
42342             _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrix.elements );
42343
42344         }
42345
42346     };
42347
42348     function getTextureUnit() {
42349
42350         var textureUnit = _usedTextureUnits;
42351
42352         if ( textureUnit >= _maxTextures ) {
42353
42354             console.warn( "Trying to use " + textureUnit + " texture units while this GPU supports only " + _maxTextures );
42355
42356         }
42357
42358         _usedTextureUnits += 1;
42359
42360         return textureUnit;
42361
42362     };
42363
42364     function loadUniformsGeneric ( program, uniforms ) {
42365
42366         var uniform, value, type, location, texture, textureUnit, i, il, j, jl, offset;
42367
42368         for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
42369
42370             location = program.uniforms[ uniforms[ j ][ 1 ] ];
42371             if ( !location ) continue;
42372
42373             uniform = uniforms[ j ][ 0 ];
42374
42375             type = uniform.type;
42376             value = uniform.value;
42377
42378             if ( type === "i" ) { // single integer
42379
42380                 _gl.uniform1i( location, value );
42381
42382             } else if ( type === "f" ) { // single float
42383
42384                 _gl.uniform1f( location, value );
42385
42386             } else if ( type === "v2" ) { // single THREE.Vector2
42387
42388                 _gl.uniform2f( location, value.x, value.y );
42389
42390             } else if ( type === "v3" ) { // single THREE.Vector3
42391
42392                 _gl.uniform3f( location, value.x, value.y, value.z );
42393
42394             } else if ( type === "v4" ) { // single THREE.Vector4
42395
42396                 _gl.uniform4f( location, value.x, value.y, value.z, value.w );
42397
42398             } else if ( type === "c" ) { // single THREE.Color
42399
42400                 _gl.uniform3f( location, value.r, value.g, value.b );
42401
42402             } else if ( type === "iv1" ) { // flat array of integers (JS or typed array)
42403
42404                 _gl.uniform1iv( location, value );
42405
42406             } else if ( type === "iv" ) { // flat array of integers with 3 x N size (JS or typed array)
42407
42408                 _gl.uniform3iv( location, value );
42409
42410             } else if ( type === "fv1" ) { // flat array of floats (JS or typed array)
42411
42412                 _gl.uniform1fv( location, value );
42413
42414             } else if ( type === "fv" ) { // flat array of floats with 3 x N size (JS or typed array)
42415
42416                 _gl.uniform3fv( location, value );
42417
42418             } else if ( type === "v2v" ) { // array of THREE.Vector2
42419
42420                 if ( uniform._array === undefined ) {
42421
42422                     uniform._array = new Float32Array( 2 * value.length );
42423
42424                 }
42425
42426                 for ( i = 0, il = value.length; i < il; i ++ ) {
42427
42428                     offset = i * 2;
42429
42430                     uniform._array[ offset ]      = value[ i ].x;
42431                     uniform._array[ offset + 1 ] = value[ i ].y;
42432
42433                 }
42434
42435                 _gl.uniform2fv( location, uniform._array );
42436
42437             } else if ( type === "v3v" ) { // array of THREE.Vector3
42438
42439                 if ( uniform._array === undefined ) {
42440
42441                     uniform._array = new Float32Array( 3 * value.length );
42442
42443                 }
42444
42445                 for ( i = 0, il = value.length; i < il; i ++ ) {
42446
42447                     offset = i * 3;
42448
42449                     uniform._array[ offset ]      = value[ i ].x;
42450                     uniform._array[ offset + 1 ] = value[ i ].y;
42451                     uniform._array[ offset + 2 ] = value[ i ].z;
42452
42453                 }
42454
42455                 _gl.uniform3fv( location, uniform._array );
42456
42457             } else if ( type === "v4v" ) { // array of THREE.Vector4
42458
42459                 if ( uniform._array === undefined ) {
42460
42461                     uniform._array = new Float32Array( 4 * value.length );
42462
42463                 }
42464
42465                 for ( i = 0, il = value.length; i < il; i ++ ) {
42466
42467                     offset = i * 4;
42468
42469                     uniform._array[ offset ]      = value[ i ].x;
42470                     uniform._array[ offset + 1 ] = value[ i ].y;
42471                     uniform._array[ offset + 2 ] = value[ i ].z;
42472                     uniform._array[ offset + 3 ] = value[ i ].w;
42473
42474                 }
42475
42476                 _gl.uniform4fv( location, uniform._array );
42477
42478             } else if ( type === "m4") { // single THREE.Matrix4
42479
42480                 if ( uniform._array === undefined ) {
42481
42482                     uniform._array = new Float32Array( 16 );
42483
42484                 }
42485
42486                 value.flattenToArray( uniform._array );
42487                 _gl.uniformMatrix4fv( location, false, uniform._array );
42488
42489             } else if ( type === "m4v" ) { // array of THREE.Matrix4
42490
42491                 if ( uniform._array === undefined ) {
42492
42493                     uniform._array = new Float32Array( 16 * value.length );
42494
42495                 }
42496
42497                 for ( i = 0, il = value.length; i < il; i ++ ) {
42498
42499                     value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
42500
42501                 }
42502
42503                 _gl.uniformMatrix4fv( location, false, uniform._array );
42504
42505             } else if ( type === "t" ) { // single THREE.Texture (2d or cube)
42506
42507                 texture = value;
42508                 textureUnit = getTextureUnit();
42509
42510                 _gl.uniform1i( location, textureUnit );
42511
42512                 if ( !texture ) continue;
42513
42514                 if ( texture.image instanceof Array && texture.image.length === 6 ) {
42515
42516                     setCubeTexture( texture, textureUnit );
42517
42518                 } else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
42519
42520                     setCubeTextureDynamic( texture, textureUnit );
42521
42522                 } else {
42523
42524                     _this.setTexture( texture, textureUnit );
42525
42526                 }
42527
42528             } else if ( type === "tv" ) { // array of THREE.Texture (2d)
42529
42530                 if ( uniform._array === undefined ) {
42531
42532                     uniform._array = [];
42533
42534                 }
42535
42536                 for( i = 0, il = uniform.value.length; i < il; i ++ ) {
42537
42538                     uniform._array[ i ] = getTextureUnit();
42539
42540                 }
42541
42542                 _gl.uniform1iv( location, uniform._array );
42543
42544                 for( i = 0, il = uniform.value.length; i < il; i ++ ) {
42545
42546                     texture = uniform.value[ i ];
42547                     textureUnit = uniform._array[ i ];
42548
42549                     if ( !texture ) continue;
42550
42551                     _this.setTexture( texture, textureUnit );
42552
42553                 }
42554
42555             }
42556
42557         }
42558
42559     };
42560
42561     function setupMatrices ( object, camera ) {
42562
42563         object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld );
42564
42565         object._normalMatrix.getInverse( object._modelViewMatrix );
42566         object._normalMatrix.transpose();
42567
42568     };
42569
42570     //
42571
42572     function setColorGamma( array, offset, color, intensitySq ) {
42573
42574         array[ offset ]     = color.r * color.r * intensitySq;
42575         array[ offset + 1 ] = color.g * color.g * intensitySq;
42576         array[ offset + 2 ] = color.b * color.b * intensitySq;
42577
42578     };
42579
42580     function setColorLinear( array, offset, color, intensity ) {
42581
42582         array[ offset ]     = color.r * intensity;
42583         array[ offset + 1 ] = color.g * intensity;
42584         array[ offset + 2 ] = color.b * intensity;
42585
42586     };
42587
42588     function setupLights ( program, lights ) {
42589
42590         var l, ll, light, n,
42591         r = 0, g = 0, b = 0,
42592         color, skyColor, groundColor,
42593         intensity,  intensitySq,
42594         position,
42595         distance,
42596
42597         zlights = _lights,
42598
42599         dirColors = zlights.directional.colors,
42600         dirPositions = zlights.directional.positions,
42601
42602         pointColors = zlights.point.colors,
42603         pointPositions = zlights.point.positions,
42604         pointDistances = zlights.point.distances,
42605
42606         spotColors = zlights.spot.colors,
42607         spotPositions = zlights.spot.positions,
42608         spotDistances = zlights.spot.distances,
42609         spotDirections = zlights.spot.directions,
42610         spotAngles = zlights.spot.angles,
42611         spotExponents = zlights.spot.exponents,
42612
42613         hemiSkyColors = zlights.hemi.skyColors,
42614         hemiGroundColors = zlights.hemi.groundColors,
42615         hemiPositions = zlights.hemi.positions,
42616
42617         dirLength = 0,
42618         pointLength = 0,
42619         spotLength = 0,
42620         hemiLength = 0,
42621
42622         dirOffset = 0,
42623         pointOffset = 0,
42624         spotOffset = 0,
42625         hemiOffset = 0;
42626
42627         for ( l = 0, ll = lights.length; l < ll; l ++ ) {
42628
42629             light = lights[ l ];
42630
42631             if ( light.onlyShadow || ! light.visible ) continue;
42632
42633             color = light.color;
42634             intensity = light.intensity;
42635             distance = light.distance;
42636
42637             if ( light instanceof THREE.AmbientLight ) {
42638
42639                 if ( _this.gammaInput ) {
42640
42641                     r += color.r * color.r;
42642                     g += color.g * color.g;
42643                     b += color.b * color.b;
42644
42645                 } else {
42646
42647                     r += color.r;
42648                     g += color.g;
42649                     b += color.b;
42650
42651                 }
42652
42653             } else if ( light instanceof THREE.DirectionalLight ) {
42654
42655                 dirOffset = dirLength * 3;
42656
42657                 if ( _this.gammaInput ) {
42658
42659                     setColorGamma( dirColors, dirOffset, color, intensity * intensity );
42660
42661                 } else {
42662
42663                     setColorLinear( dirColors, dirOffset, color, intensity );
42664
42665                 }
42666
42667                 _direction.copy( light.matrixWorld.getPosition() );
42668                 _direction.subSelf( light.target.matrixWorld.getPosition() );
42669                 _direction.normalize();
42670
42671                 dirPositions[ dirOffset ]     = _direction.x;
42672                 dirPositions[ dirOffset + 1 ] = _direction.y;
42673                 dirPositions[ dirOffset + 2 ] = _direction.z;
42674
42675                 dirLength += 1;
42676
42677             } else if( light instanceof THREE.PointLight ) {
42678
42679                 pointOffset = pointLength * 3;
42680
42681                 if ( _this.gammaInput ) {
42682
42683                     setColorGamma( pointColors, pointOffset, color, intensity * intensity );
42684
42685                 } else {
42686
42687                     setColorLinear( pointColors, pointOffset, color, intensity );
42688
42689                 }
42690
42691                 position = light.matrixWorld.getPosition();
42692
42693                 pointPositions[ pointOffset ]     = position.x;
42694                 pointPositions[ pointOffset + 1 ] = position.y;
42695                 pointPositions[ pointOffset + 2 ] = position.z;
42696
42697                 pointDistances[ pointLength ] = distance;
42698
42699                 pointLength += 1;
42700
42701             } else if( light instanceof THREE.SpotLight ) {
42702
42703                 spotOffset = spotLength * 3;
42704
42705                 if ( _this.gammaInput ) {
42706
42707                     setColorGamma( spotColors, spotOffset, color, intensity * intensity );
42708
42709                 } else {
42710
42711                     setColorLinear( spotColors, spotOffset, color, intensity );
42712
42713                 }
42714
42715                 position = light.matrixWorld.getPosition();
42716
42717                 spotPositions[ spotOffset ]     = position.x;
42718                 spotPositions[ spotOffset + 1 ] = position.y;
42719                 spotPositions[ spotOffset + 2 ] = position.z;
42720
42721                 spotDistances[ spotLength ] = distance;
42722
42723                 _direction.copy( position );
42724                 _direction.subSelf( light.target.matrixWorld.getPosition() );
42725                 _direction.normalize();
42726
42727                 spotDirections[ spotOffset ]     = _direction.x;
42728                 spotDirections[ spotOffset + 1 ] = _direction.y;
42729                 spotDirections[ spotOffset + 2 ] = _direction.z;
42730
42731                 spotAngles[ spotLength ] = Math.cos( light.angle );
42732                 spotExponents[ spotLength ] = light.exponent;
42733
42734                 spotLength += 1;
42735
42736             } else if ( light instanceof THREE.HemisphereLight ) {
42737
42738                 skyColor = light.color;
42739                 groundColor = light.groundColor;
42740
42741                 hemiOffset = hemiLength * 3;
42742
42743                 if ( _this.gammaInput ) {
42744
42745                     intensitySq = intensity * intensity;
42746
42747                     setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensitySq );
42748                     setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensitySq );
42749
42750                 } else {
42751
42752                     setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
42753                     setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );
42754
42755                 }
42756
42757                 position = light.matrixWorld.getPosition();
42758
42759                 hemiPositions[ hemiOffset ]     = position.x;
42760                 hemiPositions[ hemiOffset + 1 ] = position.y;
42761                 hemiPositions[ hemiOffset + 2 ] = position.z;
42762
42763                 hemiLength += 1;
42764
42765             }
42766
42767         }
42768
42769         // null eventual remains from removed lights
42770         // (this is to avoid if in shader)
42771
42772         for ( l = dirLength * 3, ll = dirColors.length; l < ll; l ++ ) dirColors[ l ] = 0.0;
42773         for ( l = pointLength * 3, ll = pointColors.length; l < ll; l ++ ) pointColors[ l ] = 0.0;
42774         for ( l = spotLength * 3, ll = spotColors.length; l < ll; l ++ ) spotColors[ l ] = 0.0;
42775         for ( l = hemiLength * 3, ll = hemiSkyColors.length; l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
42776         for ( l = hemiLength * 3, ll = hemiGroundColors.length; l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;
42777
42778         zlights.directional.length = dirLength;
42779         zlights.point.length = pointLength;
42780         zlights.spot.length = spotLength;
42781         zlights.hemi.length = hemiLength;
42782
42783         zlights.ambient[ 0 ] = r;
42784         zlights.ambient[ 1 ] = g;
42785         zlights.ambient[ 2 ] = b;
42786
42787     };
42788
42789     // GL state setting
42790
42791     this.setFaceCulling = function ( cullFace, frontFace ) {
42792
42793         if ( cullFace ) {
42794
42795             if ( !frontFace || frontFace === "ccw" ) {
42796
42797                 _gl.frontFace( _gl.CCW );
42798
42799             } else {
42800
42801                 _gl.frontFace( _gl.CW );
42802
42803             }
42804
42805             if( cullFace === "back" ) {
42806
42807                 _gl.cullFace( _gl.BACK );
42808
42809             } else if( cullFace === "front" ) {
42810
42811                 _gl.cullFace( _gl.FRONT );
42812
42813             } else {
42814
42815                 _gl.cullFace( _gl.FRONT_AND_BACK );
42816
42817             }
42818
42819             _gl.enable( _gl.CULL_FACE );
42820
42821         } else {
42822
42823             _gl.disable( _gl.CULL_FACE );
42824
42825         }
42826
42827     };
42828
42829     this.setMaterialFaces = function ( material ) {
42830
42831         var doubleSided = material.side === THREE.DoubleSide;
42832         var flipSided = material.side === THREE.BackSide;
42833
42834         if ( _oldDoubleSided !== doubleSided ) {
42835
42836             if ( doubleSided ) {
42837
42838                 _gl.disable( _gl.CULL_FACE );
42839
42840             } else {
42841
42842                 _gl.enable( _gl.CULL_FACE );
42843
42844             }
42845
42846             _oldDoubleSided = doubleSided;
42847
42848         }
42849
42850         if ( _oldFlipSided !== flipSided ) {
42851
42852             if ( flipSided ) {
42853
42854                 _gl.frontFace( _gl.CW );
42855
42856             } else {
42857
42858                 _gl.frontFace( _gl.CCW );
42859
42860             }
42861
42862             _oldFlipSided = flipSided;
42863
42864         }
42865
42866     };
42867
42868     this.setDepthTest = function ( depthTest ) {
42869
42870         if ( _oldDepthTest !== depthTest ) {
42871
42872             if ( depthTest ) {
42873
42874                 _gl.enable( _gl.DEPTH_TEST );
42875
42876             } else {
42877
42878                 _gl.disable( _gl.DEPTH_TEST );
42879
42880             }
42881
42882             _oldDepthTest = depthTest;
42883
42884         }
42885
42886     };
42887
42888     this.setDepthWrite = function ( depthWrite ) {
42889
42890         if ( _oldDepthWrite !== depthWrite ) {
42891
42892             _gl.depthMask( depthWrite );
42893             _oldDepthWrite = depthWrite;
42894
42895         }
42896
42897     };
42898
42899     function setLineWidth ( width ) {
42900
42901         if ( width !== _oldLineWidth ) {
42902
42903             _gl.lineWidth( width );
42904
42905             _oldLineWidth = width;
42906
42907         }
42908
42909     };
42910
42911     function setPolygonOffset ( polygonoffset, factor, units ) {
42912
42913         if ( _oldPolygonOffset !== polygonoffset ) {
42914
42915             if ( polygonoffset ) {
42916
42917                 _gl.enable( _gl.POLYGON_OFFSET_FILL );
42918
42919             } else {
42920
42921                 _gl.disable( _gl.POLYGON_OFFSET_FILL );
42922
42923             }
42924
42925             _oldPolygonOffset = polygonoffset;
42926
42927         }
42928
42929         if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
42930
42931             _gl.polygonOffset( factor, units );
42932
42933             _oldPolygonOffsetFactor = factor;
42934             _oldPolygonOffsetUnits = units;
42935
42936         }
42937
42938     };
42939
42940     this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
42941
42942         if ( blending !== _oldBlending ) {
42943
42944             if ( blending === THREE.NoBlending ) {
42945
42946                 _gl.disable( _gl.BLEND );
42947
42948             } else if ( blending === THREE.AdditiveBlending ) {
42949
42950                 _gl.enable( _gl.BLEND );
42951                 _gl.blendEquation( _gl.FUNC_ADD );
42952                 _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
42953
42954             } else if ( blending === THREE.SubtractiveBlending ) {
42955
42956                 // TODO: Find blendFuncSeparate() combination
42957                 _gl.enable( _gl.BLEND );
42958                 _gl.blendEquation( _gl.FUNC_ADD );
42959                 _gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
42960
42961             } else if ( blending === THREE.MultiplyBlending ) {
42962
42963                 // TODO: Find blendFuncSeparate() combination
42964                 _gl.enable( _gl.BLEND );
42965                 _gl.blendEquation( _gl.FUNC_ADD );
42966                 _gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
42967
42968             } else if ( blending === THREE.CustomBlending ) {
42969
42970                 _gl.enable( _gl.BLEND );
42971
42972             } else {
42973
42974                 _gl.enable( _gl.BLEND );
42975                 _gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD );
42976                 _gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
42977
42978             }
42979
42980             _oldBlending = blending;
42981
42982         }
42983
42984         if ( blending === THREE.CustomBlending ) {
42985
42986             if ( blendEquation !== _oldBlendEquation ) {
42987
42988                 _gl.blendEquation( paramThreeToGL( blendEquation ) );
42989
42990                 _oldBlendEquation = blendEquation;
42991
42992             }
42993
42994             if ( blendSrc !== _oldBlendSrc || blendDst !== _oldBlendDst ) {
42995
42996                 _gl.blendFunc( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ) );
42997
42998                 _oldBlendSrc = blendSrc;
42999                 _oldBlendDst = blendDst;
43000
43001             }
43002
43003         } else {
43004
43005             _oldBlendEquation = null;
43006             _oldBlendSrc = null;
43007             _oldBlendDst = null;
43008
43009         }
43010
43011     };
43012
43013     // Shaders
43014
43015     function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
43016
43017         var p, pl, program, code;
43018         var chunks = [];
43019
43020         // Generate code
43021
43022         if ( shaderID ) {
43023
43024             chunks.push( shaderID );
43025
43026         } else {
43027
43028             chunks.push( fragmentShader );
43029             chunks.push( vertexShader );
43030
43031         }
43032
43033         for ( p in parameters ) {
43034
43035             chunks.push( p );
43036             chunks.push( parameters[ p ] );
43037
43038         }
43039
43040         code = chunks.join();
43041
43042         // Check if code has been already compiled
43043
43044         for ( p = 0, pl = _programs.length; p < pl; p ++ ) {
43045
43046             var programInfo = _programs[ p ];
43047
43048             if ( programInfo.code === code ) {
43049
43050                 // console.log( "Code already compiled." /*: \n\n" + code*/ );
43051
43052                 programInfo.usedTimes ++;
43053
43054                 return programInfo.program;
43055
43056             }
43057
43058         }
43059
43060         //console.log( "building new program " );
43061
43062         //
43063
43064         program = _gl.createProgram();
43065
43066         var prefix_vertex = [
43067
43068             "precision " + _precision + " float;",
43069
43070             _supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
43071
43072             _this.gammaInput ? "#define GAMMA_INPUT" : "",
43073             _this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
43074             _this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",
43075
43076             "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
43077             "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
43078             "#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
43079             "#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
43080
43081             "#define MAX_SHADOWS " + parameters.maxShadows,
43082
43083             "#define MAX_BONES " + parameters.maxBones,
43084
43085             parameters.map ? "#define USE_MAP" : "",
43086             parameters.envMap ? "#define USE_ENVMAP" : "",
43087             parameters.lightMap ? "#define USE_LIGHTMAP" : "",
43088             parameters.bumpMap ? "#define USE_BUMPMAP" : "",
43089             parameters.normalMap ? "#define USE_NORMALMAP" : "",
43090             parameters.specularMap ? "#define USE_SPECULARMAP" : "",
43091             parameters.vertexColors ? "#define USE_COLOR" : "",
43092
43093             parameters.skinning ? "#define USE_SKINNING" : "",
43094             parameters.useVertexTexture ? "#define BONE_TEXTURE" : "",
43095             parameters.boneTextureWidth ? "#define N_BONE_PIXEL_X " + parameters.boneTextureWidth.toFixed( 1 ) : "",
43096             parameters.boneTextureHeight ? "#define N_BONE_PIXEL_Y " + parameters.boneTextureHeight.toFixed( 1 ) : "",
43097
43098             parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
43099             parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
43100             parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
43101             parameters.wrapAround ? "#define WRAP_AROUND" : "",
43102             parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
43103             parameters.flipSided ? "#define FLIP_SIDED" : "",
43104
43105             parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
43106             parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
43107             parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
43108             parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
43109
43110             parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",
43111
43112             "uniform mat4 modelMatrix;",
43113             "uniform mat4 modelViewMatrix;",
43114             "uniform mat4 projectionMatrix;",
43115             "uniform mat4 viewMatrix;",
43116             "uniform mat3 normalMatrix;",
43117             "uniform vec3 cameraPosition;",
43118
43119             "attribute vec3 position;",
43120             "attribute vec3 normal;",
43121             "attribute vec2 uv;",
43122             "attribute vec2 uv2;",
43123
43124             "#ifdef USE_COLOR",
43125
43126                 "attribute vec3 color;",
43127
43128             "#endif",
43129
43130             "#ifdef USE_MORPHTARGETS",
43131
43132                 "attribute vec3 morphTarget0;",
43133                 "attribute vec3 morphTarget1;",
43134                 "attribute vec3 morphTarget2;",
43135                 "attribute vec3 morphTarget3;",
43136
43137                 "#ifdef USE_MORPHNORMALS",
43138
43139                     "attribute vec3 morphNormal0;",
43140                     "attribute vec3 morphNormal1;",
43141                     "attribute vec3 morphNormal2;",
43142                     "attribute vec3 morphNormal3;",
43143
43144                 "#else",
43145
43146                     "attribute vec3 morphTarget4;",
43147                     "attribute vec3 morphTarget5;",
43148                     "attribute vec3 morphTarget6;",
43149                     "attribute vec3 morphTarget7;",
43150
43151                 "#endif",
43152
43153             "#endif",
43154
43155             "#ifdef USE_SKINNING",
43156
43157                 "attribute vec4 skinIndex;",
43158                 "attribute vec4 skinWeight;",
43159
43160             "#endif",
43161
43162             ""
43163
43164         ].join("\n");
43165
43166         var prefix_fragment = [
43167
43168             "precision " + _precision + " float;",
43169
43170             ( parameters.bumpMap || parameters.normalMap ) ? "#extension GL_OES_standard_derivatives : enable" : "",
43171
43172             "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
43173             "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
43174             "#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
43175             "#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
43176
43177             "#define MAX_SHADOWS " + parameters.maxShadows,
43178
43179             parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",
43180
43181             _this.gammaInput ? "#define GAMMA_INPUT" : "",
43182             _this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
43183             _this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",
43184
43185             ( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
43186             ( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
43187
43188             parameters.map ? "#define USE_MAP" : "",
43189             parameters.envMap ? "#define USE_ENVMAP" : "",
43190             parameters.lightMap ? "#define USE_LIGHTMAP" : "",
43191             parameters.bumpMap ? "#define USE_BUMPMAP" : "",
43192             parameters.normalMap ? "#define USE_NORMALMAP" : "",
43193             parameters.specularMap ? "#define USE_SPECULARMAP" : "",
43194             parameters.vertexColors ? "#define USE_COLOR" : "",
43195
43196             parameters.metal ? "#define METAL" : "",
43197             parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
43198             parameters.wrapAround ? "#define WRAP_AROUND" : "",
43199             parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
43200             parameters.flipSided ? "#define FLIP_SIDED" : "",
43201
43202             parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
43203             parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
43204             parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
43205             parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
43206
43207             "uniform mat4 viewMatrix;",
43208             "uniform vec3 cameraPosition;",
43209             ""
43210
43211         ].join("\n");
43212
43213         var glFragmentShader = getShader( "fragment", prefix_fragment + fragmentShader );
43214         var glVertexShader = getShader( "vertex", prefix_vertex + vertexShader );
43215
43216         _gl.attachShader( program, glVertexShader );
43217         _gl.attachShader( program, glFragmentShader );
43218
43219         _gl.linkProgram( program );
43220
43221         if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
43222
43223             console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
43224
43225         }
43226
43227         // clean up
43228
43229         _gl.deleteShader( glFragmentShader );
43230         _gl.deleteShader( glVertexShader );
43231
43232         //console.log( prefix_fragment + fragmentShader );
43233         //console.log( prefix_vertex + vertexShader );
43234
43235         program.uniforms = {};
43236         program.attributes = {};
43237
43238         var identifiers, u, a, i;
43239
43240         // cache uniform locations
43241
43242         identifiers = [
43243
43244             'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'modelMatrix', 'cameraPosition',
43245             'morphTargetInfluences'
43246
43247         ];
43248
43249         if ( parameters.useVertexTexture ) {
43250
43251             identifiers.push( 'boneTexture' );
43252
43253         } else {
43254
43255             identifiers.push( 'boneGlobalMatrices' );
43256
43257         }
43258
43259         for ( u in uniforms ) {
43260
43261             identifiers.push( u );
43262
43263         }
43264
43265         cacheUniformLocations( program, identifiers );
43266
43267         // cache attributes locations
43268
43269         identifiers = [
43270
43271             "position", "normal", "uv", "uv2", "tangent", "color",
43272             "skinIndex", "skinWeight"
43273
43274         ];
43275
43276         for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
43277
43278             identifiers.push( "morphTarget" + i );
43279
43280         }
43281
43282         for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {
43283
43284             identifiers.push( "morphNormal" + i );
43285
43286         }
43287
43288         for ( a in attributes ) {
43289
43290             identifiers.push( a );
43291
43292         }
43293
43294         cacheAttributeLocations( program, identifiers );
43295
43296         program.id = _programs_counter ++;
43297
43298         _programs.push( { program: program, code: code, usedTimes: 1 } );
43299
43300         _this.info.memory.programs = _programs.length;
43301
43302         return program;
43303
43304     };
43305
43306     // Shader parameters cache
43307
43308     function cacheUniformLocations ( program, identifiers ) {
43309
43310         var i, l, id;
43311
43312         for( i = 0, l = identifiers.length; i < l; i ++ ) {
43313
43314             id = identifiers[ i ];
43315             program.uniforms[ id ] = _gl.getUniformLocation( program, id );
43316
43317         }
43318
43319     };
43320
43321     function cacheAttributeLocations ( program, identifiers ) {
43322
43323         var i, l, id;
43324
43325         for( i = 0, l = identifiers.length; i < l; i ++ ) {
43326
43327             id = identifiers[ i ];
43328             program.attributes[ id ] = _gl.getAttribLocation( program, id );
43329
43330         }
43331
43332     };
43333
43334     function addLineNumbers ( string ) {
43335
43336         var chunks = string.split( "\n" );
43337
43338         for ( var i = 0, il = chunks.length; i < il; i ++ ) {
43339
43340             // Chrome reports shader errors on lines
43341             // starting counting from 1
43342
43343             chunks[ i ] = ( i + 1 ) + ": " + chunks[ i ];
43344
43345         }
43346
43347         return chunks.join( "\n" );
43348
43349     };
43350
43351     function getShader ( type, string ) {
43352
43353         var shader;
43354
43355         if ( type === "fragment" ) {
43356
43357             shader = _gl.createShader( _gl.FRAGMENT_SHADER );
43358
43359         } else if ( type === "vertex" ) {
43360
43361             shader = _gl.createShader( _gl.VERTEX_SHADER );
43362
43363         }
43364
43365         _gl.shaderSource( shader, string );
43366         _gl.compileShader( shader );
43367
43368         if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
43369
43370             console.error( _gl.getShaderInfoLog( shader ) );
43371             console.error( addLineNumbers( string ) );
43372             return null;
43373
43374         }
43375
43376         return shader;
43377
43378     };
43379
43380     // Textures
43381
43382
43383     function isPowerOfTwo ( value ) {
43384
43385         return ( value & ( value - 1 ) ) === 0;
43386
43387     };
43388
43389     function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
43390
43391         if ( isImagePowerOfTwo ) {
43392
43393             _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
43394             _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
43395
43396             _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
43397             _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
43398
43399         } else {
43400
43401             _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
43402             _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
43403
43404             _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
43405             _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
43406
43407         }
43408
43409         if ( _glExtensionTextureFilterAnisotropic && texture.type !== THREE.FloatType ) {
43410
43411             if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) {
43412
43413                 _gl.texParameterf( textureType, _glExtensionTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _maxAnisotropy ) );
43414                 texture.__oldAnisotropy = texture.anisotropy;
43415
43416             }
43417
43418         }
43419
43420     };
43421
43422     this.setTexture = function ( texture, slot ) {
43423
43424         if ( texture.needsUpdate ) {
43425
43426             if ( ! texture.__webglInit ) {
43427
43428                 texture.__webglInit = true;
43429                 texture.__webglTexture = _gl.createTexture();
43430
43431                 _this.info.memory.textures ++;
43432
43433             }
43434
43435             _gl.activeTexture( _gl.TEXTURE0 + slot );
43436             _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
43437
43438             _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
43439             _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
43440
43441             var image = texture.image,
43442             isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
43443             glFormat = paramThreeToGL( texture.format ),
43444             glType = paramThreeToGL( texture.type );
43445
43446             setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );
43447
43448             if ( texture instanceof THREE.CompressedTexture ) {
43449
43450                 var mipmap, mipmaps = texture.mipmaps;
43451
43452                 for( var i = 0, il = mipmaps.length; i < il; i ++ ) {
43453
43454                     mipmap = mipmaps[ i ];
43455                     _gl.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
43456
43457                 }
43458
43459             } else if ( texture instanceof THREE.DataTexture ) {
43460
43461                 _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
43462
43463             } else {
43464
43465                 _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
43466
43467             }
43468
43469             if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
43470
43471             texture.needsUpdate = false;
43472
43473             if ( texture.onUpdate ) texture.onUpdate();
43474
43475         } else {
43476
43477             _gl.activeTexture( _gl.TEXTURE0 + slot );
43478             _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
43479
43480         }
43481
43482     };
43483
43484     function clampToMaxSize ( image, maxSize ) {
43485
43486         if ( image.width <= maxSize && image.height <= maxSize ) {
43487
43488             return image;
43489
43490         }
43491
43492         // Warning: Scaling through the canvas will only work with images that use
43493         // premultiplied alpha.
43494
43495         var maxDimension = Math.max( image.width, image.height );
43496         var newWidth = Math.floor( image.width * maxSize / maxDimension );
43497         var newHeight = Math.floor( image.height * maxSize / maxDimension );
43498
43499         var canvas = document.createElement( 'canvas' );
43500         canvas.width = newWidth;
43501         canvas.height = newHeight;
43502
43503         var ctx = canvas.getContext( "2d" );
43504         ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );
43505
43506         return canvas;
43507
43508     }
43509
43510     function setCubeTexture ( texture, slot ) {
43511
43512         if ( texture.image.length === 6 ) {
43513
43514             if ( texture.needsUpdate ) {
43515
43516                 if ( ! texture.image.__webglTextureCube ) {
43517
43518                     texture.image.__webglTextureCube = _gl.createTexture();
43519
43520                 }
43521
43522                 _gl.activeTexture( _gl.TEXTURE0 + slot );
43523                 _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
43524
43525                 _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
43526
43527                 var isCompressed = texture instanceof THREE.CompressedTexture;
43528
43529                 var cubeImage = [];
43530
43531                 for ( var i = 0; i < 6; i ++ ) {
43532
43533                     if ( _this.autoScaleCubemaps && ! isCompressed ) {
43534
43535                         cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );
43536
43537                     } else {
43538
43539                         cubeImage[ i ] = texture.image[ i ];
43540
43541                     }
43542
43543                 }
43544
43545                 var image = cubeImage[ 0 ],
43546                 isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
43547                 glFormat = paramThreeToGL( texture.format ),
43548                 glType = paramThreeToGL( texture.type );
43549
43550                 setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );
43551
43552                 for ( var i = 0; i < 6; i ++ ) {
43553
43554                     if ( isCompressed ) {
43555
43556                         var mipmap, mipmaps = cubeImage[ i ].mipmaps;
43557
43558                         for( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
43559
43560                             mipmap = mipmaps[ j ];
43561                             _gl.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
43562
43563                         }
43564
43565                     } else {
43566
43567                         _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
43568
43569                     }
43570
43571                 }
43572
43573                 if ( texture.generateMipmaps && isImagePowerOfTwo ) {
43574
43575                     _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
43576
43577                 }
43578
43579                 texture.needsUpdate = false;
43580
43581                 if ( texture.onUpdate ) texture.onUpdate();
43582
43583             } else {
43584
43585                 _gl.activeTexture( _gl.TEXTURE0 + slot );
43586                 _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
43587
43588             }
43589
43590         }
43591
43592     };
43593
43594     function setCubeTextureDynamic ( texture, slot ) {
43595
43596         _gl.activeTexture( _gl.TEXTURE0 + slot );
43597         _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
43598
43599     };
43600
43601     // Render targets
43602
43603     function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
43604
43605         _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
43606         _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
43607
43608     };
43609
43610     function setupRenderBuffer ( renderbuffer, renderTarget  ) {
43611
43612         _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
43613
43614         if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
43615
43616             _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
43617             _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
43618
43619         /* For some reason this is not working. Defaulting to RGBA4.
43620         } else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
43621
43622             _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
43623             _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
43624         */
43625         } else if( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
43626
43627             _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
43628             _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
43629
43630         } else {
43631
43632             _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
43633
43634         }
43635
43636     };
43637
43638     this.setRenderTarget = function ( renderTarget ) {
43639
43640         var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
43641
43642         if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
43643
43644             if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
43645             if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
43646
43647             renderTarget.__webglTexture = _gl.createTexture();
43648
43649             // Setup texture, create render and frame buffers
43650
43651             var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
43652                 glFormat = paramThreeToGL( renderTarget.format ),
43653                 glType = paramThreeToGL( renderTarget.type );
43654
43655             if ( isCube ) {
43656
43657                 renderTarget.__webglFramebuffer = [];
43658                 renderTarget.__webglRenderbuffer = [];
43659
43660                 _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
43661                 setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
43662
43663                 for ( var i = 0; i < 6; i ++ ) {
43664
43665                     renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
43666                     renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
43667
43668                     _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
43669
43670                     setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
43671                     setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
43672
43673                 }
43674
43675                 if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
43676
43677             } else {
43678
43679                 renderTarget.__webglFramebuffer = _gl.createFramebuffer();
43680                 renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
43681
43682                 _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
43683                 setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
43684
43685                 _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
43686
43687                 setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
43688                 setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
43689
43690                 if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
43691
43692             }
43693
43694             // Release everything
43695
43696             if ( isCube ) {
43697
43698                 _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
43699
43700             } else {
43701
43702                 _gl.bindTexture( _gl.TEXTURE_2D, null );
43703
43704             }
43705
43706             _gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
43707             _gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
43708
43709         }
43710
43711         var framebuffer, width, height, vx, vy;
43712
43713         if ( renderTarget ) {
43714
43715             if ( isCube ) {
43716
43717                 framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
43718
43719             } else {
43720
43721                 framebuffer = renderTarget.__webglFramebuffer;
43722
43723             }
43724
43725             width = renderTarget.width;
43726             height = renderTarget.height;
43727
43728             vx = 0;
43729             vy = 0;
43730
43731         } else {
43732
43733             framebuffer = null;
43734
43735             width = _viewportWidth;
43736             height = _viewportHeight;
43737
43738             vx = _viewportX;
43739             vy = _viewportY;
43740
43741         }
43742
43743         if ( framebuffer !== _currentFramebuffer ) {
43744
43745             _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
43746             _gl.viewport( vx, vy, width, height );
43747
43748             _currentFramebuffer = framebuffer;
43749
43750         }
43751
43752         _currentWidth = width;
43753         _currentHeight = height;
43754
43755     };
43756
43757     function updateRenderTargetMipmap ( renderTarget ) {
43758
43759         if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
43760
43761             _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
43762             _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
43763             _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
43764
43765         } else {
43766
43767             _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
43768             _gl.generateMipmap( _gl.TEXTURE_2D );
43769             _gl.bindTexture( _gl.TEXTURE_2D, null );
43770
43771         }
43772
43773     };
43774
43775     // Fallback filters for non-power-of-2 textures
43776
43777     function filterFallback ( f ) {
43778
43779         if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {
43780
43781             return _gl.NEAREST;
43782
43783         }
43784
43785         return _gl.LINEAR;
43786
43787     };
43788
43789     // Map three.js constants to WebGL constants
43790
43791     function paramThreeToGL ( p ) {
43792
43793         if ( p === THREE.RepeatWrapping ) return _gl.REPEAT;
43794         if ( p === THREE.ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
43795         if ( p === THREE.MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
43796
43797         if ( p === THREE.NearestFilter ) return _gl.NEAREST;
43798         if ( p === THREE.NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
43799         if ( p === THREE.NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;
43800
43801         if ( p === THREE.LinearFilter ) return _gl.LINEAR;
43802         if ( p === THREE.LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
43803         if ( p === THREE.LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;
43804
43805         if ( p === THREE.UnsignedByteType ) return _gl.UNSIGNED_BYTE;
43806         if ( p === THREE.UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
43807         if ( p === THREE.UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
43808         if ( p === THREE.UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;
43809
43810         if ( p === THREE.ByteType ) return _gl.BYTE;
43811         if ( p === THREE.ShortType ) return _gl.SHORT;
43812         if ( p === THREE.UnsignedShortType ) return _gl.UNSIGNED_SHORT;
43813         if ( p === THREE.IntType ) return _gl.INT;
43814         if ( p === THREE.UnsignedIntType ) return _gl.UNSIGNED_INT;
43815         if ( p === THREE.FloatType ) return _gl.FLOAT;
43816
43817         if ( p === THREE.AlphaFormat ) return _gl.ALPHA;
43818         if ( p === THREE.RGBFormat ) return _gl.RGB;
43819         if ( p === THREE.RGBAFormat ) return _gl.RGBA;
43820         if ( p === THREE.LuminanceFormat ) return _gl.LUMINANCE;
43821         if ( p === THREE.LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;
43822
43823         if ( p === THREE.AddEquation ) return _gl.FUNC_ADD;
43824         if ( p === THREE.SubtractEquation ) return _gl.FUNC_SUBTRACT;
43825         if ( p === THREE.ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;
43826
43827         if ( p === THREE.ZeroFactor ) return _gl.ZERO;
43828         if ( p === THREE.OneFactor ) return _gl.ONE;
43829         if ( p === THREE.SrcColorFactor ) return _gl.SRC_COLOR;
43830         if ( p === THREE.OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
43831         if ( p === THREE.SrcAlphaFactor ) return _gl.SRC_ALPHA;
43832         if ( p === THREE.OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
43833         if ( p === THREE.DstAlphaFactor ) return _gl.DST_ALPHA;
43834         if ( p === THREE.OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;
43835
43836         if ( p === THREE.DstColorFactor ) return _gl.DST_COLOR;
43837         if ( p === THREE.OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
43838         if ( p === THREE.SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;
43839
43840         if ( _glExtensionCompressedTextureS3TC !== undefined ) {
43841
43842             if ( p === THREE.RGB_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGB_S3TC_DXT1_EXT;
43843             if ( p === THREE.RGBA_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT1_EXT;
43844             if ( p === THREE.RGBA_S3TC_DXT3_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT3_EXT;
43845             if ( p === THREE.RGBA_S3TC_DXT5_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT5_EXT;
43846
43847         }
43848
43849         return 0;
43850
43851     };
43852
43853     // Allocations
43854
43855     function allocateBones ( object ) {
43856
43857         if ( _supportsBoneTextures && object && object.useVertexTexture ) {
43858
43859             return 1024;
43860
43861         } else {
43862
43863             // default for when object is not specified
43864             // ( for example when prebuilding shader
43865             //   to be used with multiple objects )
43866             //
43867             //     - leave some extra space for other uniforms
43868             //  - limit here is ANGLE's 254 max uniform vectors
43869             //    (up to 54 should be safe)
43870
43871             var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS );
43872             var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
43873
43874             var maxBones = nVertexMatrices;
43875
43876             if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
43877
43878                 maxBones = Math.min( object.bones.length, maxBones );
43879
43880                 if ( maxBones < object.bones.length ) {
43881
43882                     console.warn( "WebGLRenderer: too many bones - " + object.bones.length + ", this GPU supports just " + maxBones + " (try OpenGL instead of ANGLE)" );
43883
43884                 }
43885
43886             }
43887
43888             return maxBones;
43889
43890         }
43891
43892     };
43893
43894     function allocateLights ( lights ) {
43895
43896         var l, ll, light, dirLights, pointLights, spotLights, hemiLights, maxDirLights, maxPointLights, maxSpotLights, maxHemiLights;
43897
43898         dirLights = pointLights = spotLights = hemiLights = maxDirLights = maxPointLights = maxSpotLights = maxHemiLights = 0;
43899
43900         for ( l = 0, ll = lights.length; l < ll; l ++ ) {
43901
43902             light = lights[ l ];
43903
43904             if ( light.onlyShadow ) continue;
43905
43906             if ( light instanceof THREE.DirectionalLight ) dirLights ++;
43907             if ( light instanceof THREE.PointLight ) pointLights ++;
43908             if ( light instanceof THREE.SpotLight ) spotLights ++;
43909             if ( light instanceof THREE.HemisphereLight ) hemiLights ++;
43910
43911         }
43912
43913         if ( ( pointLights + spotLights + dirLights + hemiLights) <= _maxLights ) {
43914
43915             maxDirLights = dirLights;
43916             maxPointLights = pointLights;
43917             maxSpotLights = spotLights;
43918             maxHemiLights = hemiLights;
43919
43920         } else {
43921
43922             maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
43923             maxPointLights = _maxLights - maxDirLights;
43924
43925             // these are not really correct
43926
43927             maxSpotLights = maxPointLights;
43928             maxHemiLights = maxDirLights;
43929
43930         }
43931
43932         return { 'directional' : maxDirLights, 'point' : maxPointLights, 'spot': maxSpotLights, 'hemi': maxHemiLights };
43933
43934     };
43935
43936     function allocateShadows ( lights ) {
43937
43938         var l, ll, light, maxShadows = 0;
43939
43940         for ( l = 0, ll = lights.length; l < ll; l++ ) {
43941
43942             light = lights[ l ];
43943
43944             if ( ! light.castShadow ) continue;
43945
43946             if ( light instanceof THREE.SpotLight ) maxShadows ++;
43947             if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
43948
43949         }
43950
43951         return maxShadows;
43952
43953     };
43954
43955     // Initialization
43956
43957     function initGL () {
43958
43959         try {
43960
43961             if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
43962
43963                 throw 'Error creating WebGL context.';
43964
43965             }
43966
43967         } catch ( error ) {
43968
43969             console.error( error );
43970
43971         }
43972
43973         _glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' );
43974         _glExtensionStandardDerivatives = _gl.getExtension( 'OES_standard_derivatives' );
43975
43976         _glExtensionTextureFilterAnisotropic = _gl.getExtension( 'EXT_texture_filter_anisotropic' ) ||
43977                                                _gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) ||
43978                                                _gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
43979
43980
43981         _glExtensionCompressedTextureS3TC = _gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) ||
43982                                             _gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) ||
43983                                             _gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
43984
43985         if ( ! _glExtensionTextureFloat ) {
43986
43987             console.log( 'THREE.WebGLRenderer: Float textures not supported.' );
43988
43989         }
43990
43991         if ( ! _glExtensionStandardDerivatives ) {
43992
43993             console.log( 'THREE.WebGLRenderer: Standard derivatives not supported.' );
43994
43995         }
43996
43997         if ( ! _glExtensionTextureFilterAnisotropic ) {
43998
43999             console.log( 'THREE.WebGLRenderer: Anisotropic texture filtering not supported.' );
44000
44001         }
44002
44003         if ( ! _glExtensionCompressedTextureS3TC ) {
44004
44005             console.log( 'THREE.WebGLRenderer: S3TC compressed textures not supported.' );
44006
44007         }
44008
44009     };
44010
44011     function setDefaultGLState () {
44012
44013         _gl.clearColor( 0, 0, 0, 1 );
44014         _gl.clearDepth( 1 );
44015         _gl.clearStencil( 0 );
44016
44017         _gl.enable( _gl.DEPTH_TEST );
44018         _gl.depthFunc( _gl.LEQUAL );
44019
44020         _gl.frontFace( _gl.CCW );
44021         _gl.cullFace( _gl.BACK );
44022         _gl.enable( _gl.CULL_FACE );
44023
44024         _gl.enable( _gl.BLEND );
44025         _gl.blendEquation( _gl.FUNC_ADD );
44026         _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );
44027
44028         _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
44029
44030     };
44031
44032     // default plugins (order is important)
44033
44034     this.shadowMapPlugin = new THREE.ShadowMapPlugin();
44035     this.addPrePlugin( this.shadowMapPlugin );
44036
44037     this.addPostPlugin( new THREE.SpritePlugin() );
44038     this.addPostPlugin( new THREE.LensFlarePlugin() );
44039
44040 };
44041 /**
44042  * @author szimek / https://github.com/szimek/
44043  * @author alteredq / http://alteredqualia.com/
44044  */
44045
44046 THREE.WebGLRenderTarget = function ( width, height, options ) {
44047
44048     this.width = width;
44049     this.height = height;
44050
44051     options = options || {};
44052
44053     this.wrapS = options.wrapS !== undefined ? options.wrapS : THREE.ClampToEdgeWrapping;
44054     this.wrapT = options.wrapT !== undefined ? options.wrapT : THREE.ClampToEdgeWrapping;
44055
44056     this.magFilter = options.magFilter !== undefined ? options.magFilter : THREE.LinearFilter;
44057     this.minFilter = options.minFilter !== undefined ? options.minFilter : THREE.LinearMipMapLinearFilter;
44058
44059     this.anisotropy = options.anisotropy !== undefined ? options.anisotropy : 1;
44060
44061     this.offset = new THREE.Vector2( 0, 0 );
44062     this.repeat = new THREE.Vector2( 1, 1 );
44063
44064     this.format = options.format !== undefined ? options.format : THREE.RGBAFormat;
44065     this.type = options.type !== undefined ? options.type : THREE.UnsignedByteType;
44066
44067     this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
44068     this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
44069
44070     this.generateMipmaps = true;
44071
44072 };
44073
44074 THREE.WebGLRenderTarget.prototype.clone = function() {
44075
44076     var tmp = new THREE.WebGLRenderTarget( this.width, this.height );
44077
44078     tmp.wrapS = this.wrapS;
44079     tmp.wrapT = this.wrapT;
44080
44081     tmp.magFilter = this.magFilter;
44082     tmp.anisotropy = this.anisotropy;
44083
44084     tmp.minFilter = this.minFilter;
44085
44086     tmp.offset.copy( this.offset );
44087     tmp.repeat.copy( this.repeat );
44088
44089     tmp.format = this.format;
44090     tmp.type = this.type;
44091
44092     tmp.depthBuffer = this.depthBuffer;
44093     tmp.stencilBuffer = this.stencilBuffer;
44094
44095     tmp.generateMipmaps = this.generateMipmaps;
44096
44097     return tmp;
44098
44099 };
44100 /**
44101  * @author alteredq / http://alteredqualia.com
44102  */
44103
44104 THREE.WebGLRenderTargetCube = function ( width, height, options ) {
44105
44106     THREE.WebGLRenderTarget.call( this, width, height, options );
44107
44108     this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5
44109
44110 };
44111
44112 THREE.WebGLRenderTargetCube.prototype = Object.create( THREE.WebGLRenderTarget.prototype );
44113 /**
44114  * @author mrdoob / http://mrdoob.com/
44115  */
44116
44117 THREE.RenderableVertex = function () {
44118
44119     this.positionWorld = new THREE.Vector3();
44120     this.positionScreen = new THREE.Vector4();
44121
44122     this.visible = true;
44123
44124 };
44125
44126 THREE.RenderableVertex.prototype.copy = function ( vertex ) {
44127
44128     this.positionWorld.copy( vertex.positionWorld );
44129     this.positionScreen.copy( vertex.positionScreen );
44130
44131 }
44132 /**
44133  * @author mrdoob / http://mrdoob.com/
44134  */
44135
44136 THREE.RenderableFace3 = function () {
44137
44138     this.v1 = new THREE.RenderableVertex();
44139     this.v2 = new THREE.RenderableVertex();
44140     this.v3 = new THREE.RenderableVertex();
44141
44142     this.centroidWorld = new THREE.Vector3();
44143     this.centroidScreen = new THREE.Vector3();
44144
44145     this.normalWorld = new THREE.Vector3();
44146     this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
44147     this.vertexNormalsLength = 0;
44148
44149     this.material = null;
44150     this.uvs = [[]];
44151
44152     this.z = null;
44153
44154 };
44155 /**
44156  * @author mrdoob / http://mrdoob.com/
44157  */
44158
44159 THREE.RenderableFace4 = function () {
44160
44161     this.v1 = new THREE.RenderableVertex();
44162     this.v2 = new THREE.RenderableVertex();
44163     this.v3 = new THREE.RenderableVertex();
44164     this.v4 = new THREE.RenderableVertex();
44165
44166     this.centroidWorld = new THREE.Vector3();
44167     this.centroidScreen = new THREE.Vector3();
44168
44169     this.normalWorld = new THREE.Vector3();
44170     this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
44171     this.vertexNormalsLength = 0;
44172
44173     this.material = null;
44174     this.uvs = [[]];
44175
44176     this.z = null;
44177
44178 };
44179 /**
44180  * @author mrdoob / http://mrdoob.com/
44181  */
44182
44183 THREE.RenderableObject = function () {
44184
44185     this.object = null;
44186     this.z = null;
44187
44188 };
44189 /**
44190  * @author mrdoob / http://mrdoob.com/
44191  */
44192
44193 THREE.RenderableParticle = function () {
44194
44195     this.object = null;
44196
44197     this.x = null;
44198     this.y = null;
44199     this.z = null;
44200
44201     this.rotation = null;
44202     this.scale = new THREE.Vector2();
44203
44204     this.material = null;
44205
44206 };
44207 /**
44208  * @author mrdoob / http://mrdoob.com/
44209  */
44210
44211 THREE.RenderableLine = function () {
44212
44213     this.z = null;
44214
44215     this.v1 = new THREE.RenderableVertex();
44216     this.v2 = new THREE.RenderableVertex();
44217
44218     this.material = null;
44219
44220 };
44221 /**
44222  * @author alteredq / http://alteredqualia.com/
44223  */
44224
44225 THREE.ColorUtils = {
44226
44227     adjustHSV : function ( color, h, s, v ) {
44228
44229         var hsv = THREE.ColorUtils.__hsv;
44230
44231         THREE.ColorUtils.rgbToHsv( color, hsv );
44232
44233         hsv.h = THREE.Math.clamp( hsv.h + h, 0, 1 );
44234         hsv.s = THREE.Math.clamp( hsv.s + s, 0, 1 );
44235         hsv.v = THREE.Math.clamp( hsv.v + v, 0, 1 );
44236
44237         color.setHSV( hsv.h, hsv.s, hsv.v );
44238
44239     },
44240
44241     // based on MochiKit implementation by Bob Ippolito
44242
44243     rgbToHsv : function ( color, hsv ) {
44244
44245         var r = color.r;
44246         var g = color.g;
44247         var b = color.b;
44248
44249         var max = Math.max( Math.max( r, g ), b );
44250         var min = Math.min( Math.min( r, g ), b );
44251
44252         var hue;
44253         var saturation;
44254         var value = max;
44255
44256         if ( min === max )    {
44257
44258             hue = 0;
44259             saturation = 0;
44260
44261         } else {
44262
44263             var delta = ( max - min );
44264             saturation = delta / max;
44265
44266             if ( r === max ) {
44267
44268                 hue = ( g - b ) / delta;
44269
44270             } else if ( g === max ) {
44271
44272                 hue = 2 + ( ( b - r ) / delta );
44273
44274             } else    {
44275
44276                 hue = 4 + ( ( r - g ) / delta );
44277             }
44278
44279             hue /= 6;
44280
44281             if ( hue < 0 ) {
44282
44283                 hue += 1;
44284
44285             }
44286
44287             if ( hue > 1 ) {
44288
44289                 hue -= 1;
44290
44291             }
44292
44293         }
44294
44295         if ( hsv === undefined ) {
44296
44297             hsv = { h: 0, s: 0, v: 0 };
44298
44299         }
44300
44301         hsv.h = hue;
44302         hsv.s = saturation;
44303         hsv.v = value;
44304
44305         return hsv;
44306
44307     }
44308
44309 };
44310
44311 THREE.ColorUtils.__hsv = { h: 0, s: 0, v: 0 };/**
44312  * @author mrdoob / http://mrdoob.com/
44313  * @author alteredq / http://alteredqualia.com/
44314  */
44315
44316 THREE.GeometryUtils = {
44317
44318     // Merge two geometries or geometry and geometry from object (using object's transform)
44319
44320     merge: function ( geometry1, object2 /* mesh | geometry */ ) {
44321
44322         var matrix, matrixRotation,
44323         vertexOffset = geometry1.vertices.length,
44324         uvPosition = geometry1.faceVertexUvs[ 0 ].length,
44325         geometry2 = object2 instanceof THREE.Mesh ? object2.geometry : object2,
44326         vertices1 = geometry1.vertices,
44327         vertices2 = geometry2.vertices,
44328         faces1 = geometry1.faces,
44329         faces2 = geometry2.faces,
44330         uvs1 = geometry1.faceVertexUvs[ 0 ],
44331         uvs2 = geometry2.faceVertexUvs[ 0 ];
44332
44333         var geo1MaterialsMap = {};
44334
44335         for ( var i = 0; i < geometry1.materials.length; i ++ ) {
44336
44337             var id = geometry1.materials[ i ].id;
44338
44339             geo1MaterialsMap[ id ] = i;
44340
44341         }
44342
44343         if ( object2 instanceof THREE.Mesh ) {
44344
44345             object2.matrixAutoUpdate && object2.updateMatrix();
44346
44347             matrix = object2.matrix;
44348             matrixRotation = new THREE.Matrix4();
44349             matrixRotation.extractRotation( matrix, object2.scale );
44350
44351         }
44352
44353         // vertices
44354
44355         for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
44356
44357             var vertex = vertices2[ i ];
44358
44359             var vertexCopy = vertex.clone();
44360
44361             if ( matrix ) matrix.multiplyVector3( vertexCopy );
44362
44363             vertices1.push( vertexCopy );
44364
44365         }
44366
44367         // faces
44368
44369         for ( i = 0, il = faces2.length; i < il; i ++ ) {
44370
44371             var face = faces2[ i ], faceCopy, normal, color,
44372             faceVertexNormals = face.vertexNormals,
44373             faceVertexColors = face.vertexColors;
44374
44375             if ( face instanceof THREE.Face3 ) {
44376
44377                 faceCopy = new THREE.Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
44378
44379             } else if ( face instanceof THREE.Face4 ) {
44380
44381                 faceCopy = new THREE.Face4( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset, face.d + vertexOffset );
44382
44383             }
44384
44385             faceCopy.normal.copy( face.normal );
44386
44387             if ( matrixRotation ) matrixRotation.multiplyVector3( faceCopy.normal );
44388
44389             for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
44390
44391                 normal = faceVertexNormals[ j ].clone();
44392
44393                 if ( matrixRotation ) matrixRotation.multiplyVector3( normal );
44394
44395                 faceCopy.vertexNormals.push( normal );
44396
44397             }
44398
44399             faceCopy.color.copy( face.color );
44400
44401             for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
44402
44403                 color = faceVertexColors[ j ];
44404                 faceCopy.vertexColors.push( color.clone() );
44405
44406             }
44407
44408             if ( face.materialIndex !== undefined ) {
44409
44410                 var material2 = geometry2.materials[ face.materialIndex ];
44411                 var materialId2 = material2.id;
44412
44413                 var materialIndex = geo1MaterialsMap[ materialId2 ];
44414
44415                 if ( materialIndex === undefined ) {
44416
44417                     materialIndex = geometry1.materials.length;
44418                     geo1MaterialsMap[ materialId2 ] = materialIndex;
44419
44420                     geometry1.materials.push( material2 );
44421
44422                 }
44423
44424                 faceCopy.materialIndex = materialIndex;
44425
44426             }
44427
44428             faceCopy.centroid.copy( face.centroid );
44429             if ( matrix ) matrix.multiplyVector3( faceCopy.centroid );
44430
44431             faces1.push( faceCopy );
44432
44433         }
44434
44435         // uvs
44436
44437         for ( i = 0, il = uvs2.length; i < il; i ++ ) {
44438
44439             var uv = uvs2[ i ], uvCopy = [];
44440
44441             for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
44442
44443                 uvCopy.push( new THREE.UV( uv[ j ].u, uv[ j ].v ) );
44444
44445             }
44446
44447             uvs1.push( uvCopy );
44448
44449         }
44450
44451     },
44452
44453     clone: function ( geometry ) {
44454
44455         var cloneGeo = new THREE.Geometry();
44456
44457         var i, il;
44458
44459         var vertices = geometry.vertices,
44460             faces = geometry.faces,
44461             uvs = geometry.faceVertexUvs[ 0 ];
44462
44463         // materials
44464
44465         if ( geometry.materials ) {
44466
44467             cloneGeo.materials = geometry.materials.slice();
44468
44469         }
44470
44471         // vertices
44472
44473         for ( i = 0, il = vertices.length; i < il; i ++ ) {
44474
44475             var vertex = vertices[ i ];
44476
44477             cloneGeo.vertices.push( vertex.clone() );
44478
44479         }
44480
44481         // faces
44482
44483         for ( i = 0, il = faces.length; i < il; i ++ ) {
44484
44485             var face = faces[ i ];
44486
44487             cloneGeo.faces.push( face.clone() );
44488
44489         }
44490
44491         // uvs
44492
44493         for ( i = 0, il = uvs.length; i < il; i ++ ) {
44494
44495             var uv = uvs[ i ], uvCopy = [];
44496
44497             for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
44498
44499                 uvCopy.push( new THREE.UV( uv[ j ].u, uv[ j ].v ) );
44500
44501             }
44502
44503             cloneGeo.faceVertexUvs[ 0 ].push( uvCopy );
44504
44505         }
44506
44507         return cloneGeo;
44508
44509     },
44510
44511     // Get random point in triangle (via barycentric coordinates)
44512     //     (uniform distribution)
44513     //     http://www.cgafaq.info/wiki/Random_Point_In_Triangle
44514
44515     randomPointInTriangle: function ( vectorA, vectorB, vectorC ) {
44516
44517         var a, b, c,
44518             point = new THREE.Vector3(),
44519             tmp = THREE.GeometryUtils.__v1;
44520
44521         a = THREE.GeometryUtils.random();
44522         b = THREE.GeometryUtils.random();
44523
44524         if ( ( a + b ) > 1 ) {
44525
44526             a = 1 - a;
44527             b = 1 - b;
44528
44529         }
44530
44531         c = 1 - a - b;
44532
44533         point.copy( vectorA );
44534         point.multiplyScalar( a );
44535
44536         tmp.copy( vectorB );
44537         tmp.multiplyScalar( b );
44538
44539         point.addSelf( tmp );
44540
44541         tmp.copy( vectorC );
44542         tmp.multiplyScalar( c );
44543
44544         point.addSelf( tmp );
44545
44546         return point;
44547
44548     },
44549
44550     // Get random point in face (triangle / quad)
44551     // (uniform distribution)
44552
44553     randomPointInFace: function ( face, geometry, useCachedAreas ) {
44554
44555         var vA, vB, vC, vD;
44556
44557         if ( face instanceof THREE.Face3 ) {
44558
44559             vA = geometry.vertices[ face.a ];
44560             vB = geometry.vertices[ face.b ];
44561             vC = geometry.vertices[ face.c ];
44562
44563             return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC );
44564
44565         } else if ( face instanceof THREE.Face4 ) {
44566
44567             vA = geometry.vertices[ face.a ];
44568             vB = geometry.vertices[ face.b ];
44569             vC = geometry.vertices[ face.c ];
44570             vD = geometry.vertices[ face.d ];
44571
44572             var area1, area2;
44573
44574             if ( useCachedAreas ) {
44575
44576                 if ( face._area1 && face._area2 ) {
44577
44578                     area1 = face._area1;
44579                     area2 = face._area2;
44580
44581                 } else {
44582
44583                     area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD );
44584                     area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
44585
44586                     face._area1 = area1;
44587                     face._area2 = area2;
44588
44589                 }
44590
44591             } else {
44592
44593                 area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD ),
44594                 area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
44595
44596             }
44597
44598             var r = THREE.GeometryUtils.random() * ( area1 + area2 );
44599
44600             if ( r < area1 ) {
44601
44602                 return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vD );
44603
44604             } else {
44605
44606                 return THREE.GeometryUtils.randomPointInTriangle( vB, vC, vD );
44607
44608             }
44609
44610         }
44611
44612     },
44613
44614     // Get uniformly distributed random points in mesh
44615     //     - create array with cumulative sums of face areas
44616     //  - pick random number from 0 to total area
44617     //  - find corresponding place in area array by binary search
44618     //    - get random point in face
44619
44620     randomPointsInGeometry: function ( geometry, n ) {
44621
44622         var face, i,
44623             faces = geometry.faces,
44624             vertices = geometry.vertices,
44625             il = faces.length,
44626             totalArea = 0,
44627             cumulativeAreas = [],
44628             vA, vB, vC, vD;
44629
44630         // precompute face areas
44631
44632         for ( i = 0; i < il; i ++ ) {
44633
44634             face = faces[ i ];
44635
44636             if ( face instanceof THREE.Face3 ) {
44637
44638                 vA = vertices[ face.a ];
44639                 vB = vertices[ face.b ];
44640                 vC = vertices[ face.c ];
44641
44642                 face._area = THREE.GeometryUtils.triangleArea( vA, vB, vC );
44643
44644             } else if ( face instanceof THREE.Face4 ) {
44645
44646                 vA = vertices[ face.a ];
44647                 vB = vertices[ face.b ];
44648                 vC = vertices[ face.c ];
44649                 vD = vertices[ face.d ];
44650
44651                 face._area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD );
44652                 face._area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
44653
44654                 face._area = face._area1 + face._area2;
44655
44656             }
44657
44658             totalArea += face._area;
44659
44660             cumulativeAreas[ i ] = totalArea;
44661
44662         }
44663
44664         // binary search cumulative areas array
44665
44666         function binarySearchIndices( value ) {
44667
44668             function binarySearch( start, end ) {
44669
44670                 // return closest larger index
44671                 // if exact number is not found
44672
44673                 if ( end < start )
44674                     return start;
44675
44676                 var mid = start + Math.floor( ( end - start ) / 2 );
44677
44678                 if ( cumulativeAreas[ mid ] > value ) {
44679
44680                     return binarySearch( start, mid - 1 );
44681
44682                 } else if ( cumulativeAreas[ mid ] < value ) {
44683
44684                     return binarySearch( mid + 1, end );
44685
44686                 } else {
44687
44688                     return mid;
44689
44690                 }
44691
44692             }
44693
44694             var result = binarySearch( 0, cumulativeAreas.length - 1 )
44695             return result;
44696
44697         }
44698
44699         // pick random face weighted by face area
44700
44701         var r, index,
44702             result = [];
44703
44704         var stats = {};
44705
44706         for ( i = 0; i < n; i ++ ) {
44707
44708             r = THREE.GeometryUtils.random() * totalArea;
44709
44710             index = binarySearchIndices( r );
44711
44712             result[ i ] = THREE.GeometryUtils.randomPointInFace( faces[ index ], geometry, true );
44713
44714             if ( ! stats[ index ] ) {
44715
44716                 stats[ index ] = 1;
44717
44718             } else {
44719
44720                 stats[ index ] += 1;
44721
44722             }
44723
44724         }
44725
44726         return result;
44727
44728     },
44729
44730     // Get triangle area (by Heron's formula)
44731     //     http://en.wikipedia.org/wiki/Heron%27s_formula
44732
44733     triangleArea: function ( vectorA, vectorB, vectorC ) {
44734
44735         var s, a, b, c,
44736             tmp = THREE.GeometryUtils.__v1;
44737
44738         tmp.sub( vectorA, vectorB );
44739         a = tmp.length();
44740
44741         tmp.sub( vectorA, vectorC );
44742         b = tmp.length();
44743
44744         tmp.sub( vectorB, vectorC );
44745         c = tmp.length();
44746
44747         s = 0.5 * ( a + b + c );
44748
44749         return Math.sqrt( s * ( s - a ) * ( s - b ) * ( s - c ) );
44750
44751     },
44752
44753     // Center geometry so that 0,0,0 is in center of bounding box
44754
44755     center: function ( geometry ) {
44756
44757         geometry.computeBoundingBox();
44758
44759         var bb = geometry.boundingBox;
44760
44761         var offset = new THREE.Vector3();
44762
44763         offset.add( bb.min, bb.max );
44764         offset.multiplyScalar( -0.5 );
44765
44766         geometry.applyMatrix( new THREE.Matrix4().makeTranslation( offset.x, offset.y, offset.z ) );
44767         geometry.computeBoundingBox();
44768
44769         return offset;
44770
44771     },
44772
44773     // Normalize UVs to be from <0,1>
44774     // (for now just the first set of UVs)
44775
44776     normalizeUVs: function ( geometry ) {
44777
44778         var uvSet = geometry.faceVertexUvs[ 0 ];
44779
44780         for ( var i = 0, il = uvSet.length; i < il; i ++ ) {
44781
44782             var uvs = uvSet[ i ];
44783
44784             for ( var j = 0, jl = uvs.length; j < jl; j ++ ) {
44785
44786                 // texture repeat
44787
44788                 if( uvs[ j ].u !== 1.0 ) uvs[ j ].u = uvs[ j ].u - Math.floor( uvs[ j ].u );
44789                 if( uvs[ j ].v !== 1.0 ) uvs[ j ].v = uvs[ j ].v - Math.floor( uvs[ j ].v );
44790
44791             }
44792
44793         }
44794
44795     },
44796
44797     triangulateQuads: function ( geometry ) {
44798
44799         var i, il, j, jl;
44800
44801         var faces = [];
44802         var faceUvs = [];
44803         var faceVertexUvs = [];
44804
44805         for ( i = 0, il = geometry.faceUvs.length; i < il; i ++ ) {
44806
44807             faceUvs[ i ] = [];
44808
44809         }
44810
44811         for ( i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
44812
44813             faceVertexUvs[ i ] = [];
44814
44815         }
44816
44817         for ( i = 0, il = geometry.faces.length; i < il; i ++ ) {
44818
44819             var face = geometry.faces[ i ];
44820
44821             if ( face instanceof THREE.Face4 ) {
44822
44823                 var a = face.a;
44824                 var b = face.b;
44825                 var c = face.c;
44826                 var d = face.d;
44827
44828                 var triA = new THREE.Face3();
44829                 var triB = new THREE.Face3();
44830
44831                 triA.color.copy( face.color );
44832                 triB.color.copy( face.color );
44833
44834                 triA.materialIndex = face.materialIndex;
44835                 triB.materialIndex = face.materialIndex;
44836
44837                 triA.a = a;
44838                 triA.b = b;
44839                 triA.c = d;
44840
44841                 triB.a = b;
44842                 triB.b = c;
44843                 triB.c = d;
44844
44845                 if ( face.vertexColors.length === 4 ) {
44846
44847                     triA.vertexColors[ 0 ] = face.vertexColors[ 0 ].clone();
44848                     triA.vertexColors[ 1 ] = face.vertexColors[ 1 ].clone();
44849                     triA.vertexColors[ 2 ] = face.vertexColors[ 3 ].clone();
44850
44851                     triB.vertexColors[ 0 ] = face.vertexColors[ 1 ].clone();
44852                     triB.vertexColors[ 1 ] = face.vertexColors[ 2 ].clone();
44853                     triB.vertexColors[ 2 ] = face.vertexColors[ 3 ].clone();
44854
44855                 }
44856
44857                 faces.push( triA, triB );
44858
44859                 for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
44860
44861                     if ( geometry.faceVertexUvs[ j ].length ) {
44862
44863                         var uvs = geometry.faceVertexUvs[ j ][ i ];
44864
44865                         var uvA = uvs[ 0 ];
44866                         var uvB = uvs[ 1 ];
44867                         var uvC = uvs[ 2 ];
44868                         var uvD = uvs[ 3 ];
44869
44870                         var uvsTriA = [ uvA.clone(), uvB.clone(), uvD.clone() ];
44871                         var uvsTriB = [ uvB.clone(), uvC.clone(), uvD.clone() ];
44872
44873                         faceVertexUvs[ j ].push( uvsTriA, uvsTriB );
44874
44875                     }
44876
44877                 }
44878
44879                 for ( j = 0, jl = geometry.faceUvs.length; j < jl; j ++ ) {
44880
44881                     if ( geometry.faceUvs[ j ].length ) {
44882
44883                         var faceUv = geometry.faceUvs[ j ][ i ];
44884
44885                         faceUvs[ j ].push( faceUv, faceUv );
44886
44887                     }
44888
44889                 }
44890
44891             } else {
44892
44893                 faces.push( face );
44894
44895                 for ( j = 0, jl = geometry.faceUvs.length; j < jl; j ++ ) {
44896
44897                     faceUvs[ j ].push( geometry.faceUvs[ j ][ i ] );
44898
44899                 }
44900
44901                 for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
44902
44903                     faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
44904
44905                 }
44906
44907             }
44908
44909         }
44910
44911         geometry.faces = faces;
44912         geometry.faceUvs = faceUvs;
44913         geometry.faceVertexUvs = faceVertexUvs;
44914
44915         geometry.computeCentroids();
44916         geometry.computeFaceNormals();
44917         geometry.computeVertexNormals();
44918
44919         if ( geometry.hasTangents ) geometry.computeTangents();
44920
44921     },
44922
44923     // Make all faces use unique vertices
44924     // so that each face can be separated from others
44925
44926     explode: function( geometry ) {
44927
44928         var vertices = [];
44929
44930         for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) {
44931
44932             var n = vertices.length;
44933
44934             var face = geometry.faces[ i ];
44935
44936             if ( face instanceof THREE.Face4 ) {
44937
44938                 var a = face.a;
44939                 var b = face.b;
44940                 var c = face.c;
44941                 var d = face.d;
44942
44943                 var va = geometry.vertices[ a ];
44944                 var vb = geometry.vertices[ b ];
44945                 var vc = geometry.vertices[ c ];
44946                 var vd = geometry.vertices[ d ];
44947
44948                 vertices.push( va.clone() );
44949                 vertices.push( vb.clone() );
44950                 vertices.push( vc.clone() );
44951                 vertices.push( vd.clone() );
44952
44953                 face.a = n;
44954                 face.b = n + 1;
44955                 face.c = n + 2;
44956                 face.d = n + 3;
44957
44958             } else {
44959
44960                 var a = face.a;
44961                 var b = face.b;
44962                 var c = face.c;
44963
44964                 var va = geometry.vertices[ a ];
44965                 var vb = geometry.vertices[ b ];
44966                 var vc = geometry.vertices[ c ];
44967
44968                 vertices.push( va.clone() );
44969                 vertices.push( vb.clone() );
44970                 vertices.push( vc.clone() );
44971
44972                 face.a = n;
44973                 face.b = n + 1;
44974                 face.c = n + 2;
44975
44976             }
44977
44978         }
44979
44980         geometry.vertices = vertices;
44981         delete geometry.__tmpVertices;
44982
44983     },
44984
44985     // Break faces with edges longer than maxEdgeLength
44986     // - not recursive
44987
44988     tessellate: function ( geometry, maxEdgeLength ) {
44989
44990         var i, il, face,
44991         a, b, c, d,
44992         va, vb, vc, vd,
44993         dab, dbc, dac, dcd, dad,
44994         m, m1, m2,
44995         vm, vm1, vm2,
44996         vnm, vnm1, vnm2,
44997         vcm, vcm1, vcm2,
44998         triA, triB,
44999         quadA, quadB,
45000         edge;
45001
45002         var faces = [];
45003         var faceVertexUvs = [];
45004
45005         for ( i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
45006
45007             faceVertexUvs[ i ] = [];
45008
45009         }
45010
45011         for ( i = 0, il = geometry.faces.length; i < il; i ++ ) {
45012
45013             face = geometry.faces[ i ];
45014
45015             if ( face instanceof THREE.Face3 ) {
45016
45017                 a = face.a;
45018                 b = face.b;
45019                 c = face.c;
45020
45021                 va = geometry.vertices[ a ];
45022                 vb = geometry.vertices[ b ];
45023                 vc = geometry.vertices[ c ];
45024
45025                 dab = va.distanceTo( vb );
45026                 dbc = vb.distanceTo( vc );
45027                 dac = va.distanceTo( vc );
45028
45029                 if ( dab > maxEdgeLength || dbc > maxEdgeLength || dac > maxEdgeLength ) {
45030
45031                     m = geometry.vertices.length;
45032
45033                     triA = face.clone();
45034                     triB = face.clone();
45035
45036                     if ( dab >= dbc && dab >= dac ) {
45037
45038                         vm = va.clone();
45039                         vm.lerpSelf( vb, 0.5 );
45040
45041                         triA.a = a;
45042                         triA.b = m;
45043                         triA.c = c;
45044
45045                         triB.a = m;
45046                         triB.b = b;
45047                         triB.c = c;
45048
45049                         if ( face.vertexNormals.length === 3 ) {
45050
45051                             vnm = face.vertexNormals[ 0 ].clone();
45052                             vnm.lerpSelf( face.vertexNormals[ 1 ], 0.5 );
45053
45054                             triA.vertexNormals[ 1 ].copy( vnm );
45055                             triB.vertexNormals[ 0 ].copy( vnm );
45056
45057                         }
45058
45059                         if ( face.vertexColors.length === 3 ) {
45060
45061                             vcm = face.vertexColors[ 0 ].clone();
45062                             vcm.lerpSelf( face.vertexColors[ 1 ], 0.5 );
45063
45064                             triA.vertexColors[ 1 ].copy( vcm );
45065                             triB.vertexColors[ 0 ].copy( vcm );
45066
45067                         }
45068
45069                         edge = 0;
45070
45071                     } else if ( dbc >= dab && dbc >= dac ) {
45072
45073                         vm = vb.clone();
45074                         vm.lerpSelf( vc, 0.5 );
45075
45076                         triA.a = a;
45077                         triA.b = b;
45078                         triA.c = m;
45079
45080                         triB.a = m;
45081                         triB.b = c;
45082                         triB.c = a;
45083
45084                         if ( face.vertexNormals.length === 3 ) {
45085
45086                             vnm = face.vertexNormals[ 1 ].clone();
45087                             vnm.lerpSelf( face.vertexNormals[ 2 ], 0.5 );
45088
45089                             triA.vertexNormals[ 2 ].copy( vnm );
45090
45091                             triB.vertexNormals[ 0 ].copy( vnm );
45092                             triB.vertexNormals[ 1 ].copy( face.vertexNormals[ 2 ] );
45093                             triB.vertexNormals[ 2 ].copy( face.vertexNormals[ 0 ] );
45094
45095                         }
45096
45097                         if ( face.vertexColors.length === 3 ) {
45098
45099                             vcm = face.vertexColors[ 1 ].clone();
45100                             vcm.lerpSelf( face.vertexColors[ 2 ], 0.5 );
45101
45102                             triA.vertexColors[ 2 ].copy( vcm );
45103
45104                             triB.vertexColors[ 0 ].copy( vcm );
45105                             triB.vertexColors[ 1 ].copy( face.vertexColors[ 2 ] );
45106                             triB.vertexColors[ 2 ].copy( face.vertexColors[ 0 ] );
45107
45108                         }
45109
45110                         edge = 1;
45111
45112                     } else {
45113
45114                         vm = va.clone();
45115                         vm.lerpSelf( vc, 0.5 );
45116
45117                         triA.a = a;
45118                         triA.b = b;
45119                         triA.c = m;
45120
45121                         triB.a = m;
45122                         triB.b = b;
45123                         triB.c = c;
45124
45125                         if ( face.vertexNormals.length === 3 ) {
45126
45127                             vnm = face.vertexNormals[ 0 ].clone();
45128                             vnm.lerpSelf( face.vertexNormals[ 2 ], 0.5 );
45129
45130                             triA.vertexNormals[ 2 ].copy( vnm );
45131                             triB.vertexNormals[ 0 ].copy( vnm );
45132
45133                         }
45134
45135                         if ( face.vertexColors.length === 3 ) {
45136
45137                             vcm = face.vertexColors[ 0 ].clone();
45138                             vcm.lerpSelf( face.vertexColors[ 2 ], 0.5 );
45139
45140                             triA.vertexColors[ 2 ].copy( vcm );
45141                             triB.vertexColors[ 0 ].copy( vcm );
45142
45143                         }
45144
45145                         edge = 2;
45146
45147                     }
45148
45149                     faces.push( triA, triB );
45150                     geometry.vertices.push( vm );
45151
45152                     var j, jl, uvs, uvA, uvB, uvC, uvM, uvsTriA, uvsTriB;
45153
45154                     for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
45155
45156                         if ( geometry.faceVertexUvs[ j ].length ) {
45157
45158                             uvs = geometry.faceVertexUvs[ j ][ i ];
45159
45160                             uvA = uvs[ 0 ];
45161                             uvB = uvs[ 1 ];
45162                             uvC = uvs[ 2 ];
45163
45164                             // AB
45165
45166                             if ( edge === 0 ) {
45167
45168                                 uvM = uvA.clone();
45169                                 uvM.lerpSelf( uvB, 0.5 );
45170
45171                                 uvsTriA = [ uvA.clone(), uvM.clone(), uvC.clone() ];
45172                                 uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ];
45173
45174                             // BC
45175
45176                             } else if ( edge === 1 ) {
45177
45178                                 uvM = uvB.clone();
45179                                 uvM.lerpSelf( uvC, 0.5 );
45180
45181                                 uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
45182                                 uvsTriB = [ uvM.clone(), uvC.clone(), uvA.clone() ];
45183
45184                             // AC
45185
45186                             } else {
45187
45188                                 uvM = uvA.clone();
45189                                 uvM.lerpSelf( uvC, 0.5 );
45190
45191                                 uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
45192                                 uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ];
45193
45194                             }
45195
45196                             faceVertexUvs[ j ].push( uvsTriA, uvsTriB );
45197
45198                         }
45199
45200                     }
45201
45202                 } else {
45203
45204                     faces.push( face );
45205
45206                     for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
45207
45208                         faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
45209
45210                     }
45211
45212                 }
45213
45214             } else {
45215
45216                 a = face.a;
45217                 b = face.b;
45218                 c = face.c;
45219                 d = face.d;
45220
45221                 va = geometry.vertices[ a ];
45222                 vb = geometry.vertices[ b ];
45223                 vc = geometry.vertices[ c ];
45224                 vd = geometry.vertices[ d ];
45225
45226                 dab = va.distanceTo( vb );
45227                 dbc = vb.distanceTo( vc );
45228                 dcd = vc.distanceTo( vd );
45229                 dad = va.distanceTo( vd );
45230
45231                 if ( dab > maxEdgeLength || dbc > maxEdgeLength || dcd > maxEdgeLength || dad > maxEdgeLength ) {
45232
45233                     m1 = geometry.vertices.length;
45234                     m2 = geometry.vertices.length + 1;
45235
45236                     quadA = face.clone();
45237                     quadB = face.clone();
45238
45239                     if ( ( dab >= dbc && dab >= dcd && dab >= dad ) || ( dcd >= dbc && dcd >= dab && dcd >= dad ) ) {
45240
45241                         vm1 = va.clone();
45242                         vm1.lerpSelf( vb, 0.5 );
45243
45244                         vm2 = vc.clone();
45245                         vm2.lerpSelf( vd, 0.5 );
45246
45247                         quadA.a = a;
45248                         quadA.b = m1;
45249                         quadA.c = m2;
45250                         quadA.d = d;
45251
45252                         quadB.a = m1;
45253                         quadB.b = b;
45254                         quadB.c = c;
45255                         quadB.d = m2;
45256
45257                         if ( face.vertexNormals.length === 4 ) {
45258
45259                             vnm1 = face.vertexNormals[ 0 ].clone();
45260                             vnm1.lerpSelf( face.vertexNormals[ 1 ], 0.5 );
45261
45262                             vnm2 = face.vertexNormals[ 2 ].clone();
45263                             vnm2.lerpSelf( face.vertexNormals[ 3 ], 0.5 );
45264
45265                             quadA.vertexNormals[ 1 ].copy( vnm1 );
45266                             quadA.vertexNormals[ 2 ].copy( vnm2 );
45267
45268                             quadB.vertexNormals[ 0 ].copy( vnm1 );
45269                             quadB.vertexNormals[ 3 ].copy( vnm2 );
45270
45271                         }
45272
45273                         if ( face.vertexColors.length === 4 ) {
45274
45275                             vcm1 = face.vertexColors[ 0 ].clone();
45276                             vcm1.lerpSelf( face.vertexColors[ 1 ], 0.5 );
45277
45278                             vcm2 = face.vertexColors[ 2 ].clone();
45279                             vcm2.lerpSelf( face.vertexColors[ 3 ], 0.5 );
45280
45281                             quadA.vertexColors[ 1 ].copy( vcm1 );
45282                             quadA.vertexColors[ 2 ].copy( vcm2 );
45283
45284                             quadB.vertexColors[ 0 ].copy( vcm1 );
45285                             quadB.vertexColors[ 3 ].copy( vcm2 );
45286
45287                         }
45288
45289                         edge = 0;
45290
45291                     } else {
45292
45293                         vm1 = vb.clone();
45294                         vm1.lerpSelf( vc, 0.5 );
45295
45296                         vm2 = vd.clone();
45297                         vm2.lerpSelf( va, 0.5 );
45298
45299                         quadA.a = a;
45300                         quadA.b = b;
45301                         quadA.c = m1;
45302                         quadA.d = m2;
45303
45304                         quadB.a = m2;
45305                         quadB.b = m1;
45306                         quadB.c = c;
45307                         quadB.d = d;
45308
45309                         if ( face.vertexNormals.length === 4 ) {
45310
45311                             vnm1 = face.vertexNormals[ 1 ].clone();
45312                             vnm1.lerpSelf( face.vertexNormals[ 2 ], 0.5 );
45313
45314                             vnm2 = face.vertexNormals[ 3 ].clone();
45315                             vnm2.lerpSelf( face.vertexNormals[ 0 ], 0.5 );
45316
45317                             quadA.vertexNormals[ 2 ].copy( vnm1 );
45318                             quadA.vertexNormals[ 3 ].copy( vnm2 );
45319
45320                             quadB.vertexNormals[ 0 ].copy( vnm2 );
45321                             quadB.vertexNormals[ 1 ].copy( vnm1 );
45322
45323                         }
45324
45325                         if ( face.vertexColors.length === 4 ) {
45326
45327                             vcm1 = face.vertexColors[ 1 ].clone();
45328                             vcm1.lerpSelf( face.vertexColors[ 2 ], 0.5 );
45329
45330                             vcm2 = face.vertexColors[ 3 ].clone();
45331                             vcm2.lerpSelf( face.vertexColors[ 0 ], 0.5 );
45332
45333                             quadA.vertexColors[ 2 ].copy( vcm1 );
45334                             quadA.vertexColors[ 3 ].copy( vcm2 );
45335
45336                             quadB.vertexColors[ 0 ].copy( vcm2 );
45337                             quadB.vertexColors[ 1 ].copy( vcm1 );
45338
45339                         }
45340
45341                         edge = 1;
45342
45343                     }
45344
45345                     faces.push( quadA, quadB );
45346                     geometry.vertices.push( vm1, vm2 );
45347
45348                     var j, jl, uvs, uvA, uvB, uvC, uvD, uvM1, uvM2, uvsQuadA, uvsQuadB;
45349
45350                     for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
45351
45352                         if ( geometry.faceVertexUvs[ j ].length ) {
45353
45354                             uvs = geometry.faceVertexUvs[ j ][ i ];
45355
45356                             uvA = uvs[ 0 ];
45357                             uvB = uvs[ 1 ];
45358                             uvC = uvs[ 2 ];
45359                             uvD = uvs[ 3 ];
45360
45361                             // AB + CD
45362
45363                             if ( edge === 0 ) {
45364
45365                                 uvM1 = uvA.clone();
45366                                 uvM1.lerpSelf( uvB, 0.5 );
45367
45368                                 uvM2 = uvC.clone();
45369                                 uvM2.lerpSelf( uvD, 0.5 );
45370
45371                                 uvsQuadA = [ uvA.clone(), uvM1.clone(), uvM2.clone(), uvD.clone() ];
45372                                 uvsQuadB = [ uvM1.clone(), uvB.clone(), uvC.clone(), uvM2.clone() ];
45373
45374                             // BC + AD
45375
45376                             } else {
45377
45378                                 uvM1 = uvB.clone();
45379                                 uvM1.lerpSelf( uvC, 0.5 );
45380
45381                                 uvM2 = uvD.clone();
45382                                 uvM2.lerpSelf( uvA, 0.5 );
45383
45384                                 uvsQuadA = [ uvA.clone(), uvB.clone(), uvM1.clone(), uvM2.clone() ];
45385                                 uvsQuadB = [ uvM2.clone(), uvM1.clone(), uvC.clone(), uvD.clone() ];
45386
45387                             }
45388
45389                             faceVertexUvs[ j ].push( uvsQuadA, uvsQuadB );
45390
45391                         }
45392
45393                     }
45394
45395                 } else {
45396
45397                     faces.push( face );
45398
45399                     for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
45400
45401                         faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
45402
45403                     }
45404
45405                 }
45406
45407             }
45408
45409         }
45410
45411         geometry.faces = faces;
45412         geometry.faceVertexUvs = faceVertexUvs;
45413
45414     }
45415
45416 };
45417
45418 THREE.GeometryUtils.random = THREE.Math.random16;
45419
45420 THREE.GeometryUtils.__v1 = new THREE.Vector3();
45421 /**
45422  * @author alteredq / http://alteredqualia.com/
45423  * @author mrdoob / http://mrdoob.com/
45424  */
45425
45426 THREE.ImageUtils = {
45427
45428     crossOrigin: 'anonymous',
45429
45430     loadTexture: function ( url, mapping, onLoad, onError ) {
45431
45432         var image = new Image();
45433         var texture = new THREE.Texture( image, mapping );
45434
45435         var loader = new THREE.ImageLoader();
45436
45437         loader.addEventListener( 'load', function ( event ) {
45438
45439             texture.image = event.content;
45440             texture.needsUpdate = true;
45441
45442             if ( onLoad ) onLoad( texture );
45443
45444         } );
45445
45446         loader.addEventListener( 'error', function ( event ) {
45447
45448             if ( onError ) onError( event.message );
45449
45450         } );
45451
45452         loader.crossOrigin = this.crossOrigin;
45453         loader.load( url, image );
45454
45455         return texture;
45456
45457     },
45458
45459     loadCompressedTexture: function ( url, mapping, onLoad, onError ) {
45460
45461         var texture = new THREE.CompressedTexture();
45462         texture.mapping = mapping;
45463
45464         var request = new XMLHttpRequest();
45465
45466         request.onload = function () {
45467
45468             var buffer = request.response;
45469             var dds = THREE.ImageUtils.parseDDS( buffer, true );
45470
45471             texture.format = dds.format;
45472
45473             texture.mipmaps = dds.mipmaps;
45474             texture.image.width = dds.width;
45475             texture.image.height = dds.height;
45476
45477             // gl.generateMipmap fails for compressed textures
45478             // mipmaps must be embedded in the DDS file
45479             // or texture filters must not use mipmapping
45480
45481             texture.generateMipmaps = false;
45482
45483             texture.needsUpdate = true;
45484
45485             if ( onLoad ) onLoad( texture );
45486
45487         }
45488
45489         request.onerror = onError;
45490
45491         request.open( 'GET', url, true );
45492         request.responseType = "arraybuffer";
45493         request.send( null );
45494
45495         return texture;
45496
45497     },
45498
45499     loadTextureCube: function ( array, mapping, onLoad, onError ) {
45500
45501         var images = [];
45502         images.loadCount = 0;
45503
45504         var texture = new THREE.Texture();
45505         texture.image = images;
45506         if ( mapping !== undefined ) texture.mapping = mapping;
45507
45508         // no flipping needed for cube textures
45509
45510         texture.flipY = false;
45511
45512         for ( var i = 0, il = array.length; i < il; ++ i ) {
45513
45514             var cubeImage = new Image();
45515             images[ i ] = cubeImage;
45516
45517             cubeImage.onload = function () {
45518
45519                 images.loadCount += 1;
45520
45521                 if ( images.loadCount === 6 ) {
45522
45523                     texture.needsUpdate = true;
45524                     if ( onLoad ) onLoad();
45525
45526                 }
45527
45528             };
45529
45530             cubeImage.onerror = onError;
45531
45532             cubeImage.crossOrigin = this.crossOrigin;
45533             cubeImage.src = array[ i ];
45534
45535         }
45536
45537         return texture;
45538
45539     },
45540
45541     loadCompressedTextureCube: function ( array, mapping, onLoad, onError ) {
45542
45543         var images = [];
45544         images.loadCount = 0;
45545
45546         var texture = new THREE.CompressedTexture();
45547         texture.image = images;
45548         if ( mapping !== undefined ) texture.mapping = mapping;
45549
45550         // no flipping for cube textures
45551         // (also flipping doesn't work for compressed textures )
45552
45553         texture.flipY = false;
45554
45555         // can't generate mipmaps for compressed textures
45556         // mips must be embedded in DDS files
45557
45558         texture.generateMipmaps = false;
45559
45560         var generateCubeFaceCallback = function ( rq, img ) {
45561
45562             return function () {
45563
45564                 var buffer = rq.response;
45565                 var dds = THREE.ImageUtils.parseDDS( buffer, true );
45566
45567                 img.format = dds.format;
45568
45569                 img.mipmaps = dds.mipmaps;
45570                 img.width = dds.width;
45571                 img.height = dds.height;
45572
45573                 images.loadCount += 1;
45574
45575                 if ( images.loadCount === 6 ) {
45576
45577                     texture.format = dds.format;
45578                     texture.needsUpdate = true;
45579                     if ( onLoad ) onLoad();
45580
45581                 }
45582
45583             }
45584
45585         }
45586
45587         for ( var i = 0, il = array.length; i < il; ++ i ) {
45588
45589             var cubeImage = {};
45590             images[ i ] = cubeImage;
45591
45592             var request = new XMLHttpRequest();
45593
45594             request.onload = generateCubeFaceCallback( request, cubeImage );
45595             request.onerror = onError;
45596
45597             var url = array[ i ];
45598
45599             request.open( 'GET', url, true );
45600             request.responseType = "arraybuffer";
45601             request.send( null );
45602
45603         }
45604
45605         return texture;
45606
45607     },
45608
45609     parseDDS: function ( buffer, loadMipmaps ) {
45610
45611         var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 };
45612
45613         // Adapted from @toji's DDS utils
45614         //    https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
45615
45616         // All values and structures referenced from:
45617         // http://msdn.microsoft.com/en-us/library/bb943991.aspx/
45618
45619         var DDS_MAGIC = 0x20534444;
45620
45621         var DDSD_CAPS = 0x1,
45622             DDSD_HEIGHT = 0x2,
45623             DDSD_WIDTH = 0x4,
45624             DDSD_PITCH = 0x8,
45625             DDSD_PIXELFORMAT = 0x1000,
45626             DDSD_MIPMAPCOUNT = 0x20000,
45627             DDSD_LINEARSIZE = 0x80000,
45628             DDSD_DEPTH = 0x800000;
45629
45630         var DDSCAPS_COMPLEX = 0x8,
45631             DDSCAPS_MIPMAP = 0x400000,
45632             DDSCAPS_TEXTURE = 0x1000;
45633
45634         var DDSCAPS2_CUBEMAP = 0x200,
45635             DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
45636             DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
45637             DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
45638             DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
45639             DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
45640             DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
45641             DDSCAPS2_VOLUME = 0x200000;
45642
45643         var DDPF_ALPHAPIXELS = 0x1,
45644             DDPF_ALPHA = 0x2,
45645             DDPF_FOURCC = 0x4,
45646             DDPF_RGB = 0x40,
45647             DDPF_YUV = 0x200,
45648             DDPF_LUMINANCE = 0x20000;
45649
45650         function fourCCToInt32( value ) {
45651
45652             return value.charCodeAt(0) +
45653                 (value.charCodeAt(1) << 8) +
45654                 (value.charCodeAt(2) << 16) +
45655                 (value.charCodeAt(3) << 24);
45656
45657         }
45658
45659         function int32ToFourCC( value ) {
45660
45661             return String.fromCharCode(
45662                 value & 0xff,
45663                 (value >> 8) & 0xff,
45664                 (value >> 16) & 0xff,
45665                 (value >> 24) & 0xff
45666             );
45667         }
45668
45669         var FOURCC_DXT1 = fourCCToInt32("DXT1");
45670         var FOURCC_DXT3 = fourCCToInt32("DXT3");
45671         var FOURCC_DXT5 = fourCCToInt32("DXT5");
45672
45673         var headerLengthInt = 31; // The header length in 32 bit ints
45674
45675         // Offsets into the header array
45676
45677         var off_magic = 0;
45678
45679         var off_size = 1;
45680         var off_flags = 2;
45681         var off_height = 3;
45682         var off_width = 4;
45683
45684         var off_mipmapCount = 7;
45685
45686         var off_pfFlags = 20;
45687         var off_pfFourCC = 21;
45688
45689         // Parse header
45690
45691         var header = new Int32Array( buffer, 0, headerLengthInt );
45692
45693         if ( header[ off_magic ] !== DDS_MAGIC ) {
45694
45695             console.error( "ImageUtils.parseDDS(): Invalid magic number in DDS header" );
45696             return dds;
45697
45698         }
45699
45700         if ( ! header[ off_pfFlags ] & DDPF_FOURCC ) {
45701
45702             console.error( "ImageUtils.parseDDS(): Unsupported format, must contain a FourCC code" );
45703             return dds;
45704
45705         }
45706
45707         var blockBytes;
45708
45709         var fourCC = header[ off_pfFourCC ];
45710
45711         switch ( fourCC ) {
45712
45713             case FOURCC_DXT1:
45714
45715                 blockBytes = 8;
45716                 dds.format = THREE.RGB_S3TC_DXT1_Format;
45717                 break;
45718
45719             case FOURCC_DXT3:
45720
45721                 blockBytes = 16;
45722                 dds.format = THREE.RGBA_S3TC_DXT3_Format;
45723                 break;
45724
45725             case FOURCC_DXT5:
45726
45727                 blockBytes = 16;
45728                 dds.format = THREE.RGBA_S3TC_DXT5_Format;
45729                 break;
45730
45731             default:
45732
45733                 console.error( "ImageUtils.parseDDS(): Unsupported FourCC code: ", int32ToFourCC( fourCC ) );
45734                 return dds;
45735
45736         }
45737
45738         dds.mipmapCount = 1;
45739
45740         if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) {
45741
45742             dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] );
45743
45744         }
45745
45746         dds.width = header[ off_width ];
45747         dds.height = header[ off_height ];
45748
45749         var dataOffset = header[ off_size ] + 4;
45750
45751         // Extract mipmaps buffers
45752
45753         var width = dds.width;
45754         var height = dds.height;
45755
45756         for ( var i = 0; i < dds.mipmapCount; i ++ ) {
45757
45758             var dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes;
45759             var byteArray = new Uint8Array( buffer, dataOffset, dataLength );
45760
45761             var mipmap = { "data": byteArray, "width": width, "height": height };
45762             dds.mipmaps.push( mipmap );
45763
45764             dataOffset += dataLength;
45765
45766             width = Math.max( width * 0.5, 1 );
45767             height = Math.max( height * 0.5, 1 );
45768
45769         }
45770
45771         return dds;
45772
45773     },
45774
45775     getNormalMap: function ( image, depth ) {
45776
45777         // Adapted from http://www.paulbrunt.co.uk/lab/heightnormal/
45778
45779         var cross = function ( a, b ) {
45780
45781             return [ a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ], a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ], a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ] ];
45782
45783         }
45784
45785         var subtract = function ( a, b ) {
45786
45787             return [ a[ 0 ] - b[ 0 ], a[ 1 ] - b[ 1 ], a[ 2 ] - b[ 2 ] ];
45788
45789         }
45790
45791         var normalize = function ( a ) {
45792
45793             var l = Math.sqrt( a[ 0 ] * a[ 0 ] + a[ 1 ] * a[ 1 ] + a[ 2 ] * a[ 2 ] );
45794             return [ a[ 0 ] / l, a[ 1 ] / l, a[ 2 ] / l ];
45795
45796         }
45797
45798         depth = depth | 1;
45799
45800         var width = image.width;
45801         var height = image.height;
45802
45803         var canvas = document.createElement( 'canvas' );
45804         canvas.width = width;
45805         canvas.height = height;
45806
45807         var context = canvas.getContext( '2d' );
45808         context.drawImage( image, 0, 0 );
45809
45810         var data = context.getImageData( 0, 0, width, height ).data;
45811         var imageData = context.createImageData( width, height );
45812         var output = imageData.data;
45813
45814         for ( var x = 0; x < width; x ++ ) {
45815
45816             for ( var y = 0; y < height; y ++ ) {
45817
45818                 var ly = y - 1 < 0 ? 0 : y - 1;
45819                 var uy = y + 1 > height - 1 ? height - 1 : y + 1;
45820                 var lx = x - 1 < 0 ? 0 : x - 1;
45821                 var ux = x + 1 > width - 1 ? width - 1 : x + 1;
45822
45823                 var points = [];
45824                 var origin = [ 0, 0, data[ ( y * width + x ) * 4 ] / 255 * depth ];
45825                 points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] );
45826                 points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] );
45827                 points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] );
45828                 points.push( [  1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] );
45829                 points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] );
45830                 points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] );
45831                 points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] );
45832                 points.push( [ - 1, 1, data[ ( uy * width + lx ) * 4 ] / 255 * depth ] );
45833
45834                 var normals = [];
45835                 var num_points = points.length;
45836
45837                 for ( var i = 0; i < num_points; i ++ ) {
45838
45839                     var v1 = points[ i ];
45840                     var v2 = points[ ( i + 1 ) % num_points ];
45841                     v1 = subtract( v1, origin );
45842                     v2 = subtract( v2, origin );
45843                     normals.push( normalize( cross( v1, v2 ) ) );
45844
45845                 }
45846
45847                 var normal = [ 0, 0, 0 ];
45848
45849                 for ( var i = 0; i < normals.length; i ++ ) {
45850
45851                     normal[ 0 ] += normals[ i ][ 0 ];
45852                     normal[ 1 ] += normals[ i ][ 1 ];
45853                     normal[ 2 ] += normals[ i ][ 2 ];
45854
45855                 }
45856
45857                 normal[ 0 ] /= normals.length;
45858                 normal[ 1 ] /= normals.length;
45859                 normal[ 2 ] /= normals.length;
45860
45861                 var idx = ( y * width + x ) * 4;
45862
45863                 output[ idx ] = ( ( normal[ 0 ] + 1.0 ) / 2.0 * 255 ) | 0;
45864                 output[ idx + 1 ] = ( ( normal[ 1 ] + 1.0 ) / 2.0 * 255 ) | 0;
45865                 output[ idx + 2 ] = ( normal[ 2 ] * 255 ) | 0;
45866                 output[ idx + 3 ] = 255;
45867
45868             }
45869
45870         }
45871
45872         context.putImageData( imageData, 0, 0 );
45873
45874         return canvas;
45875
45876     },
45877
45878     generateDataTexture: function ( width, height, color ) {
45879
45880         var size = width * height;
45881         var data = new Uint8Array( 3 * size );
45882
45883         var r = Math.floor( color.r * 255 );
45884         var g = Math.floor( color.g * 255 );
45885         var b = Math.floor( color.b * 255 );
45886
45887         for ( var i = 0; i < size; i ++ ) {
45888
45889             data[ i * 3 ]       = r;
45890             data[ i * 3 + 1 ] = g;
45891             data[ i * 3 + 2 ] = b;
45892
45893         }
45894
45895         var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
45896         texture.needsUpdate = true;
45897
45898         return texture;
45899
45900     }
45901
45902 };
45903 /**
45904  * @author alteredq / http://alteredqualia.com/
45905  */
45906
45907 THREE.SceneUtils = {
45908
45909     showHierarchy : function ( root, visible ) {
45910
45911         THREE.SceneUtils.traverseHierarchy( root, function( node ) { node.visible = visible; } );
45912
45913     },
45914
45915     traverseHierarchy : function ( root, callback ) {
45916
45917         var n, i, l = root.children.length;
45918
45919         for ( i = 0; i < l; i ++ ) {
45920
45921             n = root.children[ i ];
45922
45923             callback( n );
45924
45925             THREE.SceneUtils.traverseHierarchy( n, callback );
45926
45927         }
45928
45929     },
45930
45931     createMultiMaterialObject : function ( geometry, materials ) {
45932
45933         var i, il = materials.length,
45934             group = new THREE.Object3D();
45935
45936         for ( i = 0; i < il; i ++ ) {
45937
45938             var object = new THREE.Mesh( geometry, materials[ i ] );
45939             group.add( object );
45940
45941         }
45942
45943         return group;
45944
45945     },
45946
45947     cloneObject: function ( source ) {
45948
45949         var object;
45950
45951         // subclass specific properties
45952         // (must process in order from more specific subclasses to more abstract classes)
45953
45954         if ( source instanceof THREE.MorphAnimMesh ) {
45955
45956             object = new THREE.MorphAnimMesh( source.geometry, source.material );
45957
45958             object.duration = source.duration;
45959             object.mirroredLoop = source.mirroredLoop;
45960             object.time = source.time;
45961
45962             object.lastKeyframe = source.lastKeyframe;
45963             object.currentKeyframe = source.currentKeyframe;
45964
45965             object.direction = source.direction;
45966             object.directionBackwards = source.directionBackwards;
45967
45968         } else if ( source instanceof THREE.SkinnedMesh ) {
45969
45970             object = new THREE.SkinnedMesh( source.geometry, source.material, source.useVertexTexture );
45971
45972         } else if ( source instanceof THREE.Mesh ) {
45973
45974             object = new THREE.Mesh( source.geometry, source.material );
45975
45976         } else if ( source instanceof THREE.Line ) {
45977
45978             object = new THREE.Line( source.geometry, source.material, source.type );
45979
45980         } else if ( source instanceof THREE.Ribbon ) {
45981
45982             object = new THREE.Ribbon( source.geometry, source.material );
45983
45984         } else if ( source instanceof THREE.ParticleSystem ) {
45985
45986             object = new THREE.ParticleSystem( source.geometry, source.material );
45987             object.sortParticles = source.sortParticles;
45988
45989         } else if ( source instanceof THREE.Particle ) {
45990
45991             object = new THREE.Particle( source.material );
45992
45993         } else if ( source instanceof THREE.Sprite ) {
45994
45995             object = new THREE.Sprite( {} );
45996
45997             object.color.copy( source.color );
45998             object.map = source.map;
45999             object.blending = source.blending;
46000
46001             object.useScreenCoordinates = source.useScreenCoordinates;
46002             object.mergeWith3D = source.mergeWith3D;
46003             object.affectedByDistance = source.affectedByDistance;
46004             object.scaleByViewport = source.scaleByViewport;
46005             object.alignment = source.alignment;
46006
46007             object.rotation3d.copy( source.rotation3d );
46008             object.rotation = source.rotation;
46009             object.opacity = source.opacity;
46010
46011             object.uvOffset.copy( source.uvOffset );
46012             object.uvScale.copy( source.uvScale);
46013
46014         } else if ( source instanceof THREE.LOD ) {
46015
46016             object = new THREE.LOD();
46017
46018         /*
46019         } else if ( source instanceof THREE.MarchingCubes ) {
46020
46021             object = new THREE.MarchingCubes( source.resolution, source.material );
46022             object.field.set( source.field );
46023             object.isolation = source.isolation;
46024         */
46025
46026         } else if ( source instanceof THREE.Object3D ) {
46027
46028             object = new THREE.Object3D();
46029
46030         }
46031
46032         // base class properties
46033
46034         object.name = source.name;
46035
46036         object.parent = source.parent;
46037
46038         object.up.copy( source.up );
46039
46040         object.position.copy( source.position );
46041
46042         // because of Sprite madness
46043
46044         if ( object.rotation instanceof THREE.Vector3 )
46045             object.rotation.copy( source.rotation );
46046
46047         object.eulerOrder = source.eulerOrder;
46048
46049         object.scale.copy( source.scale );
46050
46051         object.dynamic = source.dynamic;
46052
46053         object.renderDepth = source.renderDepth;
46054
46055         object.rotationAutoUpdate = source.rotationAutoUpdate;
46056
46057         object.matrix.copy( source.matrix );
46058         object.matrixWorld.copy( source.matrixWorld );
46059         object.matrixRotationWorld.copy( source.matrixRotationWorld );
46060
46061         object.matrixAutoUpdate = source.matrixAutoUpdate;
46062         object.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
46063
46064         object.quaternion.copy( source.quaternion );
46065         object.useQuaternion = source.useQuaternion;
46066
46067         object.boundRadius = source.boundRadius;
46068         object.boundRadiusScale = source.boundRadiusScale;
46069
46070         object.visible = source.visible;
46071
46072         object.castShadow = source.castShadow;
46073         object.receiveShadow = source.receiveShadow;
46074
46075         object.frustumCulled = source.frustumCulled;
46076
46077         // children
46078
46079         for ( var i = 0; i < source.children.length; i ++ ) {
46080
46081             var child = THREE.SceneUtils.cloneObject( source.children[ i ] );
46082             object.children[ i ] = child;
46083
46084             child.parent = object;
46085
46086         }
46087
46088         // LODs need to be patched separately to use cloned children
46089
46090         if ( source instanceof THREE.LOD ) {
46091
46092             for ( var i = 0; i < source.LODs.length; i ++ ) {
46093
46094                 var lod = source.LODs[ i ];
46095                 object.LODs[ i ] = { visibleAtDistance: lod.visibleAtDistance, object3D: object.children[ i ] };
46096
46097             }
46098
46099         }
46100
46101         return object;
46102
46103     },
46104
46105     detach : function ( child, parent, scene ) {
46106
46107         child.applyMatrix( parent.matrixWorld );
46108         parent.remove( child );
46109         scene.add( child );
46110
46111     },
46112
46113     attach: function ( child, scene, parent ) {
46114
46115         var matrixWorldInverse = new THREE.Matrix4();
46116         matrixWorldInverse.getInverse( parent.matrixWorld );
46117         child.applyMatrix( matrixWorldInverse );
46118
46119         scene.remove( child );
46120         parent.add( child );
46121
46122     }
46123
46124 };
46125 /**
46126  * @author alteredq / http://alteredqualia.com/
46127  * @author mrdoob / http://mrdoob.com/
46128  *
46129  * ShaderUtils currently contains:
46130  *
46131  *    fresnel
46132  *    normal
46133  *     cube
46134  *
46135  */
46136
46137 if ( THREE.WebGLRenderer ) {
46138
46139 THREE.ShaderUtils = {
46140
46141     lib: {
46142
46143         /* -------------------------------------------------------------------------
46144         //    Fresnel shader
46145         //    - based on Nvidia Cg tutorial
46146          ------------------------------------------------------------------------- */
46147
46148         'fresnel': {
46149
46150             uniforms: {
46151
46152                 "mRefractionRatio": { type: "f", value: 1.02 },
46153                 "mFresnelBias": { type: "f", value: 0.1 },
46154                 "mFresnelPower": { type: "f", value: 2.0 },
46155                 "mFresnelScale": { type: "f", value: 1.0 },
46156                 "tCube": { type: "t", value: null }
46157
46158             },
46159
46160             fragmentShader: [
46161
46162                 "uniform samplerCube tCube;",
46163
46164                 "varying vec3 vReflect;",
46165                 "varying vec3 vRefract[3];",
46166                 "varying float vReflectionFactor;",
46167
46168                 "void main() {",
46169
46170                     "vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );",
46171                     "vec4 refractedColor = vec4( 1.0, 1.0, 1.0, 1.0 );",
46172
46173                     "refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;",
46174                     "refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;",
46175                     "refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;",
46176                     "refractedColor.a = 1.0;",
46177
46178                     "gl_FragColor = mix( refractedColor, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );",
46179
46180                 "}"
46181
46182             ].join("\n"),
46183
46184             vertexShader: [
46185
46186                 "uniform float mRefractionRatio;",
46187                 "uniform float mFresnelBias;",
46188                 "uniform float mFresnelScale;",
46189                 "uniform float mFresnelPower;",
46190
46191                 "varying vec3 vReflect;",
46192                 "varying vec3 vRefract[3];",
46193                 "varying float vReflectionFactor;",
46194
46195                 "void main() {",
46196
46197                     "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
46198                     "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
46199
46200                     "vec3 nWorld = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );",
46201
46202                     "vec3 I = mPosition.xyz - cameraPosition;",
46203
46204                     "vReflect = reflect( I, nWorld );",
46205                     "vRefract[0] = refract( normalize( I ), nWorld, mRefractionRatio );",
46206                     "vRefract[1] = refract( normalize( I ), nWorld, mRefractionRatio * 0.99 );",
46207                     "vRefract[2] = refract( normalize( I ), nWorld, mRefractionRatio * 0.98 );",
46208                     "vReflectionFactor = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( I ), nWorld ), mFresnelPower );",
46209
46210                     "gl_Position = projectionMatrix * mvPosition;",
46211
46212                 "}"
46213
46214             ].join("\n")
46215
46216         },
46217
46218         /* -------------------------------------------------------------------------
46219         //    Normal map shader
46220         //        - Blinn-Phong
46221         //        - normal + diffuse + specular + AO + displacement + reflection + shadow maps
46222         //        - point and directional lights (use with "lights: true" material option)
46223          ------------------------------------------------------------------------- */
46224
46225         'normal' : {
46226
46227             uniforms: THREE.UniformsUtils.merge( [
46228
46229                 THREE.UniformsLib[ "fog" ],
46230                 THREE.UniformsLib[ "lights" ],
46231                 THREE.UniformsLib[ "shadowmap" ],
46232
46233                 {
46234
46235                 "enableAO"          : { type: "i", value: 0 },
46236                 "enableDiffuse"      : { type: "i", value: 0 },
46237                 "enableSpecular"  : { type: "i", value: 0 },
46238                 "enableReflection": { type: "i", value: 0 },
46239                 "enableDisplacement": { type: "i", value: 0 },
46240
46241                 "tDisplacement": { type: "t", value: null }, // must go first as this is vertex texture
46242                 "tDiffuse"       : { type: "t", value: null },
46243                 "tCube"           : { type: "t", value: null },
46244                 "tNormal"       : { type: "t", value: null },
46245                 "tSpecular"       : { type: "t", value: null },
46246                 "tAO"           : { type: "t", value: null },
46247
46248                 "uNormalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) },
46249
46250                 "uDisplacementBias": { type: "f", value: 0.0 },
46251                 "uDisplacementScale": { type: "f", value: 1.0 },
46252
46253                 "uDiffuseColor": { type: "c", value: new THREE.Color( 0xffffff ) },
46254                 "uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) },
46255                 "uAmbientColor": { type: "c", value: new THREE.Color( 0xffffff ) },
46256                 "uShininess": { type: "f", value: 30 },
46257                 "uOpacity": { type: "f", value: 1 },
46258
46259                 "useRefract": { type: "i", value: 0 },
46260                 "uRefractionRatio": { type: "f", value: 0.98 },
46261                 "uReflectivity": { type: "f", value: 0.5 },
46262
46263                 "uOffset" : { type: "v2", value: new THREE.Vector2( 0, 0 ) },
46264                 "uRepeat" : { type: "v2", value: new THREE.Vector2( 1, 1 ) },
46265
46266                 "wrapRGB"  : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
46267
46268                 }
46269
46270             ] ),
46271
46272             fragmentShader: [
46273
46274                 "uniform vec3 uAmbientColor;",
46275                 "uniform vec3 uDiffuseColor;",
46276                 "uniform vec3 uSpecularColor;",
46277                 "uniform float uShininess;",
46278                 "uniform float uOpacity;",
46279
46280                 "uniform bool enableDiffuse;",
46281                 "uniform bool enableSpecular;",
46282                 "uniform bool enableAO;",
46283                 "uniform bool enableReflection;",
46284
46285                 "uniform sampler2D tDiffuse;",
46286                 "uniform sampler2D tNormal;",
46287                 "uniform sampler2D tSpecular;",
46288                 "uniform sampler2D tAO;",
46289
46290                 "uniform samplerCube tCube;",
46291
46292                 "uniform vec2 uNormalScale;",
46293
46294                 "uniform bool useRefract;",
46295                 "uniform float uRefractionRatio;",
46296                 "uniform float uReflectivity;",
46297
46298                 "varying vec3 vTangent;",
46299                 "varying vec3 vBinormal;",
46300                 "varying vec3 vNormal;",
46301                 "varying vec2 vUv;",
46302
46303                 "uniform vec3 ambientLightColor;",
46304
46305                 "#if MAX_DIR_LIGHTS > 0",
46306
46307                     "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
46308                     "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
46309
46310                 "#endif",
46311
46312                 "#if MAX_HEMI_LIGHTS > 0",
46313
46314                     "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
46315                     "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
46316                     "uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
46317
46318                 "#endif",
46319
46320                 "#if MAX_POINT_LIGHTS > 0",
46321
46322                     "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
46323                     "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
46324                     "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
46325
46326                 "#endif",
46327
46328                 "#if MAX_SPOT_LIGHTS > 0",
46329
46330                     "uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
46331                     "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
46332                     "uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
46333                     "uniform float spotLightAngle[ MAX_SPOT_LIGHTS ];",
46334                     "uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
46335                     "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
46336
46337                 "#endif",
46338
46339                 "#ifdef WRAP_AROUND",
46340
46341                     "uniform vec3 wrapRGB;",
46342
46343                 "#endif",
46344
46345                 "varying vec3 vWorldPosition;",
46346                 "varying vec3 vViewPosition;",
46347
46348                 THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
46349                 THREE.ShaderChunk[ "fog_pars_fragment" ],
46350
46351                 "void main() {",
46352
46353                     "gl_FragColor = vec4( vec3( 1.0 ), uOpacity );",
46354
46355                     "vec3 specularTex = vec3( 1.0 );",
46356
46357                     "vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
46358                     "normalTex.xy *= uNormalScale;",
46359                     "normalTex = normalize( normalTex );",
46360
46361                     "if( enableDiffuse ) {",
46362
46363                         "#ifdef GAMMA_INPUT",
46364
46365                             "vec4 texelColor = texture2D( tDiffuse, vUv );",
46366                             "texelColor.xyz *= texelColor.xyz;",
46367
46368                             "gl_FragColor = gl_FragColor * texelColor;",
46369
46370                         "#else",
46371
46372                             "gl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );",
46373
46374                         "#endif",
46375
46376                     "}",
46377
46378                     "if( enableAO ) {",
46379
46380                         "#ifdef GAMMA_INPUT",
46381
46382                             "vec4 aoColor = texture2D( tAO, vUv );",
46383                             "aoColor.xyz *= aoColor.xyz;",
46384
46385                             "gl_FragColor.xyz = gl_FragColor.xyz * aoColor.xyz;",
46386
46387                         "#else",
46388
46389                             "gl_FragColor.xyz = gl_FragColor.xyz * texture2D( tAO, vUv ).xyz;",
46390
46391                         "#endif",
46392
46393                     "}",
46394
46395                     "if( enableSpecular )",
46396                         "specularTex = texture2D( tSpecular, vUv ).xyz;",
46397
46398                     "mat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );",
46399                     "vec3 finalNormal = tsb * normalTex;",
46400
46401                     "#ifdef FLIP_SIDED",
46402
46403                         "finalNormal = -finalNormal;",
46404
46405                     "#endif",
46406
46407                     "vec3 normal = normalize( finalNormal );",
46408                     "vec3 viewPosition = normalize( vViewPosition );",
46409
46410                     // point lights
46411
46412                     "#if MAX_POINT_LIGHTS > 0",
46413
46414                         "vec3 pointDiffuse = vec3( 0.0 );",
46415                         "vec3 pointSpecular = vec3( 0.0 );",
46416
46417                         "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
46418
46419                             "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
46420                             "vec3 pointVector = lPosition.xyz + vViewPosition.xyz;",
46421
46422                             "float pointDistance = 1.0;",
46423                             "if ( pointLightDistance[ i ] > 0.0 )",
46424                                 "pointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );",
46425
46426                             "pointVector = normalize( pointVector );",
46427
46428                             // diffuse
46429
46430                             "#ifdef WRAP_AROUND",
46431
46432                                 "float pointDiffuseWeightFull = max( dot( normal, pointVector ), 0.0 );",
46433                                 "float pointDiffuseWeightHalf = max( 0.5 * dot( normal, pointVector ) + 0.5, 0.0 );",
46434
46435                                 "vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );",
46436
46437                             "#else",
46438
46439                                 "float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
46440
46441                             "#endif",
46442
46443                             "pointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;",
46444
46445                             // specular
46446
46447                             "vec3 pointHalfVector = normalize( pointVector + viewPosition );",
46448                             "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
46449                             "float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, uShininess ), 0.0 );",
46450
46451                             "#ifdef PHYSICALLY_BASED_SHADING",
46452
46453                                 // 2.0 => 2.0001 is hack to work around ANGLE bug
46454
46455                                 "float specularNormalization = ( uShininess + 2.0001 ) / 8.0;",
46456
46457                                 "vec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( pointVector, pointHalfVector ), 5.0 );",
46458                                 "pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;",
46459
46460                             "#else",
46461
46462                                 "pointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;",
46463
46464                             "#endif",
46465
46466                         "}",
46467
46468                     "#endif",
46469
46470                     // spot lights
46471
46472                     "#if MAX_SPOT_LIGHTS > 0",
46473
46474                         "vec3 spotDiffuse = vec3( 0.0 );",
46475                         "vec3 spotSpecular = vec3( 0.0 );",
46476
46477                         "for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
46478
46479                             "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
46480                             "vec3 spotVector = lPosition.xyz + vViewPosition.xyz;",
46481
46482                             "float spotDistance = 1.0;",
46483                             "if ( spotLightDistance[ i ] > 0.0 )",
46484                                 "spotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );",
46485
46486                             "spotVector = normalize( spotVector );",
46487
46488                             "float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );",
46489
46490                             "if ( spotEffect > spotLightAngle[ i ] ) {",
46491
46492                                 "spotEffect = pow( spotEffect, spotLightExponent[ i ] );",
46493
46494                                 // diffuse
46495
46496                                 "#ifdef WRAP_AROUND",
46497
46498                                     "float spotDiffuseWeightFull = max( dot( normal, spotVector ), 0.0 );",
46499                                     "float spotDiffuseWeightHalf = max( 0.5 * dot( normal, spotVector ) + 0.5, 0.0 );",
46500
46501                                     "vec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );",
46502
46503                                 "#else",
46504
46505                                     "float spotDiffuseWeight = max( dot( normal, spotVector ), 0.0 );",
46506
46507                                 "#endif",
46508
46509                                 "spotDiffuse += spotDistance * spotLightColor[ i ] * uDiffuseColor * spotDiffuseWeight * spotEffect;",
46510
46511                                 // specular
46512
46513                                 "vec3 spotHalfVector = normalize( spotVector + viewPosition );",
46514                                 "float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
46515                                 "float spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, uShininess ), 0.0 );",
46516
46517                                 "#ifdef PHYSICALLY_BASED_SHADING",
46518
46519                                     // 2.0 => 2.0001 is hack to work around ANGLE bug
46520
46521                                     "float specularNormalization = ( uShininess + 2.0001 ) / 8.0;",
46522
46523                                     "vec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( spotVector, spotHalfVector ), 5.0 );",
46524                                     "spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;",
46525
46526                                 "#else",
46527
46528                                     "spotSpecular += spotDistance * spotLightColor[ i ] * uSpecularColor * spotSpecularWeight * spotDiffuseWeight * spotEffect;",
46529
46530                                 "#endif",
46531
46532                             "}",
46533
46534                         "}",
46535
46536                     "#endif",
46537
46538                     // directional lights
46539
46540                     "#if MAX_DIR_LIGHTS > 0",
46541
46542                         "vec3 dirDiffuse = vec3( 0.0 );",
46543                         "vec3 dirSpecular = vec3( 0.0 );",
46544
46545                         "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
46546
46547                             "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
46548                             "vec3 dirVector = normalize( lDirection.xyz );",
46549
46550                             // diffuse
46551
46552                             "#ifdef WRAP_AROUND",
46553
46554                                 "float directionalLightWeightingFull = max( dot( normal, dirVector ), 0.0 );",
46555                                 "float directionalLightWeightingHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );",
46556
46557                                 "vec3 dirDiffuseWeight = mix( vec3( directionalLightWeightingFull ), vec3( directionalLightWeightingHalf ), wrapRGB );",
46558
46559                             "#else",
46560
46561                                 "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
46562
46563                             "#endif",
46564
46565                             "dirDiffuse += directionalLightColor[ i ] * uDiffuseColor * dirDiffuseWeight;",
46566
46567                             // specular
46568
46569                             "vec3 dirHalfVector = normalize( dirVector + viewPosition );",
46570                             "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
46571                             "float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, uShininess ), 0.0 );",
46572
46573                             "#ifdef PHYSICALLY_BASED_SHADING",
46574
46575                                 // 2.0 => 2.0001 is hack to work around ANGLE bug
46576
46577                                 "float specularNormalization = ( uShininess + 2.0001 ) / 8.0;",
46578
46579                                 "vec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );",
46580                                 "dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
46581
46582                             "#else",
46583
46584                                 "dirSpecular += directionalLightColor[ i ] * uSpecularColor * dirSpecularWeight * dirDiffuseWeight;",
46585
46586                             "#endif",
46587
46588                         "}",
46589
46590                     "#endif",
46591
46592                     // hemisphere lights
46593
46594                     "#if MAX_HEMI_LIGHTS > 0",
46595
46596                         "vec3 hemiDiffuse  = vec3( 0.0 );",
46597                         "vec3 hemiSpecular = vec3( 0.0 );" ,
46598
46599                         "for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
46600
46601                             "vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
46602                             "vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
46603
46604                             // diffuse
46605
46606                             "float dotProduct = dot( normal, lVector );",
46607                             "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
46608
46609                             "vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
46610
46611                             "hemiDiffuse += uDiffuseColor * hemiColor;",
46612
46613                             // specular (sky light)
46614
46615
46616                             "vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
46617                             "float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
46618                             "float hemiSpecularWeightSky = specularTex.r * max( pow( hemiDotNormalHalfSky, uShininess ), 0.0 );",
46619
46620                             // specular (ground light)
46621
46622                             "vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
46623
46624                             "vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );",
46625                             "float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
46626                             "float hemiSpecularWeightGround = specularTex.r * max( pow( hemiDotNormalHalfGround, uShininess ), 0.0 );",
46627
46628                             "#ifdef PHYSICALLY_BASED_SHADING",
46629
46630                                 "float dotProductGround = dot( normal, lVectorGround );",
46631
46632                                 // 2.0 => 2.0001 is hack to work around ANGLE bug
46633
46634                                 "float specularNormalization = ( uShininess + 2.0001 ) / 8.0;",
46635
46636                                 "vec3 schlickSky = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );",
46637                                 "vec3 schlickGround = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
46638                                 "hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",
46639
46640                             "#else",
46641
46642                                 "hemiSpecular += uSpecularColor * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;",
46643
46644                             "#endif",
46645
46646                         "}",
46647
46648                     "#endif",
46649
46650                     // all lights contribution summation
46651
46652                     "vec3 totalDiffuse = vec3( 0.0 );",
46653                     "vec3 totalSpecular = vec3( 0.0 );",
46654
46655                     "#if MAX_DIR_LIGHTS > 0",
46656
46657                         "totalDiffuse += dirDiffuse;",
46658                         "totalSpecular += dirSpecular;",
46659
46660                     "#endif",
46661
46662                     "#if MAX_HEMI_LIGHTS > 0",
46663
46664                         "totalDiffuse += hemiDiffuse;",
46665                         "totalSpecular += hemiSpecular;",
46666
46667                     "#endif",
46668
46669                     "#if MAX_POINT_LIGHTS > 0",
46670
46671                         "totalDiffuse += pointDiffuse;",
46672                         "totalSpecular += pointSpecular;",
46673
46674                     "#endif",
46675
46676                     "#if MAX_SPOT_LIGHTS > 0",
46677
46678                         "totalDiffuse += spotDiffuse;",
46679                         "totalSpecular += spotSpecular;",
46680
46681                     "#endif",
46682
46683                     "#ifdef METAL",
46684
46685                         "gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );",
46686
46687                     "#else",
46688
46689                         "gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor ) + totalSpecular;",
46690
46691                     "#endif",
46692
46693                     "if ( enableReflection ) {",
46694
46695                         "vec3 vReflect;",
46696                         "vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",
46697
46698                         "if ( useRefract ) {",
46699
46700                             "vReflect = refract( cameraToVertex, normal, uRefractionRatio );",
46701
46702                         "} else {",
46703
46704                             "vReflect = reflect( cameraToVertex, normal );",
46705
46706                         "}",
46707
46708                         "vec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );",
46709
46710                         "#ifdef GAMMA_INPUT",
46711
46712                             "cubeColor.xyz *= cubeColor.xyz;",
46713
46714                         "#endif",
46715
46716                         "gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * uReflectivity );",
46717
46718                     "}",
46719
46720                     THREE.ShaderChunk[ "shadowmap_fragment" ],
46721                     THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
46722                     THREE.ShaderChunk[ "fog_fragment" ],
46723
46724                 "}"
46725
46726             ].join("\n"),
46727
46728             vertexShader: [
46729
46730                 "attribute vec4 tangent;",
46731
46732                 "uniform vec2 uOffset;",
46733                 "uniform vec2 uRepeat;",
46734
46735                 "uniform bool enableDisplacement;",
46736
46737                 "#ifdef VERTEX_TEXTURES",
46738
46739                     "uniform sampler2D tDisplacement;",
46740                     "uniform float uDisplacementScale;",
46741                     "uniform float uDisplacementBias;",
46742
46743                 "#endif",
46744
46745                 "varying vec3 vTangent;",
46746                 "varying vec3 vBinormal;",
46747                 "varying vec3 vNormal;",
46748                 "varying vec2 vUv;",
46749
46750                 "varying vec3 vWorldPosition;",
46751                 "varying vec3 vViewPosition;",
46752
46753                 THREE.ShaderChunk[ "skinning_pars_vertex" ],
46754                 THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
46755
46756                 "void main() {",
46757
46758                     THREE.ShaderChunk[ "skinbase_vertex" ],
46759                     THREE.ShaderChunk[ "skinnormal_vertex" ],
46760
46761                     // normal, tangent and binormal vectors
46762
46763                     "#ifdef USE_SKINNING",
46764
46765                         "vNormal = normalMatrix * skinnedNormal.xyz;",
46766
46767                         "vec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );",
46768                         "vTangent = normalMatrix * skinnedTangent.xyz;",
46769
46770                     "#else",
46771
46772                         "vNormal = normalMatrix * normal;",
46773                         "vTangent = normalMatrix * tangent.xyz;",
46774
46775                     "#endif",
46776
46777                     "vBinormal = cross( vNormal, vTangent ) * tangent.w;",
46778
46779                     "vUv = uv * uRepeat + uOffset;",
46780
46781                     // displacement mapping
46782
46783                     "vec3 displacedPosition;",
46784
46785                     "#ifdef VERTEX_TEXTURES",
46786
46787                         "if ( enableDisplacement ) {",
46788
46789                             "vec3 dv = texture2D( tDisplacement, uv ).xyz;",
46790                             "float df = uDisplacementScale * dv.x + uDisplacementBias;",
46791                             "displacedPosition = position + normalize( normal ) * df;",
46792
46793                         "} else {",
46794
46795                             "#ifdef USE_SKINNING",
46796
46797                                 "vec4 skinVertex = vec4( position, 1.0 );",
46798
46799                                 "vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
46800                                 "skinned       += boneMatY * skinVertex * skinWeight.y;",
46801
46802                                 "displacedPosition  = skinned.xyz;",
46803
46804                             "#else",
46805
46806                                 "displacedPosition = position;",
46807
46808                             "#endif",
46809
46810                         "}",
46811
46812                     "#else",
46813
46814                         "#ifdef USE_SKINNING",
46815
46816                             "vec4 skinVertex = vec4( position, 1.0 );",
46817
46818                             "vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
46819                             "skinned       += boneMatY * skinVertex * skinWeight.y;",
46820
46821                             "displacedPosition  = skinned.xyz;",
46822
46823                         "#else",
46824
46825                             "displacedPosition = position;",
46826
46827                         "#endif",
46828
46829                     "#endif",
46830
46831                     //
46832
46833                     "vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );",
46834                     "vec4 mPosition = modelMatrix * vec4( displacedPosition, 1.0 );",
46835
46836                     "gl_Position = projectionMatrix * mvPosition;",
46837
46838                     //
46839
46840                     "vWorldPosition = mPosition.xyz;",
46841                     "vViewPosition = -mvPosition.xyz;",
46842
46843                     // shadows
46844
46845                     "#ifdef USE_SHADOWMAP",
46846
46847                         "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
46848
46849                             "vShadowCoord[ i ] = shadowMatrix[ i ] * mPosition;",
46850
46851                         "}",
46852
46853                     "#endif",
46854
46855                 "}"
46856
46857             ].join("\n")
46858
46859         },
46860
46861         /* -------------------------------------------------------------------------
46862         //    Cube map shader
46863          ------------------------------------------------------------------------- */
46864
46865         'cube': {
46866
46867             uniforms: { "tCube": { type: "t", value: null },
46868                         "tFlip": { type: "f", value: -1 } },
46869
46870             vertexShader: [
46871
46872                 "varying vec3 vViewPosition;",
46873
46874                 "void main() {",
46875
46876                     "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
46877                     "vViewPosition = cameraPosition - mPosition.xyz;",
46878
46879                     "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
46880
46881                 "}"
46882
46883             ].join("\n"),
46884
46885             fragmentShader: [
46886
46887                 "uniform samplerCube tCube;",
46888                 "uniform float tFlip;",
46889
46890                 "varying vec3 vViewPosition;",
46891
46892                 "void main() {",
46893
46894                     "vec3 wPos = cameraPosition - vViewPosition;",
46895                     "gl_FragColor = textureCube( tCube, vec3( tFlip * wPos.x, wPos.yz ) );",
46896
46897                 "}"
46898
46899             ].join("\n")
46900
46901         }
46902
46903     }
46904
46905 };
46906
46907 };
46908 /**
46909  * @author zz85 / http://www.lab4games.net/zz85/blog
46910  * @author alteredq / http://alteredqualia.com/
46911  *
46912  * For Text operations in three.js (See TextGeometry)
46913  *
46914  * It uses techniques used in:
46915  *
46916  *     typeface.js and canvastext
46917  *         For converting fonts and rendering with javascript
46918  *        http://typeface.neocracy.org
46919  *
46920  *    Triangulation ported from AS3
46921  *        Simple Polygon Triangulation
46922  *        http://actionsnippet.com/?p=1462
46923  *
46924  *     A Method to triangulate shapes with holes
46925  *        http://www.sakri.net/blog/2009/06/12/an-approach-to-triangulating-polygons-with-holes/
46926  *
46927  */
46928
46929 THREE.FontUtils = {
46930
46931     faces : {},
46932
46933     // Just for now. face[weight][style]
46934
46935     face : "helvetiker",
46936     weight: "normal",
46937     style : "normal",
46938     size : 150,
46939     divisions : 10,
46940
46941     getFace : function() {
46942
46943         return this.faces[ this.face ][ this.weight ][ this.style ];
46944
46945     },
46946
46947     loadFace : function( data ) {
46948
46949         var family = data.familyName.toLowerCase();
46950
46951         var ThreeFont = this;
46952
46953         ThreeFont.faces[ family ] = ThreeFont.faces[ family ] || {};
46954
46955         ThreeFont.faces[ family ][ data.cssFontWeight ] = ThreeFont.faces[ family ][ data.cssFontWeight ] || {};
46956         ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data;
46957
46958         var face = ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data;
46959
46960         return data;
46961
46962     },
46963
46964     drawText : function( text ) {
46965
46966         var characterPts = [], allPts = [];
46967
46968         // RenderText
46969
46970         var i, p,
46971             face = this.getFace(),
46972             scale = this.size / face.resolution,
46973             offset = 0,
46974             chars = String( text ).split( '' ),
46975             length = chars.length;
46976
46977         var fontPaths = [];
46978
46979         for ( i = 0; i < length; i ++ ) {
46980
46981             var path = new THREE.Path();
46982
46983             var ret = this.extractGlyphPoints( chars[ i ], face, scale, offset, path );
46984             offset += ret.offset;
46985
46986             fontPaths.push( ret.path );
46987
46988         }
46989
46990         // get the width
46991
46992         var width = offset / 2;
46993         //
46994         // for ( p = 0; p < allPts.length; p++ ) {
46995         //
46996         //     allPts[ p ].x -= width;
46997         //
46998         // }
46999
47000         //var extract = this.extractPoints( allPts, characterPts );
47001         //extract.contour = allPts;
47002
47003         //extract.paths = fontPaths;
47004         //extract.offset = width;
47005
47006         return { paths : fontPaths, offset : width };
47007
47008     },
47009
47010
47011
47012
47013     extractGlyphPoints : function( c, face, scale, offset, path ) {
47014
47015         var pts = [];
47016
47017         var i, i2, divisions,
47018             outline, action, length,
47019             scaleX, scaleY,
47020             x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2,
47021             laste,
47022             glyph = face.glyphs[ c ] || face.glyphs[ '?' ];
47023
47024         if ( !glyph ) return;
47025
47026         if ( glyph.o ) {
47027
47028             outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
47029             length = outline.length;
47030
47031             scaleX = scale;
47032             scaleY = scale;
47033
47034             for ( i = 0; i < length; ) {
47035
47036                 action = outline[ i ++ ];
47037
47038                 //console.log( action );
47039
47040                 switch( action ) {
47041
47042                 case 'm':
47043
47044                     // Move To
47045
47046                     x = outline[ i++ ] * scaleX + offset;
47047                     y = outline[ i++ ] * scaleY;
47048
47049                     path.moveTo( x, y );
47050                     break;
47051
47052                 case 'l':
47053
47054                     // Line To
47055
47056                     x = outline[ i++ ] * scaleX + offset;
47057                     y = outline[ i++ ] * scaleY;
47058                     path.lineTo(x,y);
47059                     break;
47060
47061                 case 'q':
47062
47063                     // QuadraticCurveTo
47064
47065                     cpx  = outline[ i++ ] * scaleX + offset;
47066                     cpy  = outline[ i++ ] * scaleY;
47067                     cpx1 = outline[ i++ ] * scaleX + offset;
47068                     cpy1 = outline[ i++ ] * scaleY;
47069
47070                     path.quadraticCurveTo(cpx1, cpy1, cpx, cpy);
47071
47072                     laste = pts[ pts.length - 1 ];
47073
47074                     if ( laste ) {
47075
47076                         cpx0 = laste.x;
47077                         cpy0 = laste.y;
47078
47079                         for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
47080
47081                             var t = i2 / divisions;
47082                             var tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx );
47083                             var ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy );
47084                       }
47085
47086                   }
47087
47088                   break;
47089
47090                 case 'b':
47091
47092                     // Cubic Bezier Curve
47093
47094                     cpx  = outline[ i++ ] *  scaleX + offset;
47095                     cpy  = outline[ i++ ] *  scaleY;
47096                     cpx1 = outline[ i++ ] *  scaleX + offset;
47097                     cpy1 = outline[ i++ ] * -scaleY;
47098                     cpx2 = outline[ i++ ] *  scaleX + offset;
47099                     cpy2 = outline[ i++ ] * -scaleY;
47100
47101                     path.bezierCurveTo( cpx, cpy, cpx1, cpy1, cpx2, cpy2 );
47102
47103                     laste = pts[ pts.length - 1 ];
47104
47105                     if ( laste ) {
47106
47107                         cpx0 = laste.x;
47108                         cpy0 = laste.y;
47109
47110                         for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
47111
47112                             var t = i2 / divisions;
47113                             var tx = THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx );
47114                             var ty = THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy );
47115
47116                         }
47117
47118                     }
47119
47120                     break;
47121
47122                 }
47123
47124             }
47125         }
47126
47127
47128
47129         return { offset: glyph.ha*scale, path:path};
47130     }
47131
47132 };
47133
47134
47135 THREE.FontUtils.generateShapes = function( text, parameters ) {
47136
47137     // Parameters
47138
47139     parameters = parameters || {};
47140
47141     var size = parameters.size !== undefined ? parameters.size : 100;
47142     var curveSegments = parameters.curveSegments !== undefined ? parameters.curveSegments: 4;
47143
47144     var font = parameters.font !== undefined ? parameters.font : "helvetiker";
47145     var weight = parameters.weight !== undefined ? parameters.weight : "normal";
47146     var style = parameters.style !== undefined ? parameters.style : "normal";
47147
47148     THREE.FontUtils.size = size;
47149     THREE.FontUtils.divisions = curveSegments;
47150
47151     THREE.FontUtils.face = font;
47152     THREE.FontUtils.weight = weight;
47153     THREE.FontUtils.style = style;
47154
47155     // Get a Font data json object
47156
47157     var data = THREE.FontUtils.drawText( text );
47158
47159     var paths = data.paths;
47160     var shapes = [];
47161
47162     for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
47163
47164         Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
47165
47166     }
47167
47168     return shapes;
47169
47170 };
47171
47172
47173 /**
47174  * This code is a quick port of code written in C++ which was submitted to
47175  * flipcode.com by John W. Ratcliff  // July 22, 2000
47176  * See original code and more information here:
47177  * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
47178  *
47179  * ported to actionscript by Zevan Rosser
47180  * www.actionsnippet.com
47181  *
47182  * ported to javascript by Joshua Koo
47183  * http://www.lab4games.net/zz85/blog
47184  *
47185  */
47186
47187
47188 ( function( namespace ) {
47189
47190     var EPSILON = 0.0000000001;
47191
47192     // takes in an contour array and returns
47193
47194     var process = function( contour, indices ) {
47195
47196         var n = contour.length;
47197
47198         if ( n < 3 ) return null;
47199
47200         var result = [],
47201             verts = [],
47202             vertIndices = [];
47203
47204         /* we want a counter-clockwise polygon in verts */
47205
47206         var u, v, w;
47207
47208         if ( area( contour ) > 0.0 ) {
47209
47210             for ( v = 0; v < n; v++ ) verts[ v ] = v;
47211
47212         } else {
47213
47214             for ( v = 0; v < n; v++ ) verts[ v ] = ( n - 1 ) - v;
47215
47216         }
47217
47218         var nv = n;
47219
47220         /*  remove nv - 2 vertices, creating 1 triangle every time */
47221
47222         var count = 2 * nv;   /* error detection */
47223
47224         for( v = nv - 1; nv > 2; ) {
47225
47226             /* if we loop, it is probably a non-simple polygon */
47227
47228             if ( ( count-- ) <= 0 ) {
47229
47230                 //** Triangulate: ERROR - probable bad polygon!
47231
47232                 //throw ( "Warning, unable to triangulate polygon!" );
47233                 //return null;
47234                 // Sometimes warning is fine, especially polygons are triangulated in reverse.
47235                 console.log( "Warning, unable to triangulate polygon!" );
47236
47237                 if ( indices ) return vertIndices;
47238                 return result;
47239
47240             }
47241
47242             /* three consecutive vertices in current polygon, <u,v,w> */
47243
47244             u = v;          if ( nv <= u ) u = 0;     /* previous */
47245             v = u + 1;  if ( nv <= v ) v = 0;     /* new v    */
47246             w = v + 1;  if ( nv <= w ) w = 0;     /* next     */
47247
47248             if ( snip( contour, u, v, w, nv, verts ) ) {
47249
47250                 var a, b, c, s, t;
47251
47252                 /* true names of the vertices */
47253
47254                 a = verts[ u ];
47255                 b = verts[ v ];
47256                 c = verts[ w ];
47257
47258                 /* output Triangle */
47259
47260                 /*
47261                 result.push( contour[ a ] );
47262                 result.push( contour[ b ] );
47263                 result.push( contour[ c ] );
47264                 */
47265                 result.push( [ contour[ a ],
47266                     contour[ b ],
47267                     contour[ c ] ] );
47268
47269
47270                 vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );
47271
47272                 /* remove v from the remaining polygon */
47273
47274                 for( s = v, t = v + 1; t < nv; s++, t++ ) {
47275
47276                     verts[ s ] = verts[ t ];
47277
47278                 }
47279
47280                 nv--;
47281
47282                 /* reset error detection counter */
47283
47284                 count = 2 * nv;
47285
47286             }
47287
47288         }
47289
47290         if ( indices ) return vertIndices;
47291         return result;
47292
47293     };
47294
47295     // calculate area of the contour polygon
47296
47297     var area = function ( contour ) {
47298
47299         var n = contour.length;
47300         var a = 0.0;
47301
47302         for( var p = n - 1, q = 0; q < n; p = q++ ) {
47303
47304             a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
47305
47306         }
47307
47308         return a * 0.5;
47309
47310     };
47311
47312     // see if p is inside triangle abc
47313
47314     var insideTriangle = function( ax, ay,
47315                                    bx, by,
47316                                    cx, cy,
47317                                    px, py ) {
47318
47319           var aX, aY, bX, bY;
47320           var cX, cY, apx, apy;
47321           var bpx, bpy, cpx, cpy;
47322           var cCROSSap, bCROSScp, aCROSSbp;
47323
47324           aX = cx - bx;  aY = cy - by;
47325           bX = ax - cx;  bY = ay - cy;
47326           cX = bx - ax;  cY = by - ay;
47327           apx= px  -ax;  apy= py - ay;
47328           bpx= px - bx;  bpy= py - by;
47329           cpx= px - cx;  cpy= py - cy;
47330
47331           aCROSSbp = aX*bpy - aY*bpx;
47332           cCROSSap = cX*apy - cY*apx;
47333           bCROSScp = bX*cpy - bY*cpx;
47334
47335           return ( (aCROSSbp >= 0.0) && (bCROSScp >= 0.0) && (cCROSSap >= 0.0) );
47336
47337     };
47338
47339
47340     var snip = function ( contour, u, v, w, n, verts ) {
47341
47342         var p;
47343         var ax, ay, bx, by;
47344         var cx, cy, px, py;
47345
47346         ax = contour[ verts[ u ] ].x;
47347         ay = contour[ verts[ u ] ].y;
47348
47349         bx = contour[ verts[ v ] ].x;
47350         by = contour[ verts[ v ] ].y;
47351
47352         cx = contour[ verts[ w ] ].x;
47353         cy = contour[ verts[ w ] ].y;
47354
47355         if ( EPSILON > (((bx-ax)*(cy-ay)) - ((by-ay)*(cx-ax))) ) return false;
47356
47357             for ( p = 0; p < n; p++ ) {
47358
47359                 if( (p == u) || (p == v) || (p == w) ) continue;
47360
47361                 px = contour[ verts[ p ] ].x
47362                 py = contour[ verts[ p ] ].y
47363
47364                 if ( insideTriangle( ax, ay, bx, by, cx, cy, px, py ) ) return false;
47365
47366           }
47367
47368           return true;
47369
47370     };
47371
47372
47373     namespace.Triangulate = process;
47374     namespace.Triangulate.area = area;
47375
47376     return namespace;
47377
47378 })(THREE.FontUtils);
47379
47380 // To use the typeface.js face files, hook up the API
47381 self._typeface_js = { faces: THREE.FontUtils.faces, loadFace: THREE.FontUtils.loadFace };/**
47382  * @author zz85 / http://www.lab4games.net/zz85/blog
47383  * Extensible curve object
47384  *
47385  * Some common of Curve methods
47386  * .getPoint(t), getTangent(t)
47387  * .getPointAt(u), getTagentAt(u)
47388  * .getPoints(), .getSpacedPoints()
47389  * .getLength()
47390  * .updateArcLengths()
47391  *
47392  * This file contains following classes:
47393  *
47394  * -- 2d classes --
47395  * THREE.Curve
47396  * THREE.LineCurve
47397  * THREE.QuadraticBezierCurve
47398  * THREE.CubicBezierCurve
47399  * THREE.SplineCurve
47400  * THREE.ArcCurve
47401  * THREE.EllipseCurve
47402  *
47403  * -- 3d classes --
47404  * THREE.LineCurve3
47405  * THREE.QuadraticBezierCurve3
47406  * THREE.CubicBezierCurve3
47407  * THREE.SplineCurve3
47408  * THREE.ClosedSplineCurve3
47409  *
47410  * A series of curves can be represented as a THREE.CurvePath
47411  *
47412  **/
47413
47414 /**************************************************************
47415  *    Abstract Curve base class
47416  **************************************************************/
47417
47418 THREE.Curve = function () {
47419
47420 };
47421
47422 // Virtual base class method to overwrite and implement in subclasses
47423 //    - t [0 .. 1]
47424
47425 THREE.Curve.prototype.getPoint = function ( t ) {
47426
47427     console.log( "Warning, getPoint() not implemented!" );
47428     return null;
47429
47430 };
47431
47432 // Get point at relative position in curve according to arc length
47433 // - u [0 .. 1]
47434
47435 THREE.Curve.prototype.getPointAt = function ( u ) {
47436
47437     var t = this.getUtoTmapping( u );
47438     return this.getPoint( t );
47439
47440 };
47441
47442 // Get sequence of points using getPoint( t )
47443
47444 THREE.Curve.prototype.getPoints = function ( divisions ) {
47445
47446     if ( !divisions ) divisions = 5;
47447
47448     var d, pts = [];
47449
47450     for ( d = 0; d <= divisions; d ++ ) {
47451
47452         pts.push( this.getPoint( d / divisions ) );
47453
47454     }
47455
47456     return pts;
47457
47458 };
47459
47460 // Get sequence of points using getPointAt( u )
47461
47462 THREE.Curve.prototype.getSpacedPoints = function ( divisions ) {
47463
47464     if ( !divisions ) divisions = 5;
47465
47466     var d, pts = [];
47467
47468     for ( d = 0; d <= divisions; d ++ ) {
47469
47470         pts.push( this.getPointAt( d / divisions ) );
47471
47472     }
47473
47474     return pts;
47475
47476 };
47477
47478 // Get total curve arc length
47479
47480 THREE.Curve.prototype.getLength = function () {
47481
47482     var lengths = this.getLengths();
47483     return lengths[ lengths.length - 1 ];
47484
47485 };
47486
47487 // Get list of cumulative segment lengths
47488
47489 THREE.Curve.prototype.getLengths = function ( divisions ) {
47490
47491     if ( !divisions ) divisions = (this.__arcLengthDivisions) ? (this.__arcLengthDivisions): 200;
47492
47493     if ( this.cacheArcLengths
47494         && ( this.cacheArcLengths.length == divisions + 1 )
47495         && !this.needsUpdate) {
47496
47497         //console.log( "cached", this.cacheArcLengths );
47498         return this.cacheArcLengths;
47499
47500     }
47501
47502     this.needsUpdate = false;
47503
47504     var cache = [];
47505     var current, last = this.getPoint( 0 );
47506     var p, sum = 0;
47507
47508     cache.push( 0 );
47509
47510     for ( p = 1; p <= divisions; p ++ ) {
47511
47512         current = this.getPoint ( p / divisions );
47513         sum += current.distanceTo( last );
47514         cache.push( sum );
47515         last = current;
47516
47517     }
47518
47519     this.cacheArcLengths = cache;
47520
47521     return cache; // { sums: cache, sum:sum }; Sum is in the last element.
47522
47523 };
47524
47525
47526 THREE.Curve.prototype.updateArcLengths = function() {
47527     this.needsUpdate = true;
47528     this.getLengths();
47529 };
47530
47531 // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equi distance
47532
47533 THREE.Curve.prototype.getUtoTmapping = function ( u, distance ) {
47534
47535     var arcLengths = this.getLengths();
47536
47537     var i = 0, il = arcLengths.length;
47538
47539     var targetArcLength; // The targeted u distance value to get
47540
47541     if ( distance ) {
47542
47543         targetArcLength = distance;
47544
47545     } else {
47546
47547         targetArcLength = u * arcLengths[ il - 1 ];
47548
47549     }
47550
47551     //var time = Date.now();
47552
47553     // binary search for the index with largest value smaller than target u distance
47554
47555     var low = 0, high = il - 1, comparison;
47556
47557     while ( low <= high ) {
47558
47559         i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats
47560
47561         comparison = arcLengths[ i ] - targetArcLength;
47562
47563         if ( comparison < 0 ) {
47564
47565             low = i + 1;
47566             continue;
47567
47568         } else if ( comparison > 0 ) {
47569
47570             high = i - 1;
47571             continue;
47572
47573         } else {
47574
47575             high = i;
47576             break;
47577
47578             // DONE
47579
47580         }
47581
47582     }
47583
47584     i = high;
47585
47586     //console.log('b' , i, low, high, Date.now()- time);
47587
47588     if ( arcLengths[ i ] == targetArcLength ) {
47589
47590         var t = i / ( il - 1 );
47591         return t;
47592
47593     }
47594
47595     // we could get finer grain at lengths, or use simple interpolatation between two points
47596
47597     var lengthBefore = arcLengths[ i ];
47598     var lengthAfter = arcLengths[ i + 1 ];
47599
47600     var segmentLength = lengthAfter - lengthBefore;
47601
47602     // determine where we are between the 'before' and 'after' points
47603
47604     var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
47605
47606     // add that fractional amount to t
47607
47608     var t = ( i + segmentFraction ) / ( il -1 );
47609
47610     return t;
47611
47612 };
47613
47614
47615 // In 2D space, there are actually 2 normal vectors,
47616 // and in 3D space, infinte
47617 // TODO this should be depreciated.
47618 THREE.Curve.prototype.getNormalVector = function( t ) {
47619
47620     var vec = this.getTangent( t );
47621
47622     return new THREE.Vector2( -vec.y , vec.x );
47623
47624 };
47625
47626 // Returns a unit vector tangent at t
47627 // In case any sub curve does not implement its tangent / normal finding,
47628 // we get 2 points with a small delta and find a gradient of the 2 points
47629 // which seems to make a reasonable approximation
47630
47631 THREE.Curve.prototype.getTangent = function( t ) {
47632
47633     var delta = 0.0001;
47634     var t1 = t - delta;
47635     var t2 = t + delta;
47636
47637     // Capping in case of danger
47638
47639     if ( t1 < 0 ) t1 = 0;
47640     if ( t2 > 1 ) t2 = 1;
47641
47642     var pt1 = this.getPoint( t1 );
47643     var pt2 = this.getPoint( t2 );
47644
47645     var vec = pt2.clone().subSelf(pt1);
47646     return vec.normalize();
47647
47648 };
47649
47650
47651 THREE.Curve.prototype.getTangentAt = function ( u ) {
47652
47653     var t = this.getUtoTmapping( u );
47654     return this.getTangent( t );
47655
47656 };
47657
47658 /**************************************************************
47659  *    Line
47660  **************************************************************/
47661
47662 THREE.LineCurve = function ( v1, v2 ) {
47663
47664     this.v1 = v1;
47665     this.v2 = v2;
47666
47667 };
47668
47669 THREE.LineCurve.prototype = Object.create( THREE.Curve.prototype );
47670
47671 THREE.LineCurve.prototype.getPoint = function ( t ) {
47672
47673     var point = this.v2.clone().subSelf(this.v1);
47674     point.multiplyScalar( t ).addSelf( this.v1 );
47675
47676     return point;
47677
47678 };
47679
47680 // Line curve is linear, so we can overwrite default getPointAt
47681
47682 THREE.LineCurve.prototype.getPointAt = function ( u ) {
47683
47684     return this.getPoint( u );
47685
47686 };
47687
47688 THREE.LineCurve.prototype.getTangent = function( t ) {
47689
47690     var tangent = this.v2.clone().subSelf(this.v1);
47691
47692     return tangent.normalize();
47693
47694 };
47695
47696 /**************************************************************
47697  *    Quadratic Bezier curve
47698  **************************************************************/
47699
47700
47701 THREE.QuadraticBezierCurve = function ( v0, v1, v2 ) {
47702
47703     this.v0 = v0;
47704     this.v1 = v1;
47705     this.v2 = v2;
47706
47707 };
47708
47709 THREE.QuadraticBezierCurve.prototype = Object.create( THREE.Curve.prototype );
47710
47711
47712 THREE.QuadraticBezierCurve.prototype.getPoint = function ( t ) {
47713
47714     var tx, ty;
47715
47716     tx = THREE.Shape.Utils.b2( t, this.v0.x, this.v1.x, this.v2.x );
47717     ty = THREE.Shape.Utils.b2( t, this.v0.y, this.v1.y, this.v2.y );
47718
47719     return new THREE.Vector2( tx, ty );
47720
47721 };
47722
47723
47724 THREE.QuadraticBezierCurve.prototype.getTangent = function( t ) {
47725
47726     var tx, ty;
47727
47728     tx = THREE.Curve.Utils.tangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x );
47729     ty = THREE.Curve.Utils.tangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y );
47730
47731     // returns unit vector
47732
47733     var tangent = new THREE.Vector2( tx, ty );
47734     tangent.normalize();
47735
47736     return tangent;
47737
47738 };
47739
47740
47741 /**************************************************************
47742  *    Cubic Bezier curve
47743  **************************************************************/
47744
47745 THREE.CubicBezierCurve = function ( v0, v1, v2, v3 ) {
47746
47747     this.v0 = v0;
47748     this.v1 = v1;
47749     this.v2 = v2;
47750     this.v3 = v3;
47751
47752 };
47753
47754 THREE.CubicBezierCurve.prototype = Object.create( THREE.Curve.prototype );
47755
47756 THREE.CubicBezierCurve.prototype.getPoint = function ( t ) {
47757
47758     var tx, ty;
47759
47760     tx = THREE.Shape.Utils.b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
47761     ty = THREE.Shape.Utils.b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
47762
47763     return new THREE.Vector2( tx, ty );
47764
47765 };
47766
47767 THREE.CubicBezierCurve.prototype.getTangent = function( t ) {
47768
47769     var tx, ty;
47770
47771     tx = THREE.Curve.Utils.tangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
47772     ty = THREE.Curve.Utils.tangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
47773
47774     var tangent = new THREE.Vector2( tx, ty );
47775     tangent.normalize();
47776
47777     return tangent;
47778
47779 };
47780
47781
47782 /**************************************************************
47783  *    Spline curve
47784  **************************************************************/
47785
47786 THREE.SplineCurve = function ( points /* array of Vector2 */ ) {
47787
47788     this.points = (points == undefined) ? [] : points;
47789
47790 };
47791
47792 THREE.SplineCurve.prototype = Object.create( THREE.Curve.prototype );
47793
47794 THREE.SplineCurve.prototype.getPoint = function ( t ) {
47795
47796     var v = new THREE.Vector2();
47797     var c = [];
47798     var points = this.points, point, intPoint, weight;
47799     point = ( points.length - 1 ) * t;
47800
47801     intPoint = Math.floor( point );
47802     weight = point - intPoint;
47803
47804     c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
47805     c[ 1 ] = intPoint;
47806     c[ 2 ] = intPoint  > points.length - 2 ? points.length -1 : intPoint + 1;
47807     c[ 3 ] = intPoint  > points.length - 3 ? points.length -1 : intPoint + 2;
47808
47809     v.x = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight );
47810     v.y = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight );
47811
47812     return v;
47813
47814 };
47815
47816 /**************************************************************
47817  *    Ellipse curve
47818  **************************************************************/
47819
47820 THREE.EllipseCurve = function ( aX, aY, xRadius, yRadius,
47821                             aStartAngle, aEndAngle,
47822                             aClockwise ) {
47823
47824     this.aX = aX;
47825     this.aY = aY;
47826
47827     this.xRadius = xRadius;
47828     this.yRadius = yRadius;
47829
47830     this.aStartAngle = aStartAngle;
47831     this.aEndAngle = aEndAngle;
47832
47833     this.aClockwise = aClockwise;
47834
47835 };
47836
47837 THREE.EllipseCurve.prototype = Object.create( THREE.Curve.prototype );
47838
47839 THREE.EllipseCurve.prototype.getPoint = function ( t ) {
47840
47841     var deltaAngle = this.aEndAngle - this.aStartAngle;
47842
47843     if ( !this.aClockwise ) {
47844
47845         t = 1 - t;
47846
47847     }
47848
47849     var angle = this.aStartAngle + t * deltaAngle;
47850
47851     var tx = this.aX + this.xRadius * Math.cos( angle );
47852     var ty = this.aY + this.yRadius * Math.sin( angle );
47853
47854     return new THREE.Vector2( tx, ty );
47855
47856 };
47857
47858 /**************************************************************
47859  *    Arc curve
47860  **************************************************************/
47861
47862 THREE.ArcCurve = function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
47863
47864     THREE.EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
47865 };
47866
47867 THREE.ArcCurve.prototype = Object.create( THREE.EllipseCurve.prototype );
47868
47869
47870 /**************************************************************
47871  *    Utils
47872  **************************************************************/
47873
47874 THREE.Curve.Utils = {
47875
47876     tangentQuadraticBezier: function ( t, p0, p1, p2 ) {
47877
47878         return 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );
47879
47880     },
47881
47882     // Puay Bing, thanks for helping with this derivative!
47883
47884     tangentCubicBezier: function (t, p0, p1, p2, p3 ) {
47885
47886         return -3 * p0 * (1 - t) * (1 - t)  +
47887             3 * p1 * (1 - t) * (1-t) - 6 *t *p1 * (1-t) +
47888             6 * t *  p2 * (1-t) - 3 * t * t * p2 +
47889             3 * t * t * p3;
47890     },
47891
47892
47893     tangentSpline: function ( t, p0, p1, p2, p3 ) {
47894
47895         // To check if my formulas are correct
47896
47897         var h00 = 6 * t * t - 6 * t;     // derived from 2t^3 − 3t^2 + 1
47898         var h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t
47899         var h01 = -6 * t * t + 6 * t;     // − 2t3 + 3t2
47900         var h11 = 3 * t * t - 2 * t;    // t3 − t2
47901
47902         return h00 + h10 + h01 + h11;
47903
47904     },
47905
47906     // Catmull-Rom
47907
47908     interpolate: function( p0, p1, p2, p3, t ) {
47909
47910         var v0 = ( p2 - p0 ) * 0.5;
47911         var v1 = ( p3 - p1 ) * 0.5;
47912         var t2 = t * t;
47913         var t3 = t * t2;
47914         return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
47915
47916     }
47917
47918 };
47919
47920
47921 // TODO: Transformation for Curves?
47922
47923 /**************************************************************
47924  *    3D Curves
47925  **************************************************************/
47926
47927 // A Factory method for creating new curve subclasses
47928
47929 THREE.Curve.create = function ( constructor, getPointFunc ) {
47930
47931     constructor.prototype = Object.create( THREE.Curve.prototype );
47932     constructor.prototype.getPoint = getPointFunc;
47933
47934     return constructor;
47935
47936 };
47937
47938
47939 /**************************************************************
47940  *    Line3D
47941  **************************************************************/
47942
47943 THREE.LineCurve3 = THREE.Curve.create(
47944
47945     function ( v1, v2 ) {
47946
47947         this.v1 = v1;
47948         this.v2 = v2;
47949
47950     },
47951
47952     function ( t ) {
47953
47954         var r = new THREE.Vector3();
47955
47956
47957         r.sub( this.v2, this.v1 ); // diff
47958         r.multiplyScalar( t );
47959         r.addSelf( this.v1 );
47960
47961         return r;
47962
47963     }
47964
47965 );
47966
47967
47968 /**************************************************************
47969  *    Quadratic Bezier 3D curve
47970  **************************************************************/
47971
47972 THREE.QuadraticBezierCurve3 = THREE.Curve.create(
47973
47974     function ( v0, v1, v2 ) {
47975
47976         this.v0 = v0;
47977         this.v1 = v1;
47978         this.v2 = v2;
47979
47980     },
47981
47982     function ( t ) {
47983
47984         var tx, ty, tz;
47985
47986         tx = THREE.Shape.Utils.b2( t, this.v0.x, this.v1.x, this.v2.x );
47987         ty = THREE.Shape.Utils.b2( t, this.v0.y, this.v1.y, this.v2.y );
47988         tz = THREE.Shape.Utils.b2( t, this.v0.z, this.v1.z, this.v2.z );
47989
47990         return new THREE.Vector3( tx, ty, tz );
47991
47992     }
47993
47994 );
47995
47996
47997
47998 /**************************************************************
47999  *    Cubic Bezier 3D curve
48000  **************************************************************/
48001
48002 THREE.CubicBezierCurve3 = THREE.Curve.create(
48003
48004     function ( v0, v1, v2, v3 ) {
48005
48006         this.v0 = v0;
48007         this.v1 = v1;
48008         this.v2 = v2;
48009         this.v3 = v3;
48010
48011     },
48012
48013     function ( t ) {
48014
48015         var tx, ty, tz;
48016
48017         tx = THREE.Shape.Utils.b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
48018         ty = THREE.Shape.Utils.b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
48019         tz = THREE.Shape.Utils.b3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z );
48020
48021         return new THREE.Vector3( tx, ty, tz );
48022
48023     }
48024
48025 );
48026
48027
48028
48029 /**************************************************************
48030  *    Spline 3D curve
48031  **************************************************************/
48032
48033
48034 THREE.SplineCurve3 = THREE.Curve.create(
48035
48036     function ( points /* array of Vector3 */) {
48037
48038         this.points = (points == undefined) ? [] : points;
48039
48040     },
48041
48042     function ( t ) {
48043
48044         var v = new THREE.Vector3();
48045         var c = [];
48046         var points = this.points, point, intPoint, weight;
48047         point = ( points.length - 1 ) * t;
48048
48049         intPoint = Math.floor( point );
48050         weight = point - intPoint;
48051
48052         c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
48053         c[ 1 ] = intPoint;
48054         c[ 2 ] = intPoint  > points.length - 2 ? points.length - 1 : intPoint + 1;
48055         c[ 3 ] = intPoint  > points.length - 3 ? points.length - 1 : intPoint + 2;
48056
48057         var pt0 = points[ c[0] ],
48058             pt1 = points[ c[1] ],
48059             pt2 = points[ c[2] ],
48060             pt3 = points[ c[3] ];
48061
48062         v.x = THREE.Curve.Utils.interpolate(pt0.x, pt1.x, pt2.x, pt3.x, weight);
48063         v.y = THREE.Curve.Utils.interpolate(pt0.y, pt1.y, pt2.y, pt3.y, weight);
48064         v.z = THREE.Curve.Utils.interpolate(pt0.z, pt1.z, pt2.z, pt3.z, weight);
48065
48066         return v;
48067
48068     }
48069
48070 );
48071
48072
48073 // THREE.SplineCurve3.prototype.getTangent = function(t) {
48074 //         var v = new THREE.Vector3();
48075 //         var c = [];
48076 //         var points = this.points, point, intPoint, weight;
48077 //         point = ( points.length - 1 ) * t;
48078
48079 //         intPoint = Math.floor( point );
48080 //         weight = point - intPoint;
48081
48082 //         c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
48083 //         c[ 1 ] = intPoint;
48084 //         c[ 2 ] = intPoint  > points.length - 2 ? points.length - 1 : intPoint + 1;
48085 //         c[ 3 ] = intPoint  > points.length - 3 ? points.length - 1 : intPoint + 2;
48086
48087 //         var pt0 = points[ c[0] ],
48088 //             pt1 = points[ c[1] ],
48089 //             pt2 = points[ c[2] ],
48090 //             pt3 = points[ c[3] ];
48091
48092 //     // t = weight;
48093 //     v.x = THREE.Curve.Utils.tangentSpline( t, pt0.x, pt1.x, pt2.x, pt3.x );
48094 //     v.y = THREE.Curve.Utils.tangentSpline( t, pt0.y, pt1.y, pt2.y, pt3.y );
48095 //     v.z = THREE.Curve.Utils.tangentSpline( t, pt0.z, pt1.z, pt2.z, pt3.z );
48096
48097 //     return v;
48098
48099 // }
48100
48101 /**************************************************************
48102  *    Closed Spline 3D curve
48103  **************************************************************/
48104
48105
48106 THREE.ClosedSplineCurve3 = THREE.Curve.create(
48107
48108     function ( points /* array of Vector3 */) {
48109
48110         this.points = (points == undefined) ? [] : points;
48111
48112     },
48113
48114     function ( t ) {
48115
48116         var v = new THREE.Vector3();
48117         var c = [];
48118         var points = this.points, point, intPoint, weight;
48119         point = ( points.length - 0 ) * t;
48120             // This needs to be from 0-length +1
48121
48122         intPoint = Math.floor( point );
48123         weight = point - intPoint;
48124
48125         intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;
48126         c[ 0 ] = ( intPoint - 1 ) % points.length;
48127         c[ 1 ] = ( intPoint ) % points.length;
48128         c[ 2 ] = ( intPoint + 1 ) % points.length;
48129         c[ 3 ] = ( intPoint + 2 ) % points.length;
48130
48131         v.x = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight );
48132         v.y = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight );
48133         v.z = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].z, points[ c[ 1 ] ].z, points[ c[ 2 ] ].z, points[ c[ 3 ] ].z, weight );
48134
48135         return v;
48136
48137     }
48138
48139 );
48140 /**
48141  * @author zz85 / http://www.lab4games.net/zz85/blog
48142  *
48143  **/
48144
48145 /**************************************************************
48146  *    Curved Path - a curve path is simply a array of connected
48147  *  curves, but retains the api of a curve
48148  **************************************************************/
48149
48150 THREE.CurvePath = function () {
48151
48152     this.curves = [];
48153     this.bends = [];
48154
48155     this.autoClose = false; // Automatically closes the path
48156 };
48157
48158 THREE.CurvePath.prototype = Object.create( THREE.Curve.prototype );
48159
48160 THREE.CurvePath.prototype.add = function ( curve ) {
48161
48162     this.curves.push( curve );
48163
48164 };
48165
48166 THREE.CurvePath.prototype.checkConnection = function() {
48167     // TODO
48168     // If the ending of curve is not connected to the starting
48169     // or the next curve, then, this is not a real path
48170 };
48171
48172 THREE.CurvePath.prototype.closePath = function() {
48173     // TODO Test
48174     // and verify for vector3 (needs to implement equals)
48175     // Add a line curve if start and end of lines are not connected
48176     var startPoint = this.curves[0].getPoint(0);
48177     var endPoint = this.curves[this.curves.length-1].getPoint(1);
48178
48179     if (!startPoint.equals(endPoint)) {
48180         this.curves.push( new THREE.LineCurve(endPoint, startPoint) );
48181     }
48182
48183 };
48184
48185 // To get accurate point with reference to
48186 // entire path distance at time t,
48187 // following has to be done:
48188
48189 // 1. Length of each sub path have to be known
48190 // 2. Locate and identify type of curve
48191 // 3. Get t for the curve
48192 // 4. Return curve.getPointAt(t')
48193
48194 THREE.CurvePath.prototype.getPoint = function( t ) {
48195
48196     var d = t * this.getLength();
48197     var curveLengths = this.getCurveLengths();
48198     var i = 0, diff, curve;
48199
48200     // To think about boundaries points.
48201
48202     while ( i < curveLengths.length ) {
48203
48204         if ( curveLengths[ i ] >= d ) {
48205
48206             diff = curveLengths[ i ] - d;
48207             curve = this.curves[ i ];
48208
48209             var u = 1 - diff / curve.getLength();
48210
48211             return curve.getPointAt( u );
48212
48213             break;
48214         }
48215
48216         i ++;
48217
48218     }
48219
48220     return null;
48221
48222     // loop where sum != 0, sum > d , sum+1 <d
48223
48224 };
48225
48226 /*
48227 THREE.CurvePath.prototype.getTangent = function( t ) {
48228 };*/
48229
48230
48231 // We cannot use the default THREE.Curve getPoint() with getLength() because in
48232 // THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
48233 // getPoint() depends on getLength
48234
48235 THREE.CurvePath.prototype.getLength = function() {
48236
48237     var lens = this.getCurveLengths();
48238     return lens[ lens.length - 1 ];
48239
48240 };
48241
48242 // Compute lengths and cache them
48243 // We cannot overwrite getLengths() because UtoT mapping uses it.
48244
48245 THREE.CurvePath.prototype.getCurveLengths = function() {
48246
48247     // We use cache values if curves and cache array are same length
48248
48249     if ( this.cacheLengths && this.cacheLengths.length == this.curves.length ) {
48250
48251         return this.cacheLengths;
48252
48253     };
48254
48255     // Get length of subsurve
48256     // Push sums into cached array
48257
48258     var lengths = [], sums = 0;
48259     var i, il = this.curves.length;
48260
48261     for ( i = 0; i < il; i ++ ) {
48262
48263         sums += this.curves[ i ].getLength();
48264         lengths.push( sums );
48265
48266     }
48267
48268     this.cacheLengths = lengths;
48269
48270     return lengths;
48271
48272 };
48273
48274
48275
48276 // Returns min and max coordinates, as well as centroid
48277
48278 THREE.CurvePath.prototype.getBoundingBox = function () {
48279
48280     var points = this.getPoints();
48281
48282     var maxX, maxY, maxZ;
48283     var minX, minY, minZ;
48284
48285     maxX = maxY = Number.NEGATIVE_INFINITY;
48286     minX = minY = Number.POSITIVE_INFINITY;
48287
48288     var p, i, il, sum;
48289
48290     var v3 = points[0] instanceof THREE.Vector3;
48291
48292     sum = v3 ? new THREE.Vector3() : new THREE.Vector2();
48293
48294     for ( i = 0, il = points.length; i < il; i ++ ) {
48295
48296         p = points[ i ];
48297
48298         if ( p.x > maxX ) maxX = p.x;
48299         else if ( p.x < minX ) minX = p.x;
48300
48301         if ( p.y > maxY ) maxY = p.y;
48302         else if ( p.y < minY ) minY = p.y;
48303
48304         if (v3) {
48305
48306             if ( p.z > maxZ ) maxZ = p.z;
48307             else if ( p.z < minZ ) minZ = p.z;
48308
48309         }
48310
48311         sum.addSelf( p );
48312
48313     }
48314
48315     var ret = {
48316
48317         minX: minX,
48318         minY: minY,
48319         maxX: maxX,
48320         maxY: maxY,
48321         centroid: sum.divideScalar( il )
48322
48323     };
48324
48325     if (v3) {
48326
48327         ret.maxZ = maxZ;
48328         ret.minZ = minZ;
48329
48330     }
48331
48332     return ret;
48333
48334 };
48335
48336 /**************************************************************
48337  *    Create Geometries Helpers
48338  **************************************************************/
48339
48340 /// Generate geometry from path points (for Line or ParticleSystem objects)
48341
48342 THREE.CurvePath.prototype.createPointsGeometry = function( divisions ) {
48343
48344     var pts = this.getPoints( divisions, true );
48345     return this.createGeometry( pts );
48346
48347 };
48348
48349 // Generate geometry from equidistance sampling along the path
48350
48351 THREE.CurvePath.prototype.createSpacedPointsGeometry = function( divisions ) {
48352
48353     var pts = this.getSpacedPoints( divisions, true );
48354     return this.createGeometry( pts );
48355
48356 };
48357
48358 THREE.CurvePath.prototype.createGeometry = function( points ) {
48359
48360     var geometry = new THREE.Geometry();
48361
48362     for ( var i = 0; i < points.length; i ++ ) {
48363
48364         geometry.vertices.push( new THREE.Vector3( points[ i ].x, points[ i ].y, points[ i ].z || 0) );
48365
48366     }
48367
48368     return geometry;
48369
48370 };
48371
48372
48373 /**************************************************************
48374  *    Bend / Wrap Helper Methods
48375  **************************************************************/
48376
48377 // Wrap path / Bend modifiers?
48378
48379 THREE.CurvePath.prototype.addWrapPath = function ( bendpath ) {
48380
48381     this.bends.push( bendpath );
48382
48383 };
48384
48385 THREE.CurvePath.prototype.getTransformedPoints = function( segments, bends ) {
48386
48387     var oldPts = this.getPoints( segments ); // getPoints getSpacedPoints
48388     var i, il;
48389
48390     if ( !bends ) {
48391
48392         bends = this.bends;
48393
48394     }
48395
48396     for ( i = 0, il = bends.length; i < il; i ++ ) {
48397
48398         oldPts = this.getWrapPoints( oldPts, bends[ i ] );
48399
48400     }
48401
48402     return oldPts;
48403
48404 };
48405
48406 THREE.CurvePath.prototype.getTransformedSpacedPoints = function( segments, bends ) {
48407
48408     var oldPts = this.getSpacedPoints( segments );
48409
48410     var i, il;
48411
48412     if ( !bends ) {
48413
48414         bends = this.bends;
48415
48416     }
48417
48418     for ( i = 0, il = bends.length; i < il; i ++ ) {
48419
48420         oldPts = this.getWrapPoints( oldPts, bends[ i ] );
48421
48422     }
48423
48424     return oldPts;
48425
48426 };
48427
48428 // This returns getPoints() bend/wrapped around the contour of a path.
48429 // Read http://www.planetclegg.com/projects/WarpingTextToSplines.html
48430
48431 THREE.CurvePath.prototype.getWrapPoints = function ( oldPts, path ) {
48432
48433     var bounds = this.getBoundingBox();
48434
48435     var i, il, p, oldX, oldY, xNorm;
48436
48437     for ( i = 0, il = oldPts.length; i < il; i ++ ) {
48438
48439         p = oldPts[ i ];
48440
48441         oldX = p.x;
48442         oldY = p.y;
48443
48444         xNorm = oldX / bounds.maxX;
48445
48446         // If using actual distance, for length > path, requires line extrusions
48447         //xNorm = path.getUtoTmapping(xNorm, oldX); // 3 styles. 1) wrap stretched. 2) wrap stretch by arc length 3) warp by actual distance
48448
48449         xNorm = path.getUtoTmapping( xNorm, oldX );
48450
48451         // check for out of bounds?
48452
48453         var pathPt = path.getPoint( xNorm );
48454         var normal = path.getNormalVector( xNorm ).multiplyScalar( oldY );
48455
48456         p.x = pathPt.x + normal.x;
48457         p.y = pathPt.y + normal.y;
48458
48459     }
48460
48461     return oldPts;
48462
48463 };
48464
48465 /**
48466  * @author alteredq / http://alteredqualia.com/
48467  */
48468
48469 THREE.Gyroscope = function () {
48470
48471     THREE.Object3D.call( this );
48472
48473 };
48474
48475 THREE.Gyroscope.prototype = Object.create( THREE.Object3D.prototype );
48476
48477 THREE.Gyroscope.prototype.updateMatrixWorld = function ( force ) {
48478
48479     this.matrixAutoUpdate && this.updateMatrix();
48480
48481     // update matrixWorld
48482
48483     if ( this.matrixWorldNeedsUpdate || force ) {
48484
48485         if ( this.parent ) {
48486
48487             this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
48488
48489             this.matrixWorld.decompose( this.translationWorld, this.rotationWorld, this.scaleWorld );
48490             this.matrix.decompose( this.translationObject, this.rotationObject, this.scaleObject );
48491
48492             this.matrixWorld.compose( this.translationWorld, this.rotationObject, this.scaleWorld );
48493
48494
48495         } else {
48496
48497             this.matrixWorld.copy( this.matrix );
48498
48499         }
48500
48501
48502         this.matrixWorldNeedsUpdate = false;
48503
48504         force = true;
48505
48506     }
48507
48508     // update children
48509
48510     for ( var i = 0, l = this.children.length; i < l; i ++ ) {
48511
48512         this.children[ i ].updateMatrixWorld( force );
48513
48514     }
48515
48516 };
48517
48518 THREE.Gyroscope.prototype.translationWorld = new THREE.Vector3();
48519 THREE.Gyroscope.prototype.translationObject = new THREE.Vector3();
48520 THREE.Gyroscope.prototype.rotationWorld = new THREE.Quaternion();
48521 THREE.Gyroscope.prototype.rotationObject = new THREE.Quaternion();
48522 THREE.Gyroscope.prototype.scaleWorld = new THREE.Vector3();
48523 THREE.Gyroscope.prototype.scaleObject = new THREE.Vector3();
48524
48525 /**
48526  * @author zz85 / http://www.lab4games.net/zz85/blog
48527  * Creates free form 2d path using series of points, lines or curves.
48528  *
48529  **/
48530
48531 THREE.Path = function ( points ) {
48532
48533     THREE.CurvePath.call(this);
48534
48535     this.actions = [];
48536
48537     if ( points ) {
48538
48539         this.fromPoints( points );
48540
48541     }
48542
48543 };
48544
48545 THREE.Path.prototype = Object.create( THREE.CurvePath.prototype );
48546
48547 THREE.PathActions = {
48548
48549     MOVE_TO: 'moveTo',
48550     LINE_TO: 'lineTo',
48551     QUADRATIC_CURVE_TO: 'quadraticCurveTo', // Bezier quadratic curve
48552     BEZIER_CURVE_TO: 'bezierCurveTo',         // Bezier cubic curve
48553     CSPLINE_THRU: 'splineThru',                // Catmull-rom spline
48554     ARC: 'arc',                                // Circle
48555     ELLIPSE: 'ellipse'
48556 };
48557
48558 // TODO Clean up PATH API
48559
48560 // Create path using straight lines to connect all points
48561 // - vectors: array of Vector2
48562
48563 THREE.Path.prototype.fromPoints = function ( vectors ) {
48564
48565     this.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );
48566
48567     for ( var v = 1, vlen = vectors.length; v < vlen; v ++ ) {
48568
48569         this.lineTo( vectors[ v ].x, vectors[ v ].y );
48570
48571     };
48572
48573 };
48574
48575 // startPath() endPath()?
48576
48577 THREE.Path.prototype.moveTo = function ( x, y ) {
48578
48579     var args = Array.prototype.slice.call( arguments );
48580     this.actions.push( { action: THREE.PathActions.MOVE_TO, args: args } );
48581
48582 };
48583
48584 THREE.Path.prototype.lineTo = function ( x, y ) {
48585
48586     var args = Array.prototype.slice.call( arguments );
48587
48588     var lastargs = this.actions[ this.actions.length - 1 ].args;
48589
48590     var x0 = lastargs[ lastargs.length - 2 ];
48591     var y0 = lastargs[ lastargs.length - 1 ];
48592
48593     var curve = new THREE.LineCurve( new THREE.Vector2( x0, y0 ), new THREE.Vector2( x, y ) );
48594     this.curves.push( curve );
48595
48596     this.actions.push( { action: THREE.PathActions.LINE_TO, args: args } );
48597
48598 };
48599
48600 THREE.Path.prototype.quadraticCurveTo = function( aCPx, aCPy, aX, aY ) {
48601
48602     var args = Array.prototype.slice.call( arguments );
48603
48604     var lastargs = this.actions[ this.actions.length - 1 ].args;
48605
48606     var x0 = lastargs[ lastargs.length - 2 ];
48607     var y0 = lastargs[ lastargs.length - 1 ];
48608
48609     var curve = new THREE.QuadraticBezierCurve( new THREE.Vector2( x0, y0 ),
48610                                                 new THREE.Vector2( aCPx, aCPy ),
48611                                                 new THREE.Vector2( aX, aY ) );
48612     this.curves.push( curve );
48613
48614     this.actions.push( { action: THREE.PathActions.QUADRATIC_CURVE_TO, args: args } );
48615
48616 };
48617
48618 THREE.Path.prototype.bezierCurveTo = function( aCP1x, aCP1y,
48619                                                aCP2x, aCP2y,
48620                                                aX, aY ) {
48621
48622     var args = Array.prototype.slice.call( arguments );
48623
48624     var lastargs = this.actions[ this.actions.length - 1 ].args;
48625
48626     var x0 = lastargs[ lastargs.length - 2 ];
48627     var y0 = lastargs[ lastargs.length - 1 ];
48628
48629     var curve = new THREE.CubicBezierCurve( new THREE.Vector2( x0, y0 ),
48630                                             new THREE.Vector2( aCP1x, aCP1y ),
48631                                             new THREE.Vector2( aCP2x, aCP2y ),
48632                                             new THREE.Vector2( aX, aY ) );
48633     this.curves.push( curve );
48634
48635     this.actions.push( { action: THREE.PathActions.BEZIER_CURVE_TO, args: args } );
48636
48637 };
48638
48639 THREE.Path.prototype.splineThru = function( pts /*Array of Vector*/ ) {
48640
48641     var args = Array.prototype.slice.call( arguments );
48642     var lastargs = this.actions[ this.actions.length - 1 ].args;
48643
48644     var x0 = lastargs[ lastargs.length - 2 ];
48645     var y0 = lastargs[ lastargs.length - 1 ];
48646 //---
48647     var npts = [ new THREE.Vector2( x0, y0 ) ];
48648     Array.prototype.push.apply( npts, pts );
48649
48650     var curve = new THREE.SplineCurve( npts );
48651     this.curves.push( curve );
48652
48653     this.actions.push( { action: THREE.PathActions.CSPLINE_THRU, args: args } );
48654
48655 };
48656
48657 // FUTURE: Change the API or follow canvas API?
48658
48659 THREE.Path.prototype.arc = function ( aX, aY, aRadius,
48660                                       aStartAngle, aEndAngle, aClockwise ) {
48661
48662     var lastargs = this.actions[ this.actions.length - 1].args;
48663     var x0 = lastargs[ lastargs.length - 2 ];
48664     var y0 = lastargs[ lastargs.length - 1 ];
48665
48666     this.absarc(aX + x0, aY + y0, aRadius,
48667         aStartAngle, aEndAngle, aClockwise );
48668
48669  };
48670
48671  THREE.Path.prototype.absarc = function ( aX, aY, aRadius,
48672                                       aStartAngle, aEndAngle, aClockwise ) {
48673     this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise);
48674  };
48675
48676 THREE.Path.prototype.ellipse = function ( aX, aY, xRadius, yRadius,
48677                                       aStartAngle, aEndAngle, aClockwise ) {
48678
48679     var lastargs = this.actions[ this.actions.length - 1].args;
48680     var x0 = lastargs[ lastargs.length - 2 ];
48681     var y0 = lastargs[ lastargs.length - 1 ];
48682
48683     this.absellipse(aX + x0, aY + y0, xRadius, yRadius,
48684         aStartAngle, aEndAngle, aClockwise );
48685
48686  };
48687
48688
48689 THREE.Path.prototype.absellipse = function ( aX, aY, xRadius, yRadius,
48690                                       aStartAngle, aEndAngle, aClockwise ) {
48691
48692     var args = Array.prototype.slice.call( arguments );
48693     var curve = new THREE.EllipseCurve( aX, aY, xRadius, yRadius,
48694                                     aStartAngle, aEndAngle, aClockwise );
48695     this.curves.push( curve );
48696
48697     var lastPoint = curve.getPoint(aClockwise ? 1 : 0);
48698     args.push(lastPoint.x);
48699     args.push(lastPoint.y);
48700
48701     this.actions.push( { action: THREE.PathActions.ELLIPSE, args: args } );
48702
48703  };
48704
48705 THREE.Path.prototype.getSpacedPoints = function ( divisions, closedPath ) {
48706
48707     if ( ! divisions ) divisions = 40;
48708
48709     var points = [];
48710
48711     for ( var i = 0; i < divisions; i ++ ) {
48712
48713         points.push( this.getPoint( i / divisions ) );
48714
48715         //if( !this.getPoint( i / divisions ) ) throw "DIE";
48716
48717     }
48718
48719     // if ( closedPath ) {
48720     //
48721     //     points.push( points[ 0 ] );
48722     //
48723     // }
48724
48725     return points;
48726
48727 };
48728
48729 /* Return an array of vectors based on contour of the path */
48730
48731 THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
48732
48733     if (this.useSpacedPoints) {
48734         console.log('tata');
48735         return this.getSpacedPoints( divisions, closedPath );
48736     }
48737
48738     divisions = divisions || 12;
48739
48740     var points = [];
48741
48742     var i, il, item, action, args;
48743     var cpx, cpy, cpx2, cpy2, cpx1, cpy1, cpx0, cpy0,
48744         laste, j,
48745         t, tx, ty;
48746
48747     for ( i = 0, il = this.actions.length; i < il; i ++ ) {
48748
48749         item = this.actions[ i ];
48750
48751         action = item.action;
48752         args = item.args;
48753
48754         switch( action ) {
48755
48756         case THREE.PathActions.MOVE_TO:
48757
48758             points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) );
48759
48760             break;
48761
48762         case THREE.PathActions.LINE_TO:
48763
48764             points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) );
48765
48766             break;
48767
48768         case THREE.PathActions.QUADRATIC_CURVE_TO:
48769
48770             cpx  = args[ 2 ];
48771             cpy  = args[ 3 ];
48772
48773             cpx1 = args[ 0 ];
48774             cpy1 = args[ 1 ];
48775
48776             if ( points.length > 0 ) {
48777
48778                 laste = points[ points.length - 1 ];
48779
48780                 cpx0 = laste.x;
48781                 cpy0 = laste.y;
48782
48783             } else {
48784
48785                 laste = this.actions[ i - 1 ].args;
48786
48787                 cpx0 = laste[ laste.length - 2 ];
48788                 cpy0 = laste[ laste.length - 1 ];
48789
48790             }
48791
48792             for ( j = 1; j <= divisions; j ++ ) {
48793
48794                 t = j / divisions;
48795
48796                 tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx );
48797                 ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy );
48798
48799                 points.push( new THREE.Vector2( tx, ty ) );
48800
48801               }
48802
48803             break;
48804
48805         case THREE.PathActions.BEZIER_CURVE_TO:
48806
48807             cpx  = args[ 4 ];
48808             cpy  = args[ 5 ];
48809
48810             cpx1 = args[ 0 ];
48811             cpy1 = args[ 1 ];
48812
48813             cpx2 = args[ 2 ];
48814             cpy2 = args[ 3 ];
48815
48816             if ( points.length > 0 ) {
48817
48818                 laste = points[ points.length - 1 ];
48819
48820                 cpx0 = laste.x;
48821                 cpy0 = laste.y;
48822
48823             } else {
48824
48825                 laste = this.actions[ i - 1 ].args;
48826
48827                 cpx0 = laste[ laste.length - 2 ];
48828                 cpy0 = laste[ laste.length - 1 ];
48829
48830             }
48831
48832
48833             for ( j = 1; j <= divisions; j ++ ) {
48834
48835                 t = j / divisions;
48836
48837                 tx = THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx );
48838                 ty = THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy );
48839
48840                 points.push( new THREE.Vector2( tx, ty ) );
48841
48842             }
48843
48844             break;
48845
48846         case THREE.PathActions.CSPLINE_THRU:
48847
48848             laste = this.actions[ i - 1 ].args;
48849
48850             var last = new THREE.Vector2( laste[ laste.length - 2 ], laste[ laste.length - 1 ] );
48851             var spts = [ last ];
48852
48853             var n = divisions * args[ 0 ].length;
48854
48855             spts = spts.concat( args[ 0 ] );
48856
48857             var spline = new THREE.SplineCurve( spts );
48858
48859             for ( j = 1; j <= n; j ++ ) {
48860
48861                 points.push( spline.getPointAt( j / n ) ) ;
48862
48863             }
48864
48865             break;
48866
48867         case THREE.PathActions.ARC:
48868
48869             var aX = args[ 0 ], aY = args[ 1 ],
48870                 aRadius = args[ 2 ],
48871                 aStartAngle = args[ 3 ], aEndAngle = args[ 4 ],
48872                 aClockwise = !!args[ 5 ];
48873
48874             var deltaAngle = aEndAngle - aStartAngle;
48875             var angle;
48876             var tdivisions = divisions * 2;
48877
48878             for ( j = 1; j <= tdivisions; j ++ ) {
48879
48880                 t = j / tdivisions;
48881
48882                 if ( ! aClockwise ) {
48883
48884                     t = 1 - t;
48885
48886                 }
48887
48888                 angle = aStartAngle + t * deltaAngle;
48889
48890                 tx = aX + aRadius * Math.cos( angle );
48891                 ty = aY + aRadius * Math.sin( angle );
48892
48893                 //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty);
48894
48895                 points.push( new THREE.Vector2( tx, ty ) );
48896
48897             }
48898
48899             //console.log(points);
48900
48901           break;
48902
48903         case THREE.PathActions.ELLIPSE:
48904
48905             var aX = args[ 0 ], aY = args[ 1 ],
48906                 xRadius = args[ 2 ],
48907                 yRadius = args[ 3 ],
48908                 aStartAngle = args[ 4 ], aEndAngle = args[ 5 ],
48909                 aClockwise = !!args[ 6 ];
48910
48911
48912             var deltaAngle = aEndAngle - aStartAngle;
48913             var angle;
48914             var tdivisions = divisions * 2;
48915
48916             for ( j = 1; j <= tdivisions; j ++ ) {
48917
48918                 t = j / tdivisions;
48919
48920                 if ( ! aClockwise ) {
48921
48922                     t = 1 - t;
48923
48924                 }
48925
48926                 angle = aStartAngle + t * deltaAngle;
48927
48928                 tx = aX + xRadius * Math.cos( angle );
48929                 ty = aY + yRadius * Math.sin( angle );
48930
48931                 //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty);
48932
48933                 points.push( new THREE.Vector2( tx, ty ) );
48934
48935             }
48936
48937             //console.log(points);
48938
48939           break;
48940
48941         } // end switch
48942
48943     }
48944
48945
48946
48947     // Normalize to remove the closing point by default.
48948     var lastPoint = points[ points.length - 1];
48949     var EPSILON = 0.0000000001;
48950     if ( Math.abs(lastPoint.x - points[ 0 ].x) < EPSILON &&
48951              Math.abs(lastPoint.y - points[ 0 ].y) < EPSILON)
48952         points.splice( points.length - 1, 1);
48953     if ( closedPath ) {
48954
48955         points.push( points[ 0 ] );
48956
48957     }
48958
48959     return points;
48960
48961 };
48962
48963 // Breaks path into shapes
48964
48965 THREE.Path.prototype.toShapes = function() {
48966
48967     var i, il, item, action, args;
48968
48969     var subPaths = [], lastPath = new THREE.Path();
48970
48971     for ( i = 0, il = this.actions.length; i < il; i ++ ) {
48972
48973         item = this.actions[ i ];
48974
48975         args = item.args;
48976         action = item.action;
48977
48978         if ( action == THREE.PathActions.MOVE_TO ) {
48979
48980             if ( lastPath.actions.length != 0 ) {
48981
48982                 subPaths.push( lastPath );
48983                 lastPath = new THREE.Path();
48984
48985             }
48986
48987         }
48988
48989         lastPath[ action ].apply( lastPath, args );
48990
48991     }
48992
48993     if ( lastPath.actions.length != 0 ) {
48994
48995         subPaths.push( lastPath );
48996
48997     }
48998
48999     // console.log(subPaths);
49000
49001     if ( subPaths.length == 0 ) return [];
49002
49003     var tmpPath, tmpShape, shapes = [];
49004
49005     var holesFirst = !THREE.Shape.Utils.isClockWise( subPaths[ 0 ].getPoints() );
49006     // console.log("Holes first", holesFirst);
49007
49008     if ( subPaths.length == 1) {
49009         tmpPath = subPaths[0];
49010         tmpShape = new THREE.Shape();
49011         tmpShape.actions = tmpPath.actions;
49012         tmpShape.curves = tmpPath.curves;
49013         shapes.push( tmpShape );
49014         return shapes;
49015     };
49016
49017     if ( holesFirst ) {
49018
49019         tmpShape = new THREE.Shape();
49020
49021         for ( i = 0, il = subPaths.length; i < il; i ++ ) {
49022
49023             tmpPath = subPaths[ i ];
49024
49025             if ( THREE.Shape.Utils.isClockWise( tmpPath.getPoints() ) ) {
49026
49027                 tmpShape.actions = tmpPath.actions;
49028                 tmpShape.curves = tmpPath.curves;
49029
49030                 shapes.push( tmpShape );
49031                 tmpShape = new THREE.Shape();
49032
49033                 //console.log('cw', i);
49034
49035             } else {
49036
49037                 tmpShape.holes.push( tmpPath );
49038
49039                 //console.log('ccw', i);
49040
49041             }
49042
49043         }
49044
49045     } else {
49046
49047         // Shapes first
49048
49049         for ( i = 0, il = subPaths.length; i < il; i ++ ) {
49050
49051             tmpPath = subPaths[ i ];
49052
49053             if ( THREE.Shape.Utils.isClockWise( tmpPath.getPoints() ) ) {
49054
49055
49056                 if ( tmpShape ) shapes.push( tmpShape );
49057
49058                 tmpShape = new THREE.Shape();
49059                 tmpShape.actions = tmpPath.actions;
49060                 tmpShape.curves = tmpPath.curves;
49061
49062             } else {
49063
49064                 tmpShape.holes.push( tmpPath );
49065
49066             }
49067
49068         }
49069
49070         shapes.push( tmpShape );
49071
49072     }
49073
49074     //console.log("shape", shapes);
49075
49076     return shapes;
49077
49078 };
49079 /**
49080  * @author zz85 / http://www.lab4games.net/zz85/blog
49081  * Defines a 2d shape plane using paths.
49082  **/
49083
49084 // STEP 1 Create a path.
49085 // STEP 2 Turn path into shape.
49086 // STEP 3 ExtrudeGeometry takes in Shape/Shapes
49087 // STEP 3a - Extract points from each shape, turn to vertices
49088 // STEP 3b - Triangulate each shape, add faces.
49089
49090 THREE.Shape = function ( ) {
49091
49092     THREE.Path.apply( this, arguments );
49093     this.holes = [];
49094
49095 };
49096
49097 THREE.Shape.prototype = Object.create( THREE.Path.prototype );
49098
49099 // Convenience method to return ExtrudeGeometry
49100
49101 THREE.Shape.prototype.extrude = function ( options ) {
49102
49103     var extruded = new THREE.ExtrudeGeometry( this, options );
49104     return extruded;
49105
49106 };
49107
49108 // Convenience method to return ShapeGeometry
49109
49110 THREE.Shape.prototype.makeGeometry = function ( options ) {
49111
49112     var geometry = new THREE.ShapeGeometry( this, options );
49113     return geometry;
49114
49115 };
49116
49117 // Get points of holes
49118
49119 THREE.Shape.prototype.getPointsHoles = function ( divisions ) {
49120
49121     var i, il = this.holes.length, holesPts = [];
49122
49123     for ( i = 0; i < il; i ++ ) {
49124
49125         holesPts[ i ] = this.holes[ i ].getTransformedPoints( divisions, this.bends );
49126
49127     }
49128
49129     return holesPts;
49130
49131 };
49132
49133 // Get points of holes (spaced by regular distance)
49134
49135 THREE.Shape.prototype.getSpacedPointsHoles = function ( divisions ) {
49136
49137     var i, il = this.holes.length, holesPts = [];
49138
49139     for ( i = 0; i < il; i ++ ) {
49140
49141         holesPts[ i ] = this.holes[ i ].getTransformedSpacedPoints( divisions, this.bends );
49142
49143     }
49144
49145     return holesPts;
49146
49147 };
49148
49149
49150 // Get points of shape and holes (keypoints based on segments parameter)
49151
49152 THREE.Shape.prototype.extractAllPoints = function ( divisions ) {
49153
49154     return {
49155
49156         shape: this.getTransformedPoints( divisions ),
49157         holes: this.getPointsHoles( divisions )
49158
49159     };
49160
49161 };
49162
49163 THREE.Shape.prototype.extractPoints = function ( divisions ) {
49164
49165     if (this.useSpacedPoints) {
49166         return this.extractAllSpacedPoints(divisions);
49167     }
49168
49169     return this.extractAllPoints(divisions);
49170
49171 };
49172
49173 //
49174 // THREE.Shape.prototype.extractAllPointsWithBend = function ( divisions, bend ) {
49175 //
49176 //     return {
49177 //
49178 //         shape: this.transform( bend, divisions ),
49179 //         holes: this.getPointsHoles( divisions, bend )
49180 //
49181 //     };
49182 //
49183 // };
49184
49185 // Get points of shape and holes (spaced by regular distance)
49186
49187 THREE.Shape.prototype.extractAllSpacedPoints = function ( divisions ) {
49188
49189     return {
49190
49191         shape: this.getTransformedSpacedPoints( divisions ),
49192         holes: this.getSpacedPointsHoles( divisions )
49193
49194     };
49195
49196 };
49197
49198 /**************************************************************
49199  *    Utils
49200  **************************************************************/
49201
49202 THREE.Shape.Utils = {
49203
49204     /*
49205         contour - array of vector2 for contour
49206         holes   - array of array of vector2
49207     */
49208
49209     removeHoles: function ( contour, holes ) {
49210
49211         var shape = contour.concat(); // work on this shape
49212         var allpoints = shape.concat();
49213
49214         /* For each isolated shape, find the closest points and break to the hole to allow triangulation */
49215
49216
49217         var prevShapeVert, nextShapeVert,
49218             prevHoleVert, nextHoleVert,
49219             holeIndex, shapeIndex,
49220             shapeId, shapeGroup,
49221             h, h2,
49222             hole, shortest, d,
49223             p, pts1, pts2,
49224             tmpShape1, tmpShape2,
49225             tmpHole1, tmpHole2,
49226             verts = [];
49227
49228         for ( h = 0; h < holes.length; h ++ ) {
49229
49230             hole = holes[ h ];
49231
49232             /*
49233             shapeholes[ h ].concat(); // preserves original
49234             holes.push( hole );
49235             */
49236
49237             Array.prototype.push.apply( allpoints, hole );
49238
49239             shortest = Number.POSITIVE_INFINITY;
49240
49241
49242             // Find the shortest pair of pts between shape and hole
49243
49244             // Note: Actually, I'm not sure now if we could optimize this to be faster than O(m*n)
49245             // Using distanceToSquared() intead of distanceTo() should speed a little
49246             // since running square roots operations are reduced.
49247
49248             for ( h2 = 0; h2 < hole.length; h2 ++ ) {
49249
49250                 pts1 = hole[ h2 ];
49251                 var dist = [];
49252
49253                 for ( p = 0; p < shape.length; p++ ) {
49254
49255                     pts2 = shape[ p ];
49256                     d = pts1.distanceToSquared( pts2 );
49257                     dist.push( d );
49258
49259                     if ( d < shortest ) {
49260
49261                         shortest = d;
49262                         holeIndex = h2;
49263                         shapeIndex = p;
49264
49265                     }
49266
49267                 }
49268
49269             }
49270
49271             //console.log("shortest", shortest, dist);
49272
49273             prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
49274             prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
49275
49276             var areaapts = [
49277
49278                 hole[ holeIndex ],
49279                 shape[ shapeIndex ],
49280                 shape[ prevShapeVert ]
49281
49282             ];
49283
49284             var areaa = THREE.FontUtils.Triangulate.area( areaapts );
49285
49286             var areabpts = [
49287
49288                 hole[ holeIndex ],
49289                 hole[ prevHoleVert ],
49290                 shape[ shapeIndex ]
49291
49292             ];
49293
49294             var areab = THREE.FontUtils.Triangulate.area( areabpts );
49295
49296             var shapeOffset = 1;
49297             var holeOffset = -1;
49298
49299             var oldShapeIndex = shapeIndex, oldHoleIndex = holeIndex;
49300             shapeIndex += shapeOffset;
49301             holeIndex += holeOffset;
49302
49303             if ( shapeIndex < 0 ) { shapeIndex += shape.length;  }
49304             shapeIndex %= shape.length;
49305
49306             if ( holeIndex < 0 ) { holeIndex += hole.length;  }
49307             holeIndex %= hole.length;
49308
49309             prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
49310             prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
49311
49312             areaapts = [
49313
49314                 hole[ holeIndex ],
49315                 shape[ shapeIndex ],
49316                 shape[ prevShapeVert ]
49317
49318             ];
49319
49320             var areaa2 = THREE.FontUtils.Triangulate.area( areaapts );
49321
49322             areabpts = [
49323
49324                 hole[ holeIndex ],
49325                 hole[ prevHoleVert ],
49326                 shape[ shapeIndex ]
49327
49328             ];
49329
49330             var areab2 = THREE.FontUtils.Triangulate.area( areabpts );
49331             //console.log(areaa,areab ,areaa2,areab2, ( areaa + areab ),  ( areaa2 + areab2 ));
49332
49333             if ( ( areaa + areab ) > ( areaa2 + areab2 ) ) {
49334
49335                 // In case areas are not correct.
49336                 //console.log("USE THIS");
49337
49338                 shapeIndex = oldShapeIndex;
49339                 holeIndex = oldHoleIndex ;
49340
49341                 if ( shapeIndex < 0 ) { shapeIndex += shape.length;  }
49342                 shapeIndex %= shape.length;
49343
49344                 if ( holeIndex < 0 ) { holeIndex += hole.length;  }
49345                 holeIndex %= hole.length;
49346
49347                 prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
49348                 prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
49349
49350             } else {
49351
49352                 //console.log("USE THAT ")
49353
49354             }
49355
49356             tmpShape1 = shape.slice( 0, shapeIndex );
49357             tmpShape2 = shape.slice( shapeIndex );
49358             tmpHole1 = hole.slice( holeIndex );
49359             tmpHole2 = hole.slice( 0, holeIndex );
49360
49361             // Should check orders here again?
49362
49363             var trianglea = [
49364
49365                 hole[ holeIndex ],
49366                 shape[ shapeIndex ],
49367                 shape[ prevShapeVert ]
49368
49369             ];
49370
49371             var triangleb = [
49372
49373                 hole[ holeIndex ] ,
49374                 hole[ prevHoleVert ],
49375                 shape[ shapeIndex ]
49376
49377             ];
49378
49379             verts.push( trianglea );
49380             verts.push( triangleb );
49381
49382             shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );
49383
49384         }
49385
49386         return {
49387
49388             shape:shape,         /* shape with no holes */
49389             isolatedPts: verts, /* isolated faces */
49390             allpoints: allpoints
49391
49392         }
49393
49394
49395     },
49396
49397     triangulateShape: function ( contour, holes ) {
49398
49399         var shapeWithoutHoles = THREE.Shape.Utils.removeHoles( contour, holes );
49400
49401         var shape = shapeWithoutHoles.shape,
49402             allpoints = shapeWithoutHoles.allpoints,
49403             isolatedPts = shapeWithoutHoles.isolatedPts;
49404
49405         var triangles = THREE.FontUtils.Triangulate( shape, false ); // True returns indices for points of spooled shape
49406
49407         // To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.
49408
49409         //console.log( "triangles",triangles, triangles.length );
49410         //console.log( "allpoints",allpoints, allpoints.length );
49411
49412         var i, il, f, face,
49413             key, index,
49414             allPointsMap = {},
49415             isolatedPointsMap = {};
49416
49417         // prepare all points map
49418
49419         for ( i = 0, il = allpoints.length; i < il; i ++ ) {
49420
49421             key = allpoints[ i ].x + ":" + allpoints[ i ].y;
49422
49423             if ( allPointsMap[ key ] !== undefined ) {
49424
49425                 console.log( "Duplicate point", key );
49426
49427             }
49428
49429             allPointsMap[ key ] = i;
49430
49431         }
49432
49433         // check all face vertices against all points map
49434
49435         for ( i = 0, il = triangles.length; i < il; i ++ ) {
49436
49437             face = triangles[ i ];
49438
49439             for ( f = 0; f < 3; f ++ ) {
49440
49441                 key = face[ f ].x + ":" + face[ f ].y;
49442
49443                 index = allPointsMap[ key ];
49444
49445                 if ( index !== undefined ) {
49446
49447                     face[ f ] = index;
49448
49449                 }
49450
49451             }
49452
49453         }
49454
49455         // check isolated points vertices against all points map
49456
49457         for ( i = 0, il = isolatedPts.length; i < il; i ++ ) {
49458
49459             face = isolatedPts[ i ];
49460
49461             for ( f = 0; f < 3; f ++ ) {
49462
49463                 key = face[ f ].x + ":" + face[ f ].y;
49464
49465                 index = allPointsMap[ key ];
49466
49467                 if ( index !== undefined ) {
49468
49469                     face[ f ] = index;
49470
49471                 }
49472
49473             }
49474
49475         }
49476
49477         return triangles.concat( isolatedPts );
49478
49479     }, // end triangulate shapes
49480
49481     /*
49482     triangulate2 : function( pts, holes ) {
49483
49484         // For use with Poly2Tri.js
49485
49486         var allpts = pts.concat();
49487         var shape = [];
49488         for (var p in pts) {
49489             shape.push(new js.poly2tri.Point(pts[p].x, pts[p].y));
49490         }
49491
49492         var swctx = new js.poly2tri.SweepContext(shape);
49493
49494         for (var h in holes) {
49495             var aHole = holes[h];
49496             var newHole = []
49497             for (i in aHole) {
49498                 newHole.push(new js.poly2tri.Point(aHole[i].x, aHole[i].y));
49499                 allpts.push(aHole[i]);
49500             }
49501             swctx.AddHole(newHole);
49502         }
49503
49504         var find;
49505         var findIndexForPt = function (pt) {
49506             find = new THREE.Vector2(pt.x, pt.y);
49507             var p;
49508             for (p=0, pl = allpts.length; p<pl; p++) {
49509                 if (allpts[p].equals(find)) return p;
49510             }
49511             return -1;
49512         };
49513
49514         // triangulate
49515         js.poly2tri.sweep.Triangulate(swctx);
49516
49517         var triangles =  swctx.GetTriangles();
49518         var tr ;
49519         var facesPts = [];
49520         for (var t in triangles) {
49521             tr =  triangles[t];
49522             facesPts.push([
49523                 findIndexForPt(tr.GetPoint(0)),
49524                 findIndexForPt(tr.GetPoint(1)),
49525                 findIndexForPt(tr.GetPoint(2))
49526                     ]);
49527         }
49528
49529
49530     //    console.log(facesPts);
49531     //    console.log("triangles", triangles.length, triangles);
49532
49533         // Returns array of faces with 3 element each
49534     return facesPts;
49535     },
49536 */
49537
49538     isClockWise: function ( pts ) {
49539
49540         return THREE.FontUtils.Triangulate.area( pts ) < 0;
49541
49542     },
49543
49544     // Bezier Curves formulas obtained from
49545     // http://en.wikipedia.org/wiki/B%C3%A9zier_curve
49546
49547     // Quad Bezier Functions
49548
49549     b2p0: function ( t, p ) {
49550
49551         var k = 1 - t;
49552         return k * k * p;
49553
49554     },
49555
49556     b2p1: function ( t, p ) {
49557
49558         return 2 * ( 1 - t ) * t * p;
49559
49560     },
49561
49562     b2p2: function ( t, p ) {
49563
49564         return t * t * p;
49565
49566     },
49567
49568     b2: function ( t, p0, p1, p2 ) {
49569
49570         return this.b2p0( t, p0 ) + this.b2p1( t, p1 ) + this.b2p2( t, p2 );
49571
49572     },
49573
49574     // Cubic Bezier Functions
49575
49576     b3p0: function ( t, p ) {
49577
49578         var k = 1 - t;
49579         return k * k * k * p;
49580
49581     },
49582
49583     b3p1: function ( t, p ) {
49584
49585         var k = 1 - t;
49586         return 3 * k * k * t * p;
49587
49588     },
49589
49590     b3p2: function ( t, p ) {
49591
49592         var k = 1 - t;
49593         return 3 * k * t * t * p;
49594
49595     },
49596
49597     b3p3: function ( t, p ) {
49598
49599         return t * t * t * p;
49600
49601     },
49602
49603     b3: function ( t, p0, p1, p2, p3 ) {
49604
49605         return this.b3p0( t, p0 ) + this.b3p1( t, p1 ) + this.b3p2( t, p2 ) +  this.b3p3( t, p3 );
49606
49607     }
49608
49609 };
49610
49611 /**
49612  * @author mikael emtinger / http://gomo.se/
49613  */
49614
49615 THREE.AnimationHandler = (function() {
49616
49617     var playing = [];
49618     var library = {};
49619     var that    = {};
49620
49621
49622     //--- update ---
49623
49624     that.update = function( deltaTimeMS ) {
49625
49626         for( var i = 0; i < playing.length; i ++ )
49627             playing[ i ].update( deltaTimeMS );
49628
49629     };
49630
49631
49632     //--- add ---
49633
49634     that.addToUpdate = function( animation ) {
49635
49636         if ( playing.indexOf( animation ) === -1 )
49637             playing.push( animation );
49638
49639     };
49640
49641
49642     //--- remove ---
49643
49644     that.removeFromUpdate = function( animation ) {
49645
49646         var index = playing.indexOf( animation );
49647
49648         if( index !== -1 )
49649             playing.splice( index, 1 );
49650
49651     };
49652
49653
49654     //--- add ---
49655
49656     that.add = function( data ) {
49657
49658         if ( library[ data.name ] !== undefined )
49659             console.log( "THREE.AnimationHandler.add: Warning! " + data.name + " already exists in library. Overwriting." );
49660
49661         library[ data.name ] = data;
49662         initData( data );
49663
49664     };
49665
49666
49667     //--- get ---
49668
49669     that.get = function( name ) {
49670
49671         if ( typeof name === "string" ) {
49672
49673             if ( library[ name ] ) {
49674
49675                 return library[ name ];
49676
49677             } else {
49678
49679                 console.log( "THREE.AnimationHandler.get: Couldn't find animation " + name );
49680                 return null;
49681
49682             }
49683
49684         } else {
49685
49686             // todo: add simple tween library
49687
49688         }
49689
49690     };
49691
49692     //--- parse ---
49693
49694     that.parse = function( root ) {
49695
49696         // setup hierarchy
49697
49698         var hierarchy = [];
49699
49700         if ( root instanceof THREE.SkinnedMesh ) {
49701
49702             for( var b = 0; b < root.bones.length; b++ ) {
49703
49704                 hierarchy.push( root.bones[ b ] );
49705
49706             }
49707
49708         } else {
49709
49710             parseRecurseHierarchy( root, hierarchy );
49711
49712         }
49713
49714         return hierarchy;
49715
49716     };
49717
49718     var parseRecurseHierarchy = function( root, hierarchy ) {
49719
49720         hierarchy.push( root );
49721
49722         for( var c = 0; c < root.children.length; c++ )
49723             parseRecurseHierarchy( root.children[ c ], hierarchy );
49724
49725     }
49726
49727
49728     //--- init data ---
49729
49730     var initData = function( data ) {
49731
49732         if( data.initialized === true )
49733             return;
49734
49735
49736         // loop through all keys
49737
49738         for( var h = 0; h < data.hierarchy.length; h ++ ) {
49739
49740             for( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
49741
49742                 // remove minus times
49743
49744                 if( data.hierarchy[ h ].keys[ k ].time < 0 )
49745                     data.hierarchy[ h ].keys[ k ].time = 0;
49746
49747
49748                 // create quaternions
49749
49750                 if( data.hierarchy[ h ].keys[ k ].rot !== undefined &&
49751                  !( data.hierarchy[ h ].keys[ k ].rot instanceof THREE.Quaternion ) ) {
49752
49753                     var quat = data.hierarchy[ h ].keys[ k ].rot;
49754                     data.hierarchy[ h ].keys[ k ].rot = new THREE.Quaternion( quat[0], quat[1], quat[2], quat[3] );
49755
49756                 }
49757
49758             }
49759
49760
49761             // prepare morph target keys
49762
49763             if( data.hierarchy[ h ].keys.length && data.hierarchy[ h ].keys[ 0 ].morphTargets !== undefined ) {
49764
49765                 // get all used
49766
49767                 var usedMorphTargets = {};
49768
49769                 for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
49770
49771                     for ( var m = 0; m < data.hierarchy[ h ].keys[ k ].morphTargets.length; m ++ ) {
49772
49773                         var morphTargetName = data.hierarchy[ h ].keys[ k ].morphTargets[ m ];
49774                         usedMorphTargets[ morphTargetName ] = -1;
49775
49776                     }
49777
49778                 }
49779
49780                 data.hierarchy[ h ].usedMorphTargets = usedMorphTargets;
49781
49782
49783                 // set all used on all frames
49784
49785                 for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
49786
49787                     var influences = {};
49788
49789                     for ( var morphTargetName in usedMorphTargets ) {
49790
49791                         for ( var m = 0; m < data.hierarchy[ h ].keys[ k ].morphTargets.length; m ++ ) {
49792
49793                             if ( data.hierarchy[ h ].keys[ k ].morphTargets[ m ] === morphTargetName ) {
49794
49795                                 influences[ morphTargetName ] = data.hierarchy[ h ].keys[ k ].morphTargetsInfluences[ m ];
49796                                 break;
49797
49798                             }
49799
49800                         }
49801
49802                         if ( m === data.hierarchy[ h ].keys[ k ].morphTargets.length ) {
49803
49804                             influences[ morphTargetName ] = 0;
49805
49806                         }
49807
49808                     }
49809
49810                     data.hierarchy[ h ].keys[ k ].morphTargetsInfluences = influences;
49811
49812                 }
49813
49814             }
49815
49816
49817             // remove all keys that are on the same time
49818
49819             for ( var k = 1; k < data.hierarchy[ h ].keys.length; k ++ ) {
49820
49821                 if ( data.hierarchy[ h ].keys[ k ].time === data.hierarchy[ h ].keys[ k - 1 ].time ) {
49822
49823                     data.hierarchy[ h ].keys.splice( k, 1 );
49824                     k --;
49825
49826                 }
49827
49828             }
49829
49830
49831             // set index
49832
49833             for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
49834
49835                 data.hierarchy[ h ].keys[ k ].index = k;
49836
49837             }
49838
49839         }
49840
49841
49842         // JIT
49843
49844         var lengthInFrames = parseInt( data.length * data.fps, 10 );
49845
49846         data.JIT = {};
49847         data.JIT.hierarchy = [];
49848
49849         for( var h = 0; h < data.hierarchy.length; h ++ )
49850             data.JIT.hierarchy.push( new Array( lengthInFrames ) );
49851
49852
49853         // done
49854
49855         data.initialized = true;
49856
49857     };
49858
49859
49860     // interpolation types
49861
49862     that.LINEAR = 0;
49863     that.CATMULLROM = 1;
49864     that.CATMULLROM_FORWARD = 2;
49865
49866     return that;
49867
49868 }());
49869 /**
49870  * @author mikael emtinger / http://gomo.se/
49871  * @author mrdoob / http://mrdoob.com/
49872  * @author alteredq / http://alteredqualia.com/
49873  */
49874
49875 THREE.Animation = function ( root, name, interpolationType ) {
49876
49877     this.root = root;
49878     this.data = THREE.AnimationHandler.get( name );
49879     this.hierarchy = THREE.AnimationHandler.parse( root );
49880
49881     this.currentTime = 0;
49882     this.timeScale = 1;
49883
49884     this.isPlaying = false;
49885     this.isPaused = true;
49886     this.loop = true;
49887
49888     this.interpolationType = interpolationType !== undefined ? interpolationType : THREE.AnimationHandler.LINEAR;
49889
49890     this.points = [];
49891     this.target = new THREE.Vector3();
49892
49893 };
49894
49895 THREE.Animation.prototype.play = function ( loop, startTimeMS ) {
49896
49897     if ( this.isPlaying === false ) {
49898
49899         this.isPlaying = true;
49900         this.loop = loop !== undefined ? loop : true;
49901         this.currentTime = startTimeMS !== undefined ? startTimeMS : 0;
49902
49903         // reset key cache
49904
49905         var h, hl = this.hierarchy.length,
49906             object;
49907
49908         for ( h = 0; h < hl; h ++ ) {
49909
49910             object = this.hierarchy[ h ];
49911
49912             if ( this.interpolationType !== THREE.AnimationHandler.CATMULLROM_FORWARD ) {
49913
49914                 object.useQuaternion = true;
49915
49916             }
49917
49918             object.matrixAutoUpdate = true;
49919
49920             if ( object.animationCache === undefined ) {
49921
49922                 object.animationCache = {};
49923                 object.animationCache.prevKey = { pos: 0, rot: 0, scl: 0 };
49924                 object.animationCache.nextKey = { pos: 0, rot: 0, scl: 0 };
49925                 object.animationCache.originalMatrix = object instanceof THREE.Bone ? object.skinMatrix : object.matrix;
49926
49927             }
49928
49929             var prevKey = object.animationCache.prevKey;
49930             var nextKey = object.animationCache.nextKey;
49931
49932             prevKey.pos = this.data.hierarchy[ h ].keys[ 0 ];
49933             prevKey.rot = this.data.hierarchy[ h ].keys[ 0 ];
49934             prevKey.scl = this.data.hierarchy[ h ].keys[ 0 ];
49935
49936             nextKey.pos = this.getNextKeyWith( "pos", h, 1 );
49937             nextKey.rot = this.getNextKeyWith( "rot", h, 1 );
49938             nextKey.scl = this.getNextKeyWith( "scl", h, 1 );
49939
49940         }
49941
49942         this.update( 0 );
49943
49944     }
49945
49946     this.isPaused = false;
49947
49948     THREE.AnimationHandler.addToUpdate( this );
49949
49950 };
49951
49952
49953 THREE.Animation.prototype.pause = function() {
49954
49955     if ( this.isPaused === true ) {
49956
49957         THREE.AnimationHandler.addToUpdate( this );
49958
49959     } else {
49960
49961         THREE.AnimationHandler.removeFromUpdate( this );
49962
49963     }
49964
49965     this.isPaused = !this.isPaused;
49966
49967 };
49968
49969
49970 THREE.Animation.prototype.stop = function() {
49971
49972     this.isPlaying = false;
49973     this.isPaused  = false;
49974     THREE.AnimationHandler.removeFromUpdate( this );
49975
49976 };
49977
49978
49979 THREE.Animation.prototype.update = function ( deltaTimeMS ) {
49980
49981     // early out
49982
49983     if ( this.isPlaying === false ) return;
49984
49985
49986     // vars
49987
49988     var types = [ "pos", "rot", "scl" ];
49989     var type;
49990     var scale;
49991     var vector;
49992     var prevXYZ, nextXYZ;
49993     var prevKey, nextKey;
49994     var object;
49995     var animationCache;
49996     var frame;
49997     var JIThierarchy = this.data.JIT.hierarchy;
49998     var currentTime, unloopedCurrentTime;
49999     var currentPoint, forwardPoint, angle;
50000
50001
50002     this.currentTime += deltaTimeMS * this.timeScale;
50003
50004     unloopedCurrentTime = this.currentTime;
50005     currentTime = this.currentTime = this.currentTime % this.data.length;
50006     frame = parseInt( Math.min( currentTime * this.data.fps, this.data.length * this.data.fps ), 10 );
50007
50008
50009     for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
50010
50011         object = this.hierarchy[ h ];
50012         animationCache = object.animationCache;
50013
50014         // loop through pos/rot/scl
50015
50016         for ( var t = 0; t < 3; t ++ ) {
50017
50018             // get keys
50019
50020             type    = types[ t ];
50021             prevKey = animationCache.prevKey[ type ];
50022             nextKey = animationCache.nextKey[ type ];
50023
50024             // switch keys?
50025
50026             if ( nextKey.time <= unloopedCurrentTime ) {
50027
50028                 // did we loop?
50029
50030                 if ( currentTime < unloopedCurrentTime ) {
50031
50032                     if ( this.loop ) {
50033
50034                         prevKey = this.data.hierarchy[ h ].keys[ 0 ];
50035                         nextKey = this.getNextKeyWith( type, h, 1 );
50036
50037                         while( nextKey.time < currentTime ) {
50038
50039                             prevKey = nextKey;
50040                             nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 );
50041
50042                         }
50043
50044                     } else {
50045
50046                         this.stop();
50047                         return;
50048
50049                     }
50050
50051                 } else {
50052
50053                     do {
50054
50055                         prevKey = nextKey;
50056                         nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 );
50057
50058                     } while( nextKey.time < currentTime )
50059
50060                 }
50061
50062                 animationCache.prevKey[ type ] = prevKey;
50063                 animationCache.nextKey[ type ] = nextKey;
50064
50065             }
50066
50067
50068             object.matrixAutoUpdate = true;
50069             object.matrixWorldNeedsUpdate = true;
50070
50071             scale = ( currentTime - prevKey.time ) / ( nextKey.time - prevKey.time );
50072             prevXYZ = prevKey[ type ];
50073             nextXYZ = nextKey[ type ];
50074
50075
50076             // check scale error
50077
50078             if ( scale < 0 || scale > 1 ) {
50079
50080                 console.log( "THREE.Animation.update: Warning! Scale out of bounds:" + scale + " on bone " + h );
50081                 scale = scale < 0 ? 0 : 1;
50082
50083             }
50084
50085             // interpolate
50086
50087             if ( type === "pos" ) {
50088
50089                 vector = object.position;
50090
50091                 if ( this.interpolationType === THREE.AnimationHandler.LINEAR ) {
50092
50093                     vector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale;
50094                     vector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale;
50095                     vector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale;
50096
50097                 } else if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
50098                             this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
50099
50100                     this.points[ 0 ] = this.getPrevKeyWith( "pos", h, prevKey.index - 1 )[ "pos" ];
50101                     this.points[ 1 ] = prevXYZ;
50102                     this.points[ 2 ] = nextXYZ;
50103                     this.points[ 3 ] = this.getNextKeyWith( "pos", h, nextKey.index + 1 )[ "pos" ];
50104
50105                     scale = scale * 0.33 + 0.33;
50106
50107                     currentPoint = this.interpolateCatmullRom( this.points, scale );
50108
50109                     vector.x = currentPoint[ 0 ];
50110                     vector.y = currentPoint[ 1 ];
50111                     vector.z = currentPoint[ 2 ];
50112
50113                     if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
50114
50115                         forwardPoint = this.interpolateCatmullRom( this.points, scale * 1.01 );
50116
50117                         this.target.set( forwardPoint[ 0 ], forwardPoint[ 1 ], forwardPoint[ 2 ] );
50118                         this.target.subSelf( vector );
50119                         this.target.y = 0;
50120                         this.target.normalize();
50121
50122                         angle = Math.atan2( this.target.x, this.target.z );
50123                         object.rotation.set( 0, angle, 0 );
50124
50125                     }
50126
50127                 }
50128
50129             } else if ( type === "rot" ) {
50130
50131                 THREE.Quaternion.slerp( prevXYZ, nextXYZ, object.quaternion, scale );
50132
50133             } else if ( type === "scl" ) {
50134
50135                 vector = object.scale;
50136
50137                 vector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale;
50138                 vector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale;
50139                 vector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale;
50140
50141             }
50142
50143         }
50144
50145     }
50146
50147 };
50148
50149 // Catmull-Rom spline
50150
50151 THREE.Animation.prototype.interpolateCatmullRom = function ( points, scale ) {
50152
50153     var c = [], v3 = [],
50154     point, intPoint, weight, w2, w3,
50155     pa, pb, pc, pd;
50156
50157     point = ( points.length - 1 ) * scale;
50158     intPoint = Math.floor( point );
50159     weight = point - intPoint;
50160
50161     c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
50162     c[ 1 ] = intPoint;
50163     c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1;
50164     c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2;
50165
50166     pa = points[ c[ 0 ] ];
50167     pb = points[ c[ 1 ] ];
50168     pc = points[ c[ 2 ] ];
50169     pd = points[ c[ 3 ] ];
50170
50171     w2 = weight * weight;
50172     w3 = weight * w2;
50173
50174     v3[ 0 ] = this.interpolate( pa[ 0 ], pb[ 0 ], pc[ 0 ], pd[ 0 ], weight, w2, w3 );
50175     v3[ 1 ] = this.interpolate( pa[ 1 ], pb[ 1 ], pc[ 1 ], pd[ 1 ], weight, w2, w3 );
50176     v3[ 2 ] = this.interpolate( pa[ 2 ], pb[ 2 ], pc[ 2 ], pd[ 2 ], weight, w2, w3 );
50177
50178     return v3;
50179
50180 };
50181
50182 THREE.Animation.prototype.interpolate = function ( p0, p1, p2, p3, t, t2, t3 ) {
50183
50184     var v0 = ( p2 - p0 ) * 0.5,
50185         v1 = ( p3 - p1 ) * 0.5;
50186
50187     return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
50188
50189 };
50190
50191
50192
50193 // Get next key with
50194
50195 THREE.Animation.prototype.getNextKeyWith = function ( type, h, key ) {
50196
50197     var keys = this.data.hierarchy[ h ].keys;
50198
50199     if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
50200          this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
50201
50202         key = key < keys.length - 1 ? key : keys.length - 1;
50203
50204     } else {
50205
50206         key = key % keys.length;
50207
50208     }
50209
50210     for ( ; key < keys.length; key++ ) {
50211
50212         if ( keys[ key ][ type ] !== undefined ) {
50213
50214             return keys[ key ];
50215
50216         }
50217
50218     }
50219
50220     return this.data.hierarchy[ h ].keys[ 0 ];
50221
50222 };
50223
50224 // Get previous key with
50225
50226 THREE.Animation.prototype.getPrevKeyWith = function ( type, h, key ) {
50227
50228     var keys = this.data.hierarchy[ h ].keys;
50229
50230     if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
50231          this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
50232
50233         key = key > 0 ? key : 0;
50234
50235     } else {
50236
50237         key = key >= 0 ? key : key + keys.length;
50238
50239     }
50240
50241
50242     for ( ; key >= 0; key -- ) {
50243
50244         if ( keys[ key ][ type ] !== undefined ) {
50245
50246             return keys[ key ];
50247
50248         }
50249
50250     }
50251
50252     return this.data.hierarchy[ h ].keys[ keys.length - 1 ];
50253
50254 };
50255 /**
50256  * @author mikael emtinger / http://gomo.se/
50257  * @author mrdoob / http://mrdoob.com/
50258  * @author alteredq / http://alteredqualia.com/
50259  * @author khang duong
50260  * @author erik kitson
50261  */
50262
50263 THREE.KeyFrameAnimation = function( root, data, JITCompile ) {
50264
50265     this.root = root;
50266     this.data = THREE.AnimationHandler.get( data );
50267     this.hierarchy = THREE.AnimationHandler.parse( root );
50268     this.currentTime = 0;
50269     this.timeScale = 0.001;
50270     this.isPlaying = false;
50271     this.isPaused = true;
50272     this.loop = true;
50273     this.JITCompile = JITCompile !== undefined ? JITCompile : true;
50274
50275     // initialize to first keyframes
50276
50277     for ( var h = 0, hl = this.hierarchy.length; h < hl; h++ ) {
50278
50279         var keys = this.data.hierarchy[h].keys,
50280             sids = this.data.hierarchy[h].sids,
50281             obj = this.hierarchy[h];
50282
50283         if ( keys.length && sids ) {
50284
50285             for ( var s = 0; s < sids.length; s++ ) {
50286
50287                 var sid = sids[ s ],
50288                     next = this.getNextKeyWith( sid, h, 0 );
50289
50290                 if ( next ) {
50291
50292                     next.apply( sid );
50293
50294                 }
50295
50296             }
50297
50298             obj.matrixAutoUpdate = false;
50299             this.data.hierarchy[h].node.updateMatrix();
50300             obj.matrixWorldNeedsUpdate = true;
50301
50302         }
50303
50304     }
50305
50306 };
50307
50308 // Play
50309
50310 THREE.KeyFrameAnimation.prototype.play = function( loop, startTimeMS ) {
50311
50312     if( !this.isPlaying ) {
50313
50314         this.isPlaying = true;
50315         this.loop = loop !== undefined ? loop : true;
50316         this.currentTime = startTimeMS !== undefined ? startTimeMS : 0;
50317         this.startTimeMs = startTimeMS;
50318         this.startTime = 10000000;
50319         this.endTime = -this.startTime;
50320
50321
50322         // reset key cache
50323
50324         var h, hl = this.hierarchy.length,
50325             object,
50326             node;
50327
50328         for ( h = 0; h < hl; h++ ) {
50329
50330             object = this.hierarchy[ h ];
50331             node = this.data.hierarchy[ h ];
50332             object.useQuaternion = true;
50333
50334             if ( node.animationCache === undefined ) {
50335
50336                 node.animationCache = {};
50337                 node.animationCache.prevKey = null;
50338                 node.animationCache.nextKey = null;
50339                 node.animationCache.originalMatrix = object instanceof THREE.Bone ? object.skinMatrix : object.matrix;
50340
50341             }
50342
50343             var keys = this.data.hierarchy[h].keys;
50344
50345             if (keys.length) {
50346
50347                 node.animationCache.prevKey = keys[ 0 ];
50348                 node.animationCache.nextKey = keys[ 1 ];
50349
50350                 this.startTime = Math.min( keys[0].time, this.startTime );
50351                 this.endTime = Math.max( keys[keys.length - 1].time, this.endTime );
50352
50353             }
50354
50355         }
50356
50357         this.update( 0 );
50358
50359     }
50360
50361     this.isPaused = false;
50362
50363     THREE.AnimationHandler.addToUpdate( this );
50364
50365 };
50366
50367
50368
50369 // Pause
50370
50371 THREE.KeyFrameAnimation.prototype.pause = function() {
50372
50373     if( this.isPaused ) {
50374
50375         THREE.AnimationHandler.addToUpdate( this );
50376
50377     } else {
50378
50379         THREE.AnimationHandler.removeFromUpdate( this );
50380
50381     }
50382
50383     this.isPaused = !this.isPaused;
50384
50385 };
50386
50387
50388 // Stop
50389
50390 THREE.KeyFrameAnimation.prototype.stop = function() {
50391
50392     this.isPlaying = false;
50393     this.isPaused  = false;
50394     THREE.AnimationHandler.removeFromUpdate( this );
50395
50396
50397     // reset JIT matrix and remove cache
50398
50399     for ( var h = 0; h < this.data.hierarchy.length; h++ ) {
50400
50401         var obj = this.hierarchy[ h ];
50402         var node = this.data.hierarchy[ h ];
50403
50404         if ( node.animationCache !== undefined ) {
50405
50406             var original = node.animationCache.originalMatrix;
50407
50408             if( obj instanceof THREE.Bone ) {
50409
50410                 original.copy( obj.skinMatrix );
50411                 obj.skinMatrix = original;
50412
50413             } else {
50414
50415                 original.copy( obj.matrix );
50416                 obj.matrix = original;
50417
50418             }
50419
50420             delete node.animationCache;
50421
50422         }
50423
50424     }
50425
50426 };
50427
50428
50429 // Update
50430
50431 THREE.KeyFrameAnimation.prototype.update = function( deltaTimeMS ) {
50432
50433     // early out
50434
50435     if( !this.isPlaying ) return;
50436
50437
50438     // vars
50439
50440     var prevKey, nextKey;
50441     var object;
50442     var node;
50443     var frame;
50444     var JIThierarchy = this.data.JIT.hierarchy;
50445     var currentTime, unloopedCurrentTime;
50446     var looped;
50447
50448
50449     // update
50450
50451     this.currentTime += deltaTimeMS * this.timeScale;
50452
50453     unloopedCurrentTime = this.currentTime;
50454     currentTime         = this.currentTime = this.currentTime % this.data.length;
50455
50456     // if looped around, the current time should be based on the startTime
50457     if ( currentTime < this.startTimeMs ) {
50458
50459         currentTime = this.currentTime = this.startTimeMs + currentTime;
50460
50461     }
50462
50463     frame               = parseInt( Math.min( currentTime * this.data.fps, this.data.length * this.data.fps ), 10 );
50464     looped                 = currentTime < unloopedCurrentTime;
50465
50466     if ( looped && !this.loop ) {
50467
50468         // Set the animation to the last keyframes and stop
50469         for ( var h = 0, hl = this.hierarchy.length; h < hl; h++ ) {
50470
50471             var keys = this.data.hierarchy[h].keys,
50472                 sids = this.data.hierarchy[h].sids,
50473                 end = keys.length-1,
50474                 obj = this.hierarchy[h];
50475
50476             if ( keys.length ) {
50477
50478                 for ( var s = 0; s < sids.length; s++ ) {
50479
50480                     var sid = sids[ s ],
50481                         prev = this.getPrevKeyWith( sid, h, end );
50482
50483                     if ( prev ) {
50484                         prev.apply( sid );
50485
50486                     }
50487
50488                 }
50489
50490                 this.data.hierarchy[h].node.updateMatrix();
50491                 obj.matrixWorldNeedsUpdate = true;
50492
50493             }
50494
50495         }
50496
50497         this.stop();
50498         return;
50499
50500     }
50501
50502     // check pre-infinity
50503     if ( currentTime < this.startTime ) {
50504
50505         return;
50506
50507     }
50508
50509     // update
50510
50511     for ( var h = 0, hl = this.hierarchy.length; h < hl; h++ ) {
50512
50513         object = this.hierarchy[ h ];
50514         node = this.data.hierarchy[ h ];
50515
50516         var keys = node.keys,
50517             animationCache = node.animationCache;
50518
50519         // use JIT?
50520
50521         if ( this.JITCompile && JIThierarchy[ h ][ frame ] !== undefined ) {
50522
50523             if( object instanceof THREE.Bone ) {
50524
50525                 object.skinMatrix = JIThierarchy[ h ][ frame ];
50526                 object.matrixWorldNeedsUpdate = false;
50527
50528             } else {
50529
50530                 object.matrix = JIThierarchy[ h ][ frame ];
50531                 object.matrixWorldNeedsUpdate = true;
50532
50533             }
50534
50535         // use interpolation
50536
50537         } else if ( keys.length ) {
50538
50539             // make sure so original matrix and not JIT matrix is set
50540
50541             if ( this.JITCompile && animationCache ) {
50542
50543                 if( object instanceof THREE.Bone ) {
50544
50545                     object.skinMatrix = animationCache.originalMatrix;
50546
50547                 } else {
50548
50549                     object.matrix = animationCache.originalMatrix;
50550
50551                 }
50552
50553             }
50554
50555             prevKey = animationCache.prevKey;
50556             nextKey = animationCache.nextKey;
50557
50558             if ( prevKey && nextKey ) {
50559
50560                 // switch keys?
50561
50562                 if ( nextKey.time <= unloopedCurrentTime ) {
50563
50564                     // did we loop?
50565
50566                     if ( looped && this.loop ) {
50567
50568                         prevKey = keys[ 0 ];
50569                         nextKey = keys[ 1 ];
50570
50571                         while ( nextKey.time < currentTime ) {
50572
50573                             prevKey = nextKey;
50574                             nextKey = keys[ prevKey.index + 1 ];
50575
50576                         }
50577
50578                     } else if ( !looped ) {
50579
50580                         var lastIndex = keys.length - 1;
50581
50582                         while ( nextKey.time < currentTime && nextKey.index !== lastIndex ) {
50583
50584                             prevKey = nextKey;
50585                             nextKey = keys[ prevKey.index + 1 ];
50586
50587                         }
50588
50589                     }
50590
50591                     animationCache.prevKey = prevKey;
50592                     animationCache.nextKey = nextKey;
50593
50594                 }
50595                 if(nextKey.time >= currentTime)
50596                     prevKey.interpolate( nextKey, currentTime );
50597                 else
50598                     prevKey.interpolate( nextKey, nextKey.time);
50599
50600             }
50601
50602             this.data.hierarchy[h].node.updateMatrix();
50603             object.matrixWorldNeedsUpdate = true;
50604
50605         }
50606
50607     }
50608
50609     // update JIT?
50610
50611     if ( this.JITCompile ) {
50612
50613         if ( JIThierarchy[ 0 ][ frame ] === undefined ) {
50614
50615             this.hierarchy[ 0 ].updateMatrixWorld( true );
50616
50617             for ( var h = 0; h < this.hierarchy.length; h++ ) {
50618
50619                 if( this.hierarchy[ h ] instanceof THREE.Bone ) {
50620
50621                     JIThierarchy[ h ][ frame ] = this.hierarchy[ h ].skinMatrix.clone();
50622
50623                 } else {
50624
50625                     JIThierarchy[ h ][ frame ] = this.hierarchy[ h ].matrix.clone();
50626
50627                 }
50628
50629             }
50630
50631         }
50632
50633     }
50634
50635 };
50636
50637 // Get next key with
50638
50639 THREE.KeyFrameAnimation.prototype.getNextKeyWith = function( sid, h, key ) {
50640
50641     var keys = this.data.hierarchy[ h ].keys;
50642     key = key % keys.length;
50643
50644     for ( ; key < keys.length; key++ ) {
50645
50646         if ( keys[ key ].hasTarget( sid ) ) {
50647
50648             return keys[ key ];
50649
50650         }
50651
50652     }
50653
50654     return keys[ 0 ];
50655
50656 };
50657
50658 // Get previous key with
50659
50660 THREE.KeyFrameAnimation.prototype.getPrevKeyWith = function( sid, h, key ) {
50661
50662     var keys = this.data.hierarchy[ h ].keys;
50663     key = key >= 0 ? key : key + keys.length;
50664
50665     for ( ; key >= 0; key-- ) {
50666
50667         if ( keys[ key ].hasTarget( sid ) ) {
50668
50669             return keys[ key ];
50670
50671         }
50672
50673     }
50674
50675     return keys[ keys.length - 1 ];
50676
50677 };
50678 /**
50679  * Camera for rendering cube maps
50680  *    - renders scene into axis-aligned cube
50681  *
50682  * @author alteredq / http://alteredqualia.com/
50683  */
50684
50685 THREE.CubeCamera = function ( near, far, cubeResolution ) {
50686
50687     THREE.Object3D.call( this );
50688
50689     var fov = 90, aspect = 1;
50690
50691     var cameraPX = new THREE.PerspectiveCamera( fov, aspect, near, far );
50692     cameraPX.up.set( 0, -1, 0 );
50693     cameraPX.lookAt( new THREE.Vector3( 1, 0, 0 ) );
50694     this.add( cameraPX );
50695
50696     var cameraNX = new THREE.PerspectiveCamera( fov, aspect, near, far );
50697     cameraNX.up.set( 0, -1, 0 );
50698     cameraNX.lookAt( new THREE.Vector3( -1, 0, 0 ) );
50699     this.add( cameraNX );
50700
50701     var cameraPY = new THREE.PerspectiveCamera( fov, aspect, near, far );
50702     cameraPY.up.set( 0, 0, 1 );
50703     cameraPY.lookAt( new THREE.Vector3( 0, 1, 0 ) );
50704     this.add( cameraPY );
50705
50706     var cameraNY = new THREE.PerspectiveCamera( fov, aspect, near, far );
50707     cameraNY.up.set( 0, 0, -1 );
50708     cameraNY.lookAt( new THREE.Vector3( 0, -1, 0 ) );
50709     this.add( cameraNY );
50710
50711     var cameraPZ = new THREE.PerspectiveCamera( fov, aspect, near, far );
50712     cameraPZ.up.set( 0, -1, 0 );
50713     cameraPZ.lookAt( new THREE.Vector3( 0, 0, 1 ) );
50714     this.add( cameraPZ );
50715
50716     var cameraNZ = new THREE.PerspectiveCamera( fov, aspect, near, far );
50717     cameraNZ.up.set( 0, -1, 0 );
50718     cameraNZ.lookAt( new THREE.Vector3( 0, 0, -1 ) );
50719     this.add( cameraNZ );
50720
50721     this.renderTarget = new THREE.WebGLRenderTargetCube( cubeResolution, cubeResolution, { format: THREE.RGBFormat, magFilter: THREE.LinearFilter, minFilter: THREE.LinearFilter } );
50722
50723     this.updateCubeMap = function ( renderer, scene ) {
50724
50725         var renderTarget = this.renderTarget;
50726         var generateMipmaps = renderTarget.generateMipmaps;
50727
50728         renderTarget.generateMipmaps = false;
50729
50730         renderTarget.activeCubeFace = 0;
50731         renderer.render( scene, cameraPX, renderTarget );
50732
50733         renderTarget.activeCubeFace = 1;
50734         renderer.render( scene, cameraNX, renderTarget );
50735
50736         renderTarget.activeCubeFace = 2;
50737         renderer.render( scene, cameraPY, renderTarget );
50738
50739         renderTarget.activeCubeFace = 3;
50740         renderer.render( scene, cameraNY, renderTarget );
50741
50742         renderTarget.activeCubeFace = 4;
50743         renderer.render( scene, cameraPZ, renderTarget );
50744
50745         renderTarget.generateMipmaps = generateMipmaps;
50746
50747         renderTarget.activeCubeFace = 5;
50748         renderer.render( scene, cameraNZ, renderTarget );
50749
50750     };
50751
50752 };
50753
50754 THREE.CubeCamera.prototype = Object.create( THREE.Object3D.prototype );
50755 /*
50756  *    @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
50757  *
50758  *    A general perpose camera, for setting FOV, Lens Focal Length,
50759  *        and switching between perspective and orthographic views easily.
50760  *        Use this only if you do not wish to manage
50761  *        both a Orthographic and Perspective Camera
50762  *
50763  */
50764
50765
50766 THREE.CombinedCamera = function ( width, height, fov, near, far, orthoNear, orthoFar ) {
50767
50768     THREE.Camera.call( this );
50769
50770     this.fov = fov;
50771
50772     this.left = -width / 2;
50773     this.right = width / 2
50774     this.top = height / 2;
50775     this.bottom = -height / 2;
50776
50777     // We could also handle the projectionMatrix internally, but just wanted to test nested camera objects
50778
50779     this.cameraO = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2,     orthoNear, orthoFar );
50780     this.cameraP = new THREE.PerspectiveCamera( fov, width / height, near, far );
50781
50782     this.zoom = 1;
50783
50784     this.toPerspective();
50785
50786     var aspect = width/height;
50787
50788 };
50789
50790 THREE.CombinedCamera.prototype = Object.create( THREE.Camera.prototype );
50791
50792 THREE.CombinedCamera.prototype.toPerspective = function () {
50793
50794     // Switches to the Perspective Camera
50795
50796     this.near = this.cameraP.near;
50797     this.far = this.cameraP.far;
50798
50799     this.cameraP.fov =  this.fov / this.zoom ;
50800
50801     this.cameraP.updateProjectionMatrix();
50802
50803     this.projectionMatrix = this.cameraP.projectionMatrix;
50804
50805     this.inPerspectiveMode = true;
50806     this.inOrthographicMode = false;
50807
50808 };
50809
50810 THREE.CombinedCamera.prototype.toOrthographic = function () {
50811
50812     // Switches to the Orthographic camera estimating viewport from Perspective
50813
50814     var fov = this.fov;
50815     var aspect = this.cameraP.aspect;
50816     var near = this.cameraP.near;
50817     var far = this.cameraP.far;
50818
50819     // The size that we set is the mid plane of the viewing frustum
50820
50821     var hyperfocus = ( near + far ) / 2;
50822
50823     var halfHeight = Math.tan( fov / 2 ) * hyperfocus;
50824     var planeHeight = 2 * halfHeight;
50825     var planeWidth = planeHeight * aspect;
50826     var halfWidth = planeWidth / 2;
50827
50828     halfHeight /= this.zoom;
50829     halfWidth /= this.zoom;
50830
50831     this.cameraO.left = -halfWidth;
50832     this.cameraO.right = halfWidth;
50833     this.cameraO.top = halfHeight;
50834     this.cameraO.bottom = -halfHeight;
50835
50836     // this.cameraO.left = -farHalfWidth;
50837     // this.cameraO.right = farHalfWidth;
50838     // this.cameraO.top = farHalfHeight;
50839     // this.cameraO.bottom = -farHalfHeight;
50840
50841     // this.cameraO.left = this.left / this.zoom;
50842     // this.cameraO.right = this.right / this.zoom;
50843     // this.cameraO.top = this.top / this.zoom;
50844     // this.cameraO.bottom = this.bottom / this.zoom;
50845
50846     this.cameraO.updateProjectionMatrix();
50847
50848     this.near = this.cameraO.near;
50849     this.far = this.cameraO.far;
50850     this.projectionMatrix = this.cameraO.projectionMatrix;
50851
50852     this.inPerspectiveMode = false;
50853     this.inOrthographicMode = true;
50854
50855 };
50856
50857
50858 THREE.CombinedCamera.prototype.setSize = function( width, height ) {
50859
50860     this.cameraP.aspect = width / height;
50861     this.left = -width / 2;
50862     this.right = width / 2
50863     this.top = height / 2;
50864     this.bottom = -height / 2;
50865
50866 };
50867
50868
50869 THREE.CombinedCamera.prototype.setFov = function( fov ) {
50870
50871     this.fov = fov;
50872
50873     if ( this.inPerspectiveMode ) {
50874
50875         this.toPerspective();
50876
50877     } else {
50878
50879         this.toOrthographic();
50880
50881     }
50882
50883 };
50884
50885 // For mantaining similar API with PerspectiveCamera
50886
50887 THREE.CombinedCamera.prototype.updateProjectionMatrix = function() {
50888
50889     if ( this.inPerspectiveMode ) {
50890
50891         this.toPerspective();
50892
50893     } else {
50894
50895         this.toPerspective();
50896         this.toOrthographic();
50897
50898     }
50899
50900 };
50901
50902 /*
50903 * Uses Focal Length (in mm) to estimate and set FOV
50904 * 35mm (fullframe) camera is used if frame size is not specified;
50905 * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
50906 */
50907 THREE.CombinedCamera.prototype.setLens = function ( focalLength, frameHeight ) {
50908
50909     if ( frameHeight === undefined ) frameHeight = 24;
50910
50911     var fov = 2 * Math.atan( frameHeight / ( focalLength * 2 ) ) * ( 180 / Math.PI );
50912
50913     this.setFov( fov );
50914
50915     return fov;
50916 };
50917
50918
50919 THREE.CombinedCamera.prototype.setZoom = function( zoom ) {
50920
50921     this.zoom = zoom;
50922
50923     if ( this.inPerspectiveMode ) {
50924
50925         this.toPerspective();
50926
50927     } else {
50928
50929         this.toOrthographic();
50930
50931     }
50932
50933 };
50934
50935 THREE.CombinedCamera.prototype.toFrontView = function() {
50936
50937     this.rotation.x = 0;
50938     this.rotation.y = 0;
50939     this.rotation.z = 0;
50940
50941     // should we be modifing the matrix instead?
50942
50943     this.rotationAutoUpdate = false;
50944
50945 };
50946
50947 THREE.CombinedCamera.prototype.toBackView = function() {
50948
50949     this.rotation.x = 0;
50950     this.rotation.y = Math.PI;
50951     this.rotation.z = 0;
50952     this.rotationAutoUpdate = false;
50953
50954 };
50955
50956 THREE.CombinedCamera.prototype.toLeftView = function() {
50957
50958     this.rotation.x = 0;
50959     this.rotation.y = - Math.PI / 2;
50960     this.rotation.z = 0;
50961     this.rotationAutoUpdate = false;
50962
50963 };
50964
50965 THREE.CombinedCamera.prototype.toRightView = function() {
50966
50967     this.rotation.x = 0;
50968     this.rotation.y = Math.PI / 2;
50969     this.rotation.z = 0;
50970     this.rotationAutoUpdate = false;
50971
50972 };
50973
50974 THREE.CombinedCamera.prototype.toTopView = function() {
50975
50976     this.rotation.x = - Math.PI / 2;
50977     this.rotation.y = 0;
50978     this.rotation.z = 0;
50979     this.rotationAutoUpdate = false;
50980
50981 };
50982
50983 THREE.CombinedCamera.prototype.toBottomView = function() {
50984
50985     this.rotation.x = Math.PI / 2;
50986     this.rotation.y = 0;
50987     this.rotation.z = 0;
50988     this.rotationAutoUpdate = false;
50989
50990 };
50991
50992 /**
50993  * @author mrdoob / http://mrdoob.com/
50994  * @author alteredq / http://alteredqualia.com/
50995  * @author paulirish / http://paulirish.com/
50996  */
50997
50998 THREE.FirstPersonControls = function ( object, domElement ) {
50999
51000     this.object = object;
51001     this.target = new THREE.Vector3( 0, 0, 0 );
51002
51003     this.domElement = ( domElement !== undefined ) ? domElement : document;
51004
51005     this.movementSpeed = 1.0;
51006     this.lookSpeed = 0.005;
51007
51008     this.lookVertical = true;
51009     this.autoForward = false;
51010     // this.invertVertical = false;
51011
51012     this.activeLook = true;
51013
51014     this.heightSpeed = false;
51015     this.heightCoef = 1.0;
51016     this.heightMin = 0.0;
51017     this.heightMax = 1.0;
51018
51019     this.constrainVertical = false;
51020     this.verticalMin = 0;
51021     this.verticalMax = Math.PI;
51022
51023     this.autoSpeedFactor = 0.0;
51024
51025     this.mouseX = 0;
51026     this.mouseY = 0;
51027
51028     this.lat = 0;
51029     this.lon = 0;
51030     this.phi = 0;
51031     this.theta = 0;
51032
51033     this.moveForward = false;
51034     this.moveBackward = false;
51035     this.moveLeft = false;
51036     this.moveRight = false;
51037     this.freeze = false;
51038
51039     this.mouseDragOn = false;
51040
51041     this.viewHalfX = 0;
51042     this.viewHalfY = 0;
51043
51044     if ( this.domElement !== document ) {
51045
51046         this.domElement.setAttribute( 'tabindex', -1 );
51047
51048     }
51049
51050     //
51051
51052     this.handleResize = function () {
51053
51054         if ( this.domElement === document ) {
51055
51056             this.viewHalfX = window.innerWidth / 2;
51057             this.viewHalfY = window.innerHeight / 2;
51058
51059         } else {
51060
51061             this.viewHalfX = this.domElement.offsetWidth / 2;
51062             this.viewHalfY = this.domElement.offsetHeight / 2;
51063
51064         }
51065
51066     };
51067
51068     this.onMouseDown = function ( event ) {
51069
51070         if ( this.domElement !== document ) {
51071
51072             this.domElement.focus();
51073
51074         }
51075
51076         event.preventDefault();
51077         event.stopPropagation();
51078
51079         if ( this.activeLook ) {
51080
51081             switch ( event.button ) {
51082
51083                 case 0: this.moveForward = true; break;
51084                 case 2: this.moveBackward = true; break;
51085
51086             }
51087
51088         }
51089
51090         this.mouseDragOn = true;
51091
51092     };
51093
51094     this.onMouseUp = function ( event ) {
51095
51096         event.preventDefault();
51097         event.stopPropagation();
51098
51099         if ( this.activeLook ) {
51100
51101             switch ( event.button ) {
51102
51103                 case 0: this.moveForward = false; break;
51104                 case 2: this.moveBackward = false; break;
51105
51106             }
51107
51108         }
51109
51110         this.mouseDragOn = false;
51111
51112     };
51113
51114     this.onMouseMove = function ( event ) {
51115
51116         if ( this.domElement === document ) {
51117
51118             this.mouseX = event.pageX - this.viewHalfX;
51119             this.mouseY = event.pageY - this.viewHalfY;
51120
51121         } else {
51122
51123             this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
51124             this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
51125
51126         }
51127
51128     };
51129
51130     this.onKeyDown = function ( event ) {
51131
51132         //event.preventDefault();
51133
51134         switch ( event.keyCode ) {
51135
51136             case 38: /*up*/
51137             case 87: /*W*/ this.moveForward = true; break;
51138
51139             case 37: /*left*/
51140             case 65: /*A*/ this.moveLeft = true; break;
51141
51142             case 40: /*down*/
51143             case 83: /*S*/ this.moveBackward = true; break;
51144
51145             case 39: /*right*/
51146             case 68: /*D*/ this.moveRight = true; break;
51147
51148             case 82: /*R*/ this.moveUp = true; break;
51149             case 70: /*F*/ this.moveDown = true; break;
51150
51151             case 81: /*Q*/ this.freeze = !this.freeze; break;
51152
51153         }
51154
51155     };
51156
51157     this.onKeyUp = function ( event ) {
51158
51159         switch( event.keyCode ) {
51160
51161             case 38: /*up*/
51162             case 87: /*W*/ this.moveForward = false; break;
51163
51164             case 37: /*left*/
51165             case 65: /*A*/ this.moveLeft = false; break;
51166
51167             case 40: /*down*/
51168             case 83: /*S*/ this.moveBackward = false; break;
51169
51170             case 39: /*right*/
51171             case 68: /*D*/ this.moveRight = false; break;
51172
51173             case 82: /*R*/ this.moveUp = false; break;
51174             case 70: /*F*/ this.moveDown = false; break;
51175
51176         }
51177
51178     };
51179
51180     this.update = function( delta ) {
51181         var actualMoveSpeed = 0;
51182
51183         if ( this.freeze ) {
51184
51185             return;
51186
51187         } else {
51188
51189             if ( this.heightSpeed ) {
51190
51191                 var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax );
51192                 var heightDelta = y - this.heightMin;
51193
51194                 this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef );
51195
51196             } else {
51197
51198                 this.autoSpeedFactor = 0.0;
51199
51200             }
51201
51202             actualMoveSpeed = delta * this.movementSpeed;
51203
51204             if ( this.moveForward || ( this.autoForward && !this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
51205             if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed );
51206
51207             if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed );
51208             if ( this.moveRight ) this.object.translateX( actualMoveSpeed );
51209
51210             if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
51211             if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );
51212
51213             var actualLookSpeed = delta * this.lookSpeed;
51214
51215             if ( !this.activeLook ) {
51216
51217                 actualLookSpeed = 0;
51218
51219             }
51220
51221             this.lon += this.mouseX * actualLookSpeed;
51222             if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed; // * this.invertVertical?-1:1;
51223
51224             this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
51225             this.phi = ( 90 - this.lat ) * Math.PI / 180;
51226             this.theta = this.lon * Math.PI / 180;
51227
51228             var targetPosition = this.target,
51229                 position = this.object.position;
51230
51231             targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
51232             targetPosition.y = position.y + 100 * Math.cos( this.phi );
51233             targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
51234
51235         }
51236
51237         var verticalLookRatio = 1;
51238
51239         if ( this.constrainVertical ) {
51240
51241             verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );
51242
51243         }
51244
51245         this.lon += this.mouseX * actualLookSpeed;
51246         if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio;
51247
51248         this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
51249         this.phi = ( 90 - this.lat ) * Math.PI / 180;
51250
51251         this.theta = this.lon * Math.PI / 180;
51252
51253         if ( this.constrainVertical ) {
51254
51255             this.phi = THREE.Math.mapLinear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax );
51256
51257         }
51258
51259         var targetPosition = this.target,
51260             position = this.object.position;
51261
51262         targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
51263         targetPosition.y = position.y + 100 * Math.cos( this.phi );
51264         targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
51265
51266         this.object.lookAt( targetPosition );
51267
51268     };
51269
51270
51271     this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
51272
51273     this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
51274     this.domElement.addEventListener( 'mousedown', bind( this, this.onMouseDown ), false );
51275     this.domElement.addEventListener( 'mouseup', bind( this, this.onMouseUp ), false );
51276     this.domElement.addEventListener( 'keydown', bind( this, this.onKeyDown ), false );
51277     this.domElement.addEventListener( 'keyup', bind( this, this.onKeyUp ), false );
51278
51279     function bind( scope, fn ) {
51280
51281         return function () {
51282
51283             fn.apply( scope, arguments );
51284
51285         };
51286
51287     };
51288
51289     this.handleResize();
51290
51291 };
51292 /**
51293  * @author alteredq / http://alteredqualia.com/
51294  */
51295
51296 THREE.PathControls = function ( object, domElement ) {
51297
51298     this.object = object;
51299     this.domElement = ( domElement !== undefined ) ? domElement : document;
51300
51301     this.id = "PathControls" + THREE.PathControlsIdCounter ++;
51302
51303     // API
51304
51305     this.duration = 10 * 1000; // milliseconds
51306     this.waypoints = [];
51307
51308     this.useConstantSpeed = true;
51309     this.resamplingCoef = 50;
51310
51311     this.debugPath = new THREE.Object3D();
51312     this.debugDummy = new THREE.Object3D();
51313
51314     this.animationParent = new THREE.Object3D();
51315
51316     this.lookSpeed = 0.005;
51317     this.lookVertical = true;
51318     this.lookHorizontal = true;
51319     this.verticalAngleMap   = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0, 2 * Math.PI ] };
51320     this.horizontalAngleMap = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0, 2 * Math.PI ] };
51321
51322     // internals
51323
51324     this.target = new THREE.Object3D();
51325
51326     this.mouseX = 0;
51327     this.mouseY = 0;
51328
51329     this.lat = 0;
51330     this.lon = 0;
51331
51332     this.phi = 0;
51333     this.theta = 0;
51334
51335     var PI2 = Math.PI * 2,
51336         PI180 = Math.PI / 180;
51337
51338     this.viewHalfX = 0;
51339     this.viewHalfY = 0;
51340
51341     if ( this.domElement !== document ) {
51342
51343         this.domElement.setAttribute( 'tabindex', -1 );
51344
51345     }
51346
51347     // methods
51348
51349     this.handleResize = function () {
51350
51351         if ( this.domElement === document ) {
51352
51353             this.viewHalfX = window.innerWidth / 2;
51354             this.viewHalfY = window.innerHeight / 2;
51355
51356         } else {
51357
51358             this.viewHalfX = this.domElement.offsetWidth / 2;
51359             this.viewHalfY = this.domElement.offsetHeight / 2;
51360
51361         }
51362
51363     };
51364
51365     this.update = function ( delta ) {
51366
51367         var srcRange, dstRange;
51368
51369         if( this.lookHorizontal ) this.lon += this.mouseX * this.lookSpeed * delta;
51370         if( this.lookVertical )   this.lat -= this.mouseY * this.lookSpeed * delta;
51371
51372         this.lon = Math.max( 0, Math.min( 360, this.lon ) );
51373         this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
51374
51375         this.phi = ( 90 - this.lat ) * PI180;
51376         this.theta = this.lon * PI180;
51377
51378         this.phi = normalize_angle_rad( this.phi );
51379
51380         // constrain vertical look angle
51381
51382         srcRange = this.verticalAngleMap.srcRange;
51383         dstRange = this.verticalAngleMap.dstRange;
51384
51385         var tmpPhi = THREE.Math.mapLinear( this.phi, srcRange[ 0 ], srcRange[ 1 ], dstRange[ 0 ], dstRange[ 1 ] );
51386         var tmpPhiFullRange = dstRange[ 1 ] - dstRange[ 0 ];
51387         var tmpPhiNormalized = ( tmpPhi - dstRange[ 0 ] ) / tmpPhiFullRange;
51388
51389         this.phi = QuadraticEaseInOut( tmpPhiNormalized ) * tmpPhiFullRange + dstRange[ 0 ];
51390
51391         // constrain horizontal look angle
51392
51393         srcRange = this.horizontalAngleMap.srcRange;
51394         dstRange = this.horizontalAngleMap.dstRange;
51395
51396         var tmpTheta = THREE.Math.mapLinear( this.theta, srcRange[ 0 ], srcRange[ 1 ], dstRange[ 0 ], dstRange[ 1 ] );
51397         var tmpThetaFullRange = dstRange[ 1 ] - dstRange[ 0 ];
51398         var tmpThetaNormalized = ( tmpTheta - dstRange[ 0 ] ) / tmpThetaFullRange;
51399
51400         this.theta = QuadraticEaseInOut( tmpThetaNormalized ) * tmpThetaFullRange + dstRange[ 0 ];
51401
51402         var targetPosition = this.target.position,
51403             position = this.object.position;
51404
51405         targetPosition.x = 100 * Math.sin( this.phi ) * Math.cos( this.theta );
51406         targetPosition.y = 100 * Math.cos( this.phi );
51407         targetPosition.z = 100 * Math.sin( this.phi ) * Math.sin( this.theta );
51408
51409         this.object.lookAt( this.target.position );
51410
51411     };
51412
51413     this.onMouseMove = function ( event ) {
51414
51415         if ( this.domElement === document ) {
51416
51417             this.mouseX = event.pageX - this.viewHalfX;
51418             this.mouseY = event.pageY - this.viewHalfY;
51419
51420         } else {
51421
51422             this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
51423             this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
51424
51425         }
51426
51427     };
51428
51429     // utils
51430
51431     function normalize_angle_rad( a ) {
51432
51433         var b = a % PI2;
51434         return b >= 0 ? b : b + PI2;
51435
51436     };
51437
51438     function distance( a, b ) {
51439
51440         var dx = a[ 0 ] - b[ 0 ],
51441             dy = a[ 1 ] - b[ 1 ],
51442             dz = a[ 2 ] - b[ 2 ];
51443
51444         return Math.sqrt( dx * dx + dy * dy + dz * dz );
51445
51446     };
51447
51448     function QuadraticEaseInOut ( k ) {
51449
51450         if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
51451         return - 0.5 * ( --k * ( k - 2 ) - 1 );
51452
51453     };
51454
51455     function bind( scope, fn ) {
51456
51457         return function () {
51458
51459             fn.apply( scope, arguments );
51460
51461         };
51462
51463     };
51464
51465     function initAnimationPath( parent, spline, name, duration ) {
51466
51467         var animationData = {
51468
51469            name: name,
51470            fps: 0.6,
51471            length: duration,
51472
51473            hierarchy: []
51474
51475         };
51476
51477         var i,
51478             parentAnimation, childAnimation,
51479             path = spline.getControlPointsArray(),
51480             sl = spline.getLength(),
51481             pl = path.length,
51482             t = 0,
51483             first = 0,
51484             last  = pl - 1;
51485
51486         parentAnimation = { parent: -1, keys: [] };
51487         parentAnimation.keys[ first ] = { time: 0,        pos: path[ first ], rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
51488         parentAnimation.keys[ last  ] = { time: duration, pos: path[ last ],  rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
51489
51490         for ( i = 1; i < pl - 1; i++ ) {
51491
51492             // real distance (approximation via linear segments)
51493
51494             t = duration * sl.chunks[ i ] / sl.total;
51495
51496             // equal distance
51497
51498             //t = duration * ( i / pl );
51499
51500             // linear distance
51501
51502             //t += duration * distance( path[ i ], path[ i - 1 ] ) / sl.total;
51503
51504             parentAnimation.keys[ i ] = { time: t, pos: path[ i ] };
51505
51506         }
51507
51508         animationData.hierarchy[ 0 ] = parentAnimation;
51509
51510         THREE.AnimationHandler.add( animationData );
51511
51512         return new THREE.Animation( parent, name, THREE.AnimationHandler.CATMULLROM_FORWARD, false );
51513
51514     };
51515
51516
51517     function createSplineGeometry( spline, n_sub ) {
51518
51519         var i, index, position,
51520             geometry = new THREE.Geometry();
51521
51522         for ( i = 0; i < spline.points.length * n_sub; i ++ ) {
51523
51524             index = i / ( spline.points.length * n_sub );
51525             position = spline.getPoint( index );
51526
51527             geometry.vertices[ i ] = new THREE.Vector3( position.x, position.y, position.z );
51528
51529         }
51530
51531         return geometry;
51532
51533     };
51534
51535     function createPath( parent, spline ) {
51536
51537         var lineGeo = createSplineGeometry( spline, 10 ),
51538             particleGeo = createSplineGeometry( spline, 10 ),
51539             lineMat = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 3 } ),
51540             lineObj = new THREE.Line( lineGeo, lineMat ),
51541             particleObj = new THREE.ParticleSystem( particleGeo, new THREE.ParticleBasicMaterial( { color: 0xffaa00, size: 3 } ) );
51542
51543         lineObj.scale.set( 1, 1, 1 );
51544         parent.add( lineObj );
51545
51546         particleObj.scale.set( 1, 1, 1 );
51547         parent.add( particleObj );
51548
51549         var waypoint,
51550             geo = new THREE.SphereGeometry( 1, 16, 8 ),
51551             mat = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
51552
51553         for ( var i = 0; i < spline.points.length; i ++ ) {
51554
51555             waypoint = new THREE.Mesh( geo, mat );
51556             waypoint.position.copy( spline.points[ i ] );
51557             parent.add( waypoint );
51558
51559         }
51560
51561     };
51562
51563     this.init = function ( ) {
51564
51565         // constructor
51566
51567         this.spline = new THREE.Spline();
51568         this.spline.initFromArray( this.waypoints );
51569
51570         if ( this.useConstantSpeed ) {
51571
51572             this.spline.reparametrizeByArcLength( this.resamplingCoef );
51573
51574         }
51575
51576         if ( this.createDebugDummy ) {
51577
51578             var dummyParentMaterial = new THREE.MeshLambertMaterial( { color: 0x0077ff } ),
51579             dummyChildMaterial  = new THREE.MeshLambertMaterial( { color: 0x00ff00 } ),
51580             dummyParentGeo = new THREE.CubeGeometry( 10, 10, 20 ),
51581             dummyChildGeo  = new THREE.CubeGeometry( 2, 2, 10 );
51582
51583             this.animationParent = new THREE.Mesh( dummyParentGeo, dummyParentMaterial );
51584
51585             var dummyChild = new THREE.Mesh( dummyChildGeo, dummyChildMaterial );
51586             dummyChild.position.set( 0, 10, 0 );
51587
51588             this.animation = initAnimationPath( this.animationParent, this.spline, this.id, this.duration );
51589
51590             this.animationParent.add( this.object );
51591             this.animationParent.add( this.target );
51592             this.animationParent.add( dummyChild );
51593
51594         } else {
51595
51596             this.animation = initAnimationPath( this.animationParent, this.spline, this.id, this.duration );
51597             this.animationParent.add( this.target );
51598             this.animationParent.add( this.object );
51599
51600         }
51601
51602         if ( this.createDebugPath ) {
51603
51604             createPath( this.debugPath, this.spline );
51605
51606         }
51607
51608         this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
51609
51610     };
51611
51612     this.handleResize();
51613
51614 };
51615
51616 THREE.PathControlsIdCounter = 0;
51617 /**
51618  * @author James Baicoianu / http://www.baicoianu.com/
51619  */
51620
51621 THREE.FlyControls = function ( object, domElement ) {
51622
51623     this.object = object;
51624
51625     this.domElement = ( domElement !== undefined ) ? domElement : document;
51626     if ( domElement ) this.domElement.setAttribute( 'tabindex', -1 );
51627
51628     // API
51629
51630     this.movementSpeed = 1.0;
51631     this.rollSpeed = 0.005;
51632
51633     this.dragToLook = false;
51634     this.autoForward = false;
51635
51636     // disable default target object behavior
51637
51638     this.object.useQuaternion = true;
51639
51640     // internals
51641
51642     this.tmpQuaternion = new THREE.Quaternion();
51643
51644     this.mouseStatus = 0;
51645
51646     this.moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 };
51647     this.moveVector = new THREE.Vector3( 0, 0, 0 );
51648     this.rotationVector = new THREE.Vector3( 0, 0, 0 );
51649
51650     this.handleEvent = function ( event ) {
51651
51652         if ( typeof this[ event.type ] == 'function' ) {
51653
51654             this[ event.type ]( event );
51655
51656         }
51657
51658     };
51659
51660     this.keydown = function( event ) {
51661
51662         if ( event.altKey ) {
51663
51664             return;
51665
51666         }
51667
51668         //event.preventDefault();
51669
51670         switch ( event.keyCode ) {
51671
51672             case 16: /* shift */ this.movementSpeedMultiplier = .1; break;
51673
51674             case 87: /*W*/ this.moveState.forward = 1; break;
51675             case 83: /*S*/ this.moveState.back = 1; break;
51676
51677             case 65: /*A*/ this.moveState.left = 1; break;
51678             case 68: /*D*/ this.moveState.right = 1; break;
51679
51680             case 82: /*R*/ this.moveState.up = 1; break;
51681             case 70: /*F*/ this.moveState.down = 1; break;
51682
51683             case 38: /*up*/ this.moveState.pitchUp = 1; break;
51684             case 40: /*down*/ this.moveState.pitchDown = 1; break;
51685
51686             case 37: /*left*/ this.moveState.yawLeft = 1; break;
51687             case 39: /*right*/ this.moveState.yawRight = 1; break;
51688
51689             case 81: /*Q*/ this.moveState.rollLeft = 1; break;
51690             case 69: /*E*/ this.moveState.rollRight = 1; break;
51691
51692         }
51693
51694         this.updateMovementVector();
51695         this.updateRotationVector();
51696
51697     };
51698
51699     this.keyup = function( event ) {
51700
51701         switch( event.keyCode ) {
51702
51703             case 16: /* shift */ this.movementSpeedMultiplier = 1; break;
51704
51705             case 87: /*W*/ this.moveState.forward = 0; break;
51706             case 83: /*S*/ this.moveState.back = 0; break;
51707
51708             case 65: /*A*/ this.moveState.left = 0; break;
51709             case 68: /*D*/ this.moveState.right = 0; break;
51710
51711             case 82: /*R*/ this.moveState.up = 0; break;
51712             case 70: /*F*/ this.moveState.down = 0; break;
51713
51714             case 38: /*up*/ this.moveState.pitchUp = 0; break;
51715             case 40: /*down*/ this.moveState.pitchDown = 0; break;
51716
51717             case 37: /*left*/ this.moveState.yawLeft = 0; break;
51718             case 39: /*right*/ this.moveState.yawRight = 0; break;
51719
51720             case 81: /*Q*/ this.moveState.rollLeft = 0; break;
51721             case 69: /*E*/ this.moveState.rollRight = 0; break;
51722
51723         }
51724
51725         this.updateMovementVector();
51726         this.updateRotationVector();
51727
51728     };
51729
51730     this.mousedown = function( event ) {
51731
51732         if ( this.domElement !== document ) {
51733
51734             this.domElement.focus();
51735
51736         }
51737
51738         event.preventDefault();
51739         event.stopPropagation();
51740
51741         if ( this.dragToLook ) {
51742
51743             this.mouseStatus ++;
51744
51745         } else {
51746
51747             switch ( event.button ) {
51748
51749                 case 0: this.object.moveForward = true; break;
51750                 case 2: this.object.moveBackward = true; break;
51751
51752             }
51753
51754         }
51755
51756     };
51757
51758     this.mousemove = function( event ) {
51759
51760         if ( !this.dragToLook || this.mouseStatus > 0 ) {
51761
51762             var container = this.getContainerDimensions();
51763             var halfWidth  = container.size[ 0 ] / 2;
51764             var halfHeight = container.size[ 1 ] / 2;
51765
51766             this.moveState.yawLeft   = - ( ( event.pageX - container.offset[ 0 ] ) - halfWidth  ) / halfWidth;
51767             this.moveState.pitchDown =   ( ( event.pageY - container.offset[ 1 ] ) - halfHeight ) / halfHeight;
51768
51769             this.updateRotationVector();
51770
51771         }
51772
51773     };
51774
51775     this.mouseup = function( event ) {
51776
51777         event.preventDefault();
51778         event.stopPropagation();
51779
51780         if ( this.dragToLook ) {
51781
51782             this.mouseStatus --;
51783
51784             this.moveState.yawLeft = this.moveState.pitchDown = 0;
51785
51786         } else {
51787
51788             switch ( event.button ) {
51789
51790                 case 0: this.moveForward = false; break;
51791                 case 2: this.moveBackward = false; break;
51792
51793             }
51794
51795         }
51796
51797         this.updateRotationVector();
51798
51799     };
51800
51801     this.update = function( delta ) {
51802
51803         var moveMult = delta * this.movementSpeed;
51804         var rotMult = delta * this.rollSpeed;
51805
51806         this.object.translateX( this.moveVector.x * moveMult );
51807         this.object.translateY( this.moveVector.y * moveMult );
51808         this.object.translateZ( this.moveVector.z * moveMult );
51809
51810         this.tmpQuaternion.set( this.rotationVector.x * rotMult, this.rotationVector.y * rotMult, this.rotationVector.z * rotMult, 1 ).normalize();
51811         this.object.quaternion.multiplySelf( this.tmpQuaternion );
51812
51813         this.object.matrix.setPosition( this.object.position );
51814         this.object.matrix.setRotationFromQuaternion( this.object.quaternion );
51815         this.object.matrixWorldNeedsUpdate = true;
51816
51817
51818     };
51819
51820     this.updateMovementVector = function() {
51821
51822         var forward = ( this.moveState.forward || ( this.autoForward && !this.moveState.back ) ) ? 1 : 0;
51823
51824         this.moveVector.x = ( -this.moveState.left    + this.moveState.right );
51825         this.moveVector.y = ( -this.moveState.down    + this.moveState.up );
51826         this.moveVector.z = ( -forward + this.moveState.back );
51827
51828         //console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] );
51829
51830     };
51831
51832     this.updateRotationVector = function() {
51833
51834         this.rotationVector.x = ( -this.moveState.pitchDown + this.moveState.pitchUp );
51835         this.rotationVector.y = ( -this.moveState.yawRight  + this.moveState.yawLeft );
51836         this.rotationVector.z = ( -this.moveState.rollRight + this.moveState.rollLeft );
51837
51838         //console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] );
51839
51840     };
51841
51842     this.getContainerDimensions = function() {
51843
51844         if ( this.domElement != document ) {
51845
51846             return {
51847                 size    : [ this.domElement.offsetWidth, this.domElement.offsetHeight ],
51848                 offset    : [ this.domElement.offsetLeft,  this.domElement.offsetTop ]
51849             };
51850
51851         } else {
51852
51853             return {
51854                 size    : [ window.innerWidth, window.innerHeight ],
51855                 offset    : [ 0, 0 ]
51856             };
51857
51858         }
51859
51860     };
51861
51862     function bind( scope, fn ) {
51863
51864         return function () {
51865
51866             fn.apply( scope, arguments );
51867
51868         };
51869
51870     };
51871
51872     this.domElement.addEventListener( 'mousemove', bind( this, this.mousemove ), false );
51873     this.domElement.addEventListener( 'mousedown', bind( this, this.mousedown ), false );
51874     this.domElement.addEventListener( 'mouseup',   bind( this, this.mouseup ), false );
51875
51876     this.domElement.addEventListener( 'keydown', bind( this, this.keydown ), false );
51877     this.domElement.addEventListener( 'keyup',   bind( this, this.keyup ), false );
51878
51879     this.updateMovementVector();
51880     this.updateRotationVector();
51881
51882 };
51883 /**
51884  * @author mikael emtinger / http://gomo.se/
51885  * @author alteredq / http://alteredqualia.com/
51886  */
51887
51888 THREE.RollControls = function ( object, domElement ) {
51889
51890     this.object = object;
51891     this.domElement = ( domElement !== undefined ) ? domElement : document;
51892
51893     // API
51894
51895     this.mouseLook = true;
51896     this.autoForward = false;
51897
51898     this.lookSpeed = 1;
51899     this.movementSpeed = 1;
51900     this.rollSpeed = 1;
51901
51902     this.constrainVertical = [ -0.9, 0.9 ];
51903
51904     // disable default target object behavior
51905
51906     this.object.matrixAutoUpdate = false;
51907
51908     // internals
51909
51910     this.forward = new THREE.Vector3( 0, 0, 1 );
51911     this.roll = 0;
51912
51913     var xTemp = new THREE.Vector3();
51914     var yTemp = new THREE.Vector3();
51915     var zTemp = new THREE.Vector3();
51916     var rollMatrix = new THREE.Matrix4();
51917
51918     var doRoll = false, rollDirection = 1, forwardSpeed = 0, sideSpeed = 0, upSpeed = 0;
51919
51920     var mouseX = 0, mouseY = 0;
51921
51922     var windowHalfX = 0;
51923     var windowHalfY = 0;
51924
51925     //
51926
51927     this.handleResize = function () {
51928
51929         windowHalfX = window.innerWidth / 2;
51930         windowHalfY = window.innerHeight / 2;
51931
51932     };
51933
51934     // custom update
51935
51936     this.update = function ( delta ) {
51937
51938         if ( this.mouseLook ) {
51939
51940             var actualLookSpeed = delta * this.lookSpeed;
51941
51942             this.rotateHorizontally( actualLookSpeed * mouseX );
51943             this.rotateVertically( actualLookSpeed * mouseY );
51944
51945         }
51946
51947         var actualSpeed = delta * this.movementSpeed;
51948         var forwardOrAuto = ( forwardSpeed > 0 || ( this.autoForward && ! ( forwardSpeed < 0 ) ) ) ? 1 : forwardSpeed;
51949
51950         this.object.translateZ( -actualSpeed * forwardOrAuto );
51951         this.object.translateX( actualSpeed * sideSpeed );
51952         this.object.translateY( actualSpeed * upSpeed );
51953
51954         if( doRoll ) {
51955
51956             this.roll += this.rollSpeed * delta * rollDirection;
51957
51958         }
51959
51960         // cap forward up / down
51961
51962         if( this.forward.y > this.constrainVertical[ 1 ] ) {
51963
51964             this.forward.y = this.constrainVertical[ 1 ];
51965             this.forward.normalize();
51966
51967         } else if( this.forward.y < this.constrainVertical[ 0 ] ) {
51968
51969             this.forward.y = this.constrainVertical[ 0 ];
51970             this.forward.normalize();
51971
51972         }
51973
51974
51975         // construct unrolled camera matrix
51976
51977         zTemp.copy( this.forward );
51978         yTemp.set( 0, 1, 0 );
51979
51980         xTemp.cross( yTemp, zTemp ).normalize();
51981         yTemp.cross( zTemp, xTemp ).normalize();
51982
51983         this.object.matrix.elements[0] = xTemp.x; this.object.matrix.elements[4] = yTemp.x; this.object.matrix.elements[8] = zTemp.x;
51984         this.object.matrix.elements[1] = xTemp.y; this.object.matrix.elements[5] = yTemp.y; this.object.matrix.elements[9] = zTemp.y;
51985         this.object.matrix.elements[2] = xTemp.z; this.object.matrix.elements[6] = yTemp.z; this.object.matrix.elements[10] = zTemp.z;
51986
51987         // calculate roll matrix
51988
51989         rollMatrix.identity();
51990         rollMatrix.elements[0] = Math.cos( this.roll ); rollMatrix.elements[4] = -Math.sin( this.roll );
51991         rollMatrix.elements[1] = Math.sin( this.roll ); rollMatrix.elements[5] =  Math.cos( this.roll );
51992
51993         // multiply camera with roll
51994
51995         this.object.matrix.multiplySelf( rollMatrix );
51996         this.object.matrixWorldNeedsUpdate = true;
51997
51998         // set position
51999
52000         this.object.matrix.elements[12] = this.object.position.x;
52001         this.object.matrix.elements[13] = this.object.position.y;
52002         this.object.matrix.elements[14] = this.object.position.z;
52003
52004
52005     };
52006
52007     this.translateX = function ( distance ) {
52008
52009         this.object.position.x += this.object.matrix.elements[0] * distance;
52010         this.object.position.y += this.object.matrix.elements[1] * distance;
52011         this.object.position.z += this.object.matrix.elements[2] * distance;
52012
52013     };
52014
52015     this.translateY = function ( distance ) {
52016
52017         this.object.position.x += this.object.matrix.elements[4] * distance;
52018         this.object.position.y += this.object.matrix.elements[5] * distance;
52019         this.object.position.z += this.object.matrix.elements[6] * distance;
52020
52021     };
52022
52023     this.translateZ = function ( distance ) {
52024
52025         this.object.position.x -= this.object.matrix.elements[8] * distance;
52026         this.object.position.y -= this.object.matrix.elements[9] * distance;
52027         this.object.position.z -= this.object.matrix.elements[10] * distance;
52028
52029     };
52030
52031
52032     this.rotateHorizontally = function ( amount ) {
52033
52034         // please note that the amount is NOT degrees, but a scale value
52035
52036         xTemp.set( this.object.matrix.elements[0], this.object.matrix.elements[1], this.object.matrix.elements[2] );
52037         xTemp.multiplyScalar( amount );
52038
52039         this.forward.subSelf( xTemp );
52040         this.forward.normalize();
52041
52042     };
52043
52044     this.rotateVertically = function ( amount ) {
52045
52046         // please note that the amount is NOT degrees, but a scale value
52047
52048         yTemp.set( this.object.matrix.elements[4], this.object.matrix.elements[5], this.object.matrix.elements[6] );
52049         yTemp.multiplyScalar( amount );
52050
52051         this.forward.addSelf( yTemp );
52052         this.forward.normalize();
52053
52054     };
52055
52056     function onKeyDown( event ) {
52057
52058         //event.preventDefault();
52059
52060         switch ( event.keyCode ) {
52061
52062             case 38: /*up*/
52063             case 87: /*W*/ forwardSpeed = 1; break;
52064
52065             case 37: /*left*/
52066             case 65: /*A*/ sideSpeed = -1; break;
52067
52068             case 40: /*down*/
52069             case 83: /*S*/ forwardSpeed = -1; break;
52070
52071             case 39: /*right*/
52072             case 68: /*D*/ sideSpeed = 1; break;
52073
52074             case 81: /*Q*/ doRoll = true; rollDirection = 1; break;
52075             case 69: /*E*/ doRoll = true; rollDirection = -1; break;
52076
52077             case 82: /*R*/ upSpeed = 1; break;
52078             case 70: /*F*/ upSpeed = -1; break;
52079
52080         }
52081
52082     };
52083
52084     function onKeyUp( event ) {
52085
52086         switch( event.keyCode ) {
52087
52088             case 38: /*up*/
52089             case 87: /*W*/ forwardSpeed = 0; break;
52090
52091             case 37: /*left*/
52092             case 65: /*A*/ sideSpeed = 0; break;
52093
52094             case 40: /*down*/
52095             case 83: /*S*/ forwardSpeed = 0; break;
52096
52097             case 39: /*right*/
52098             case 68: /*D*/ sideSpeed = 0; break;
52099
52100             case 81: /*Q*/ doRoll = false; break;
52101             case 69: /*E*/ doRoll = false; break;
52102
52103             case 82: /*R*/ upSpeed = 0; break;
52104             case 70: /*F*/ upSpeed = 0; break;
52105
52106         }
52107
52108     };
52109
52110     function onMouseMove( event ) {
52111
52112         mouseX = ( event.clientX - windowHalfX ) / window.innerWidth;
52113         mouseY = ( event.clientY - windowHalfY ) / window.innerHeight;
52114
52115     };
52116
52117     function onMouseDown ( event ) {
52118
52119         event.preventDefault();
52120         event.stopPropagation();
52121
52122         switch ( event.button ) {
52123
52124             case 0: forwardSpeed = 1; break;
52125             case 2: forwardSpeed = -1; break;
52126
52127         }
52128
52129     };
52130
52131     function onMouseUp ( event ) {
52132
52133         event.preventDefault();
52134         event.stopPropagation();
52135
52136         switch ( event.button ) {
52137
52138             case 0: forwardSpeed = 0; break;
52139             case 2: forwardSpeed = 0; break;
52140
52141         }
52142
52143     };
52144
52145     this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
52146
52147     this.domElement.addEventListener( 'mousemove', onMouseMove, false );
52148     this.domElement.addEventListener( 'mousedown', onMouseDown, false );
52149     this.domElement.addEventListener( 'mouseup', onMouseUp, false );
52150     this.domElement.addEventListener( 'keydown', onKeyDown, false );
52151     this.domElement.addEventListener( 'keyup', onKeyUp, false );
52152
52153     this.handleResize();
52154
52155 };
52156 /**
52157  * @author Eberhard Graether / http://egraether.com/
52158  */
52159
52160 THREE.TrackballControls = function ( object, domElement ) {
52161
52162     THREE.EventTarget.call( this );
52163
52164     var _this = this,
52165     STATE = { NONE : -1, ROTATE : 0, ZOOM : 1, PAN : 2 };
52166
52167     this.object = object;
52168     this.domElement = ( domElement !== undefined ) ? domElement : document;
52169
52170     // API
52171
52172     this.enabled = true;
52173
52174     this.screen = { width: 0, height: 0, offsetLeft: 0, offsetTop: 0 };
52175     this.radius = ( this.screen.width + this.screen.height ) / 4;
52176
52177     this.rotateSpeed = 1.0;
52178     this.zoomSpeed = 1.2;
52179     this.panSpeed = 0.3;
52180
52181     this.noRotate = false;
52182     this.noZoom = false;
52183     this.noPan = false;
52184
52185     this.staticMoving = false;
52186     this.dynamicDampingFactor = 0.2;
52187
52188     this.minDistance = 0;
52189     this.maxDistance = Infinity;
52190
52191     this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
52192
52193     // internals
52194
52195     this.target = new THREE.Vector3();
52196
52197     var lastPosition = new THREE.Vector3();
52198
52199     var _keyPressed = false,
52200     _state = STATE.NONE,
52201
52202     _eye = new THREE.Vector3(),
52203
52204     _rotateStart = new THREE.Vector3(),
52205     _rotateEnd = new THREE.Vector3(),
52206
52207     _zoomStart = new THREE.Vector2(),
52208     _zoomEnd = new THREE.Vector2(),
52209
52210     _panStart = new THREE.Vector2(),
52211     _panEnd = new THREE.Vector2();
52212
52213     // events
52214
52215     var changeEvent = { type: 'change' };
52216
52217
52218     // methods
52219
52220     this.handleResize = function () {
52221
52222         this.screen.width = window.innerWidth;
52223         this.screen.height = window.innerHeight;
52224
52225         this.screen.offsetLeft = 0;
52226         this.screen.offsetTop = 0;
52227
52228         this.radius = ( this.screen.width + this.screen.height ) / 4;
52229     };
52230
52231     this.handleEvent = function ( event ) {
52232
52233         if ( typeof this[ event.type ] == 'function' ) {
52234
52235             this[ event.type ]( event );
52236
52237         }
52238
52239     };
52240
52241     this.getMouseOnScreen = function ( clientX, clientY ) {
52242
52243         return new THREE.Vector2(
52244             ( clientX - _this.screen.offsetLeft ) / _this.radius * 0.5,
52245             ( clientY - _this.screen.offsetTop ) / _this.radius * 0.5
52246         );
52247
52248     };
52249
52250     this.getMouseProjectionOnBall = function ( clientX, clientY ) {
52251
52252         var mouseOnBall = new THREE.Vector3(
52253             ( clientX - _this.screen.width * 0.5 - _this.screen.offsetLeft ) / _this.radius,
52254             ( _this.screen.height * 0.5 + _this.screen.offsetTop - clientY ) / _this.radius,
52255             0.0
52256         );
52257
52258         var length = mouseOnBall.length();
52259
52260         if ( length > 1.0 ) {
52261
52262             mouseOnBall.normalize();
52263
52264         } else {
52265
52266             mouseOnBall.z = Math.sqrt( 1.0 - length * length );
52267
52268         }
52269
52270         _eye.copy( _this.object.position ).subSelf( _this.target );
52271
52272         var projection = _this.object.up.clone().setLength( mouseOnBall.y );
52273         projection.addSelf( _this.object.up.clone().crossSelf( _eye ).setLength( mouseOnBall.x ) );
52274         projection.addSelf( _eye.setLength( mouseOnBall.z ) );
52275
52276         return projection;
52277
52278     };
52279
52280     this.rotateCamera = function () {
52281
52282         var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
52283
52284         if ( angle ) {
52285
52286             var axis = ( new THREE.Vector3() ).cross( _rotateStart, _rotateEnd ).normalize(),
52287                 quaternion = new THREE.Quaternion();
52288
52289             angle *= _this.rotateSpeed;
52290
52291             quaternion.setFromAxisAngle( axis, -angle );
52292
52293             quaternion.multiplyVector3( _eye );
52294             quaternion.multiplyVector3( _this.object.up );
52295
52296             quaternion.multiplyVector3( _rotateEnd );
52297
52298             if ( _this.staticMoving ) {
52299
52300                 _rotateStart.copy( _rotateEnd );
52301
52302             } else {
52303
52304                 quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
52305                 quaternion.multiplyVector3( _rotateStart );
52306
52307             }
52308
52309         }
52310
52311     };
52312
52313     this.zoomCamera = function () {
52314
52315         var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;
52316
52317         if ( factor !== 1.0 && factor > 0.0 ) {
52318
52319             _eye.multiplyScalar( factor );
52320
52321             if ( _this.staticMoving ) {
52322
52323                 _zoomStart.copy( _zoomEnd );
52324
52325             } else {
52326
52327                 _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
52328
52329             }
52330
52331         }
52332
52333     };
52334
52335     this.panCamera = function () {
52336
52337         var mouseChange = _panEnd.clone().subSelf( _panStart );
52338
52339         if ( mouseChange.lengthSq() ) {
52340
52341             mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
52342
52343             var pan = _eye.clone().crossSelf( _this.object.up ).setLength( mouseChange.x );
52344             pan.addSelf( _this.object.up.clone().setLength( mouseChange.y ) );
52345
52346             _this.object.position.addSelf( pan );
52347             _this.target.addSelf( pan );
52348
52349             if ( _this.staticMoving ) {
52350
52351                 _panStart = _panEnd;
52352
52353             } else {
52354
52355                 _panStart.addSelf( mouseChange.sub( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
52356
52357             }
52358
52359         }
52360
52361     };
52362
52363     this.checkDistances = function () {
52364
52365         if ( !_this.noZoom || !_this.noPan ) {
52366
52367             if ( _this.object.position.lengthSq() > _this.maxDistance * _this.maxDistance ) {
52368
52369                 _this.object.position.setLength( _this.maxDistance );
52370
52371             }
52372
52373             if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) {
52374
52375                 _this.object.position.add( _this.target, _eye.setLength( _this.minDistance ) );
52376
52377             }
52378
52379         }
52380
52381     };
52382
52383     this.update = function () {
52384
52385         _eye.copy( _this.object.position ).subSelf( _this.target );
52386
52387         if ( !_this.noRotate ) {
52388
52389             _this.rotateCamera();
52390
52391         }
52392
52393         if ( !_this.noZoom ) {
52394
52395             _this.zoomCamera();
52396
52397         }
52398
52399         if ( !_this.noPan ) {
52400
52401             _this.panCamera();
52402
52403         }
52404
52405         _this.object.position.add( _this.target, _eye );
52406
52407         _this.checkDistances();
52408
52409         _this.object.lookAt( _this.target );
52410
52411         if ( lastPosition.distanceToSquared( _this.object.position ) > 0 ) {
52412
52413             _this.dispatchEvent( changeEvent );
52414
52415             lastPosition.copy( _this.object.position );
52416
52417         }
52418
52419     };
52420
52421     // listeners
52422
52423     function keydown( event ) {
52424
52425         if ( ! _this.enabled ) return;
52426
52427         //event.preventDefault();
52428
52429         if ( _state !== STATE.NONE ) {
52430
52431             return;
52432
52433         } else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && !_this.noRotate ) {
52434
52435             _state = STATE.ROTATE;
52436
52437         } else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && !_this.noZoom ) {
52438
52439             _state = STATE.ZOOM;
52440
52441         } else if ( event.keyCode === _this.keys[ STATE.PAN ] && !_this.noPan ) {
52442
52443             _state = STATE.PAN;
52444
52445         }
52446
52447         if ( _state !== STATE.NONE ) {
52448
52449             _keyPressed = true;
52450
52451         }
52452
52453     }
52454
52455     function keyup( event ) {
52456
52457         if ( ! _this.enabled ) return;
52458
52459         if ( _state !== STATE.NONE ) {
52460
52461             _state = STATE.NONE;
52462
52463         }
52464
52465     }
52466
52467     function mousedown( event ) {
52468
52469         if ( ! _this.enabled ) return;
52470
52471         event.preventDefault();
52472         event.stopPropagation();
52473
52474         if ( _state === STATE.NONE ) {
52475
52476             _state = event.button;
52477
52478             if ( _state === STATE.ROTATE && !_this.noRotate ) {
52479
52480                 _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
52481
52482             } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
52483
52484                 _zoomStart = _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52485
52486             } else if ( !this.noPan ) {
52487
52488                 _panStart = _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52489
52490             }
52491
52492         }
52493
52494     }
52495
52496     function mousemove( event ) {
52497
52498         if ( ! _this.enabled ) return;
52499
52500         if ( _keyPressed ) {
52501
52502             _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
52503             _zoomStart = _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52504             _panStart = _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52505
52506             _keyPressed = false;
52507
52508         }
52509
52510         if ( _state === STATE.NONE ) {
52511
52512             return;
52513
52514         } else if ( _state === STATE.ROTATE && !_this.noRotate ) {
52515
52516             _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
52517
52518         } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
52519
52520             _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52521
52522         } else if ( _state === STATE.PAN && !_this.noPan ) {
52523
52524             _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52525
52526         }
52527
52528     }
52529
52530     function mouseup( event ) {
52531
52532         if ( ! _this.enabled ) return;
52533
52534         event.preventDefault();
52535         event.stopPropagation();
52536
52537         _state = STATE.NONE;
52538
52539     }
52540
52541     function mousewheel( event ) {
52542
52543         if ( ! _this.enabled ) return;
52544
52545         event.preventDefault();
52546         event.stopPropagation();
52547
52548         var delta = 0;
52549
52550         if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
52551
52552             delta = event.wheelDelta / 40;
52553
52554         } else if ( event.detail ) { // Firefox
52555
52556             delta = - event.detail / 3;
52557
52558         }
52559
52560         _zoomStart.y += ( 1 / delta ) * 0.05;
52561
52562     }
52563
52564     this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
52565
52566     this.domElement.addEventListener( 'mousemove', mousemove, false );
52567     this.domElement.addEventListener( 'mousedown', mousedown, false );
52568     this.domElement.addEventListener( 'mouseup', mouseup, false );
52569     this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false );
52570     this.domElement.addEventListener( 'mousewheel', mousewheel, false );
52571
52572     window.addEventListener( 'keydown', keydown, false );
52573     window.addEventListener( 'keyup', keyup, false );
52574
52575     this.handleResize();
52576
52577 };
52578 /**
52579  * @author qiao / https://github.com/qiao
52580  * @author mrdoob / http://mrdoob.com
52581  * @author alteredq / http://alteredqualia.com/
52582  */
52583
52584 THREE.OrbitControls = function ( object, domElement ) {
52585
52586     THREE.EventTarget.call( this );
52587
52588     this.object = object;
52589     this.domElement = ( domElement !== undefined ) ? domElement : document;
52590
52591     // API
52592
52593     this.center = new THREE.Vector3();
52594
52595     this.userZoom = true;
52596     this.userZoomSpeed = 1.0;
52597
52598     this.userRotate = true;
52599     this.userRotateSpeed = 1.0;
52600
52601     this.autoRotate = false;
52602     this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
52603
52604     // internals
52605
52606     var scope = this;
52607
52608     var EPS = 0.000001;
52609     var PIXELS_PER_ROUND = 1800;
52610
52611     var rotateStart = new THREE.Vector2();
52612     var rotateEnd = new THREE.Vector2();
52613     var rotateDelta = new THREE.Vector2();
52614
52615     var zoomStart = new THREE.Vector2();
52616     var zoomEnd = new THREE.Vector2();
52617     var zoomDelta = new THREE.Vector2();
52618
52619     var phiDelta = 0;
52620     var thetaDelta = 0;
52621     var scale = 1;
52622
52623     var lastPosition = new THREE.Vector3();
52624
52625     var STATE = { NONE : -1, ROTATE : 0, ZOOM : 1 };
52626     var state = STATE.NONE;
52627
52628     // events
52629
52630     var changeEvent = { type: 'change' };
52631
52632
52633     this.rotateLeft = function ( angle ) {
52634
52635         if ( angle === undefined ) {
52636
52637             angle = getAutoRotationAngle();
52638
52639         }
52640
52641         thetaDelta -= angle;
52642
52643     };
52644
52645     this.rotateRight = function ( angle ) {
52646
52647         if ( angle === undefined ) {
52648
52649             angle = getAutoRotationAngle();
52650
52651         }
52652
52653         thetaDelta += angle;
52654
52655     };
52656
52657     this.rotateUp = function ( angle ) {
52658
52659         if ( angle === undefined ) {
52660
52661             angle = getAutoRotationAngle();
52662
52663         }
52664
52665         phiDelta -= angle;
52666
52667     };
52668
52669     this.rotateDown = function ( angle ) {
52670
52671         if ( angle === undefined ) {
52672
52673             angle = getAutoRotationAngle();
52674
52675         }
52676
52677         phiDelta += angle;
52678
52679     };
52680
52681     this.zoomIn = function ( zoomScale ) {
52682
52683         if ( zoomScale === undefined ) {
52684
52685             zoomScale = getZoomScale();
52686
52687         }
52688
52689         scale /= zoomScale;
52690
52691     };
52692
52693     this.zoomOut = function ( zoomScale ) {
52694
52695         if ( zoomScale === undefined ) {
52696
52697             zoomScale = getZoomScale();
52698
52699         }
52700
52701         scale *= zoomScale;
52702
52703     };
52704
52705     this.update = function () {
52706
52707         var position = this.object.position;
52708         var offset = position.clone().subSelf( this.center )
52709
52710         // angle from z-axis around y-axis
52711
52712         var theta = Math.atan2( offset.x, offset.z );
52713
52714         // angle from y-axis
52715
52716         var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
52717
52718         if ( this.autoRotate ) {
52719
52720             this.rotateLeft( getAutoRotationAngle() );
52721
52722         }
52723
52724         theta += thetaDelta;
52725         phi += phiDelta;
52726
52727         // restrict phi to be betwee EPS and PI-EPS
52728
52729         phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
52730
52731         var radius = offset.length();
52732         offset.x = radius * Math.sin( phi ) * Math.sin( theta );
52733         offset.y = radius * Math.cos( phi );
52734         offset.z = radius * Math.sin( phi ) * Math.cos( theta );
52735         offset.multiplyScalar( scale );
52736
52737         position.copy( this.center ).addSelf( offset );
52738
52739         this.object.lookAt( this.center );
52740
52741         thetaDelta = 0;
52742         phiDelta = 0;
52743         scale = 1;
52744
52745         if ( lastPosition.distanceTo( this.object.position ) > 0 ) {
52746
52747             this.dispatchEvent( changeEvent );
52748
52749             lastPosition.copy( this.object.position );
52750
52751         }
52752
52753     };
52754
52755
52756     function getAutoRotationAngle() {
52757
52758         return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
52759
52760     }
52761
52762     function getZoomScale() {
52763
52764         return Math.pow( 0.95, scope.userZoomSpeed );
52765
52766     }
52767
52768     function onMouseDown( event ) {
52769
52770         if ( !scope.userRotate ) return;
52771
52772         event.preventDefault();
52773
52774         if ( event.button === 0 || event.button === 2 ) {
52775
52776             state = STATE.ROTATE;
52777
52778             rotateStart.set( event.clientX, event.clientY );
52779
52780         } else if ( event.button === 1 ) {
52781
52782             state = STATE.ZOOM;
52783
52784             zoomStart.set( event.clientX, event.clientY );
52785
52786         }
52787
52788         document.addEventListener( 'mousemove', onMouseMove, false );
52789         document.addEventListener( 'mouseup', onMouseUp, false );
52790
52791     }
52792
52793     function onMouseMove( event ) {
52794
52795         event.preventDefault();
52796
52797         if ( state === STATE.ROTATE ) {
52798
52799             rotateEnd.set( event.clientX, event.clientY );
52800             rotateDelta.sub( rotateEnd, rotateStart );
52801
52802             scope.rotateLeft( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * scope.userRotateSpeed );
52803             scope.rotateUp( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * scope.userRotateSpeed );
52804
52805             rotateStart.copy( rotateEnd );
52806
52807         } else if ( state === STATE.ZOOM ) {
52808
52809             zoomEnd.set( event.clientX, event.clientY );
52810             zoomDelta.sub( zoomEnd, zoomStart );
52811
52812             if ( zoomDelta.y > 0 ) {
52813
52814                 scope.zoomIn();
52815
52816             } else {
52817
52818                 scope.zoomOut();
52819
52820             }
52821
52822             zoomStart.copy( zoomEnd );
52823
52824         }
52825
52826     }
52827
52828     function onMouseUp( event ) {
52829
52830         if ( ! scope.userRotate ) return;
52831
52832         document.removeEventListener( 'mousemove', onMouseMove, false );
52833         document.removeEventListener( 'mouseup', onMouseUp, false );
52834
52835         state = STATE.NONE;
52836
52837     }
52838
52839     function onMouseWheel( event ) {
52840
52841         if ( ! scope.userZoom ) return;
52842
52843         if ( event.wheelDelta > 0 ) {
52844
52845             scope.zoomOut();
52846
52847         } else {
52848
52849             scope.zoomIn();
52850
52851         }
52852
52853     }
52854
52855     this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
52856     this.domElement.addEventListener( 'mousedown', onMouseDown, false );
52857     this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
52858
52859 };
52860 /**
52861  * @author hughes
52862  */
52863
52864 THREE.CircleGeometry = function ( radius, segments, thetaStart, thetaLength ) {
52865
52866     THREE.Geometry.call( this );
52867
52868     radius = radius || 50;
52869
52870     thetaStart = thetaStart !== undefined ? thetaStart : 0;
52871     thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
52872     segments = segments !== undefined ? Math.max( 3, segments ) : 8;
52873
52874     var i, uvs = [],
52875     center = new THREE.Vector3(), centerUV = new THREE.UV( 0.5, 0.5 );
52876
52877     this.vertices.push(center);
52878     uvs.push( centerUV );
52879
52880     for ( i = 0; i <= segments; i ++ ) {
52881
52882         var vertex = new THREE.Vector3();
52883
52884         vertex.x = radius * Math.cos( thetaStart + i / segments * thetaLength );
52885         vertex.y = radius * Math.sin( thetaStart + i / segments * thetaLength );
52886
52887         this.vertices.push( vertex );
52888         uvs.push( new THREE.UV( ( vertex.x / radius + 1 ) / 2, - ( vertex.y / radius + 1 ) / 2 + 1 ) );
52889
52890     }
52891
52892     var n = new THREE.Vector3( 0, 0, -1 );
52893
52894     for ( i = 1; i <= segments; i ++ ) {
52895
52896         var v1 = i;
52897         var v2 = i + 1 ;
52898         var v3 = 0;
52899
52900         this.faces.push( new THREE.Face3( v1, v2, v3, [ n, n, n ] ) );
52901         this.faceVertexUvs[ 0 ].push( [ uvs[ i ], uvs[ i + 1 ], centerUV ] );
52902
52903     }
52904
52905     this.computeCentroids();
52906     this.computeFaceNormals();
52907
52908     this.boundingSphere = { radius: radius };
52909
52910 };
52911
52912 THREE.CircleGeometry.prototype = Object.create( THREE.Geometry.prototype );
52913 /**
52914  * @author mrdoob / http://mrdoob.com/
52915  * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as
52916  */
52917
52918 THREE.CubeGeometry = function ( width, height, depth, segmentsWidth, segmentsHeight, segmentsDepth, materials, sides ) {
52919
52920     THREE.Geometry.call( this );
52921
52922     var scope = this,
52923     width_half = width / 2,
52924     height_half = height / 2,
52925     depth_half = depth / 2;
52926
52927     var mpx, mpy, mpz, mnx, mny, mnz;
52928
52929     if ( materials !== undefined ) {
52930
52931         if ( materials instanceof Array ) {
52932
52933             this.materials = materials;
52934
52935         } else {
52936
52937             this.materials = [];
52938
52939             for ( var i = 0; i < 6; i ++ ) {
52940
52941                 this.materials.push( materials );
52942
52943             }
52944
52945         }
52946
52947         mpx = 0; mnx = 1; mpy = 2; mny = 3; mpz = 4; mnz = 5;
52948
52949     } else {
52950
52951         this.materials = [];
52952
52953     }
52954
52955     this.sides = { px: true, nx: true, py: true, ny: true, pz: true, nz: true };
52956
52957     if ( sides != undefined ) {
52958
52959         for ( var s in sides ) {
52960
52961             if ( this.sides[ s ] !== undefined ) {
52962
52963                 this.sides[ s ] = sides[ s ];
52964
52965             }
52966
52967         }
52968
52969     }
52970
52971     this.sides.px && buildPlane( 'z', 'y', - 1, - 1, depth, height, width_half, mpx ); // px
52972     this.sides.nx && buildPlane( 'z', 'y',   1, - 1, depth, height, - width_half, mnx ); // nx
52973     this.sides.py && buildPlane( 'x', 'z',   1,   1, width, depth, height_half, mpy ); // py
52974     this.sides.ny && buildPlane( 'x', 'z',   1, - 1, width, depth, - height_half, mny ); // ny
52975     this.sides.pz && buildPlane( 'x', 'y',   1, - 1, width, height, depth_half, mpz ); // pz
52976     this.sides.nz && buildPlane( 'x', 'y', - 1, - 1, width, height, - depth_half, mnz ); // nz
52977
52978     function buildPlane( u, v, udir, vdir, width, height, depth, material ) {
52979
52980         var w, ix, iy,
52981         gridX = segmentsWidth || 1,
52982         gridY = segmentsHeight || 1,
52983         width_half = width / 2,
52984         height_half = height / 2,
52985         offset = scope.vertices.length;
52986
52987         if ( ( u === 'x' && v === 'y' ) || ( u === 'y' && v === 'x' ) ) {
52988
52989             w = 'z';
52990
52991         } else if ( ( u === 'x' && v === 'z' ) || ( u === 'z' && v === 'x' ) ) {
52992
52993             w = 'y';
52994             gridY = segmentsDepth || 1;
52995
52996         } else if ( ( u === 'z' && v === 'y' ) || ( u === 'y' && v === 'z' ) ) {
52997
52998             w = 'x';
52999             gridX = segmentsDepth || 1;
53000
53001         }
53002
53003         var gridX1 = gridX + 1,
53004         gridY1 = gridY + 1,
53005         segment_width = width / gridX,
53006         segment_height = height / gridY,
53007         normal = new THREE.Vector3();
53008
53009         normal[ w ] = depth > 0 ? 1 : - 1;
53010
53011         for ( iy = 0; iy < gridY1; iy ++ ) {
53012
53013             for ( ix = 0; ix < gridX1; ix ++ ) {
53014
53015                 var vector = new THREE.Vector3();
53016                 vector[ u ] = ( ix * segment_width - width_half ) * udir;
53017                 vector[ v ] = ( iy * segment_height - height_half ) * vdir;
53018                 vector[ w ] = depth;
53019
53020                 scope.vertices.push( vector );
53021
53022             }
53023
53024         }
53025
53026         for ( iy = 0; iy < gridY; iy++ ) {
53027
53028             for ( ix = 0; ix < gridX; ix++ ) {
53029
53030                 var a = ix + gridX1 * iy;
53031                 var b = ix + gridX1 * ( iy + 1 );
53032                 var c = ( ix + 1 ) + gridX1 * ( iy + 1 );
53033                 var d = ( ix + 1 ) + gridX1 * iy;
53034
53035                 var face = new THREE.Face4( a + offset, b + offset, c + offset, d + offset );
53036                 face.normal.copy( normal );
53037                 face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone(), normal.clone() );
53038                 face.materialIndex = material;
53039
53040                 scope.faces.push( face );
53041                 scope.faceVertexUvs[ 0 ].push( [
53042                             new THREE.UV( ix / gridX, 1 - iy / gridY ),
53043                             new THREE.UV( ix / gridX, 1 - ( iy + 1 ) / gridY ),
53044                             new THREE.UV( ( ix + 1 ) / gridX, 1- ( iy + 1 ) / gridY ),
53045                             new THREE.UV( ( ix + 1 ) / gridX, 1 - iy / gridY )
53046                         ] );
53047
53048             }
53049
53050         }
53051
53052     }
53053
53054     this.computeCentroids();
53055     this.mergeVertices();
53056
53057 };
53058
53059 THREE.CubeGeometry.prototype = Object.create( THREE.Geometry.prototype );
53060 /**
53061  * @author mrdoob / http://mrdoob.com/
53062  */
53063
53064 THREE.CylinderGeometry = function ( radiusTop, radiusBottom, height, segmentsRadius, segmentsHeight, openEnded ) {
53065
53066     THREE.Geometry.call( this );
53067
53068     radiusTop = radiusTop !== undefined ? radiusTop : 20;
53069     radiusBottom = radiusBottom !== undefined ? radiusBottom : 20;
53070     height = height !== undefined ? height : 100;
53071
53072     var heightHalf = height / 2;
53073     var segmentsX = segmentsRadius || 8;
53074     var segmentsY = segmentsHeight || 1;
53075
53076     var x, y, vertices = [], uvs = [];
53077
53078     for ( y = 0; y <= segmentsY; y ++ ) {
53079
53080         var verticesRow = [];
53081         var uvsRow = [];
53082
53083         var v = y / segmentsY;
53084         var radius = v * ( radiusBottom - radiusTop ) + radiusTop;
53085
53086         for ( x = 0; x <= segmentsX; x ++ ) {
53087
53088             var u = x / segmentsX;
53089
53090             var vertex = new THREE.Vector3();
53091             vertex.x = radius * Math.sin( u * Math.PI * 2 );
53092             vertex.y = - v * height + heightHalf;
53093             vertex.z = radius * Math.cos( u * Math.PI * 2 );
53094
53095             this.vertices.push( vertex );
53096
53097             verticesRow.push( this.vertices.length - 1 );
53098             uvsRow.push( new THREE.UV( u, 1 - v ) );
53099
53100         }
53101
53102         vertices.push( verticesRow );
53103         uvs.push( uvsRow );
53104
53105     }
53106
53107     var tanTheta = ( radiusBottom - radiusTop ) / height;
53108     var na, nb;
53109
53110     for ( x = 0; x < segmentsX; x ++ ) {
53111
53112         if ( radiusTop !== 0 ) {
53113
53114             na = this.vertices[ vertices[ 0 ][ x ] ].clone();
53115             nb = this.vertices[ vertices[ 0 ][ x + 1 ] ].clone();
53116
53117         } else {
53118
53119             na = this.vertices[ vertices[ 1 ][ x ] ].clone();
53120             nb = this.vertices[ vertices[ 1 ][ x + 1 ] ].clone();
53121
53122         }
53123
53124         na.setY( Math.sqrt( na.x * na.x + na.z * na.z ) * tanTheta ).normalize();
53125         nb.setY( Math.sqrt( nb.x * nb.x + nb.z * nb.z ) * tanTheta ).normalize();
53126
53127         for ( y = 0; y < segmentsY; y ++ ) {
53128
53129             var v1 = vertices[ y ][ x ];
53130             var v2 = vertices[ y + 1 ][ x ];
53131             var v3 = vertices[ y + 1 ][ x + 1 ];
53132             var v4 = vertices[ y ][ x + 1 ];
53133
53134             var n1 = na.clone();
53135             var n2 = na.clone();
53136             var n3 = nb.clone();
53137             var n4 = nb.clone();
53138
53139             var uv1 = uvs[ y ][ x ].clone();
53140             var uv2 = uvs[ y + 1 ][ x ].clone();
53141             var uv3 = uvs[ y + 1 ][ x + 1 ].clone();
53142             var uv4 = uvs[ y ][ x + 1 ].clone();
53143
53144             this.faces.push( new THREE.Face4( v1, v2, v3, v4, [ n1, n2, n3, n4 ] ) );
53145             this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3, uv4 ] );
53146
53147         }
53148
53149     }
53150
53151     // top cap
53152
53153     if ( !openEnded && radiusTop > 0 ) {
53154
53155         this.vertices.push( new THREE.Vector3( 0, heightHalf, 0 ) );
53156
53157         for ( x = 0; x < segmentsX; x ++ ) {
53158
53159             var v1 = vertices[ 0 ][ x ];
53160             var v2 = vertices[ 0 ][ x + 1 ];
53161             var v3 = this.vertices.length - 1;
53162
53163             var n1 = new THREE.Vector3( 0, 1, 0 );
53164             var n2 = new THREE.Vector3( 0, 1, 0 );
53165             var n3 = new THREE.Vector3( 0, 1, 0 );
53166
53167             var uv1 = uvs[ 0 ][ x ].clone();
53168             var uv2 = uvs[ 0 ][ x + 1 ].clone();
53169             var uv3 = new THREE.UV( uv2.u, 0 );
53170
53171             this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) );
53172             this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] );
53173
53174         }
53175
53176     }
53177
53178     // bottom cap
53179
53180     if ( !openEnded && radiusBottom > 0 ) {
53181
53182         this.vertices.push( new THREE.Vector3( 0, - heightHalf, 0 ) );
53183
53184         for ( x = 0; x < segmentsX; x ++ ) {
53185
53186             var v1 = vertices[ y ][ x + 1 ];
53187             var v2 = vertices[ y ][ x ];
53188             var v3 = this.vertices.length - 1;
53189
53190             var n1 = new THREE.Vector3( 0, - 1, 0 );
53191             var n2 = new THREE.Vector3( 0, - 1, 0 );
53192             var n3 = new THREE.Vector3( 0, - 1, 0 );
53193
53194             var uv1 = uvs[ y ][ x + 1 ].clone();
53195             var uv2 = uvs[ y ][ x ].clone();
53196             var uv3 = new THREE.UV( uv2.u, 1 );
53197
53198             this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) );
53199             this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] );
53200
53201         }
53202
53203     }
53204
53205     this.computeCentroids();
53206     this.computeFaceNormals();
53207
53208 }
53209
53210 THREE.CylinderGeometry.prototype = Object.create( THREE.Geometry.prototype );
53211 /**
53212  * @author zz85 / http://www.lab4games.net/zz85/blog
53213  *
53214  * Creates extruded geometry from a path shape.
53215  *
53216  * parameters = {
53217  *
53218  *  size: <float>, // size of the text
53219  *  height: <float>, // thickness to extrude text
53220  *  curveSegments: <int>, // number of points on the curves
53221  *  steps: <int>, // number of points for z-side extrusions / used for subdividing segements of extrude spline too
53222  *  amount: <int>, // Amount
53223  *
53224  *  bevelEnabled: <bool>, // turn on bevel
53225  *  bevelThickness: <float>, // how deep into text bevel goes
53226  *  bevelSize: <float>, // how far from text outline is bevel
53227  *  bevelSegments: <int>, // number of bevel layers
53228  *
53229  *  extrudePath: <THREE.CurvePath> // 3d spline path to extrude shape along. (creates Frames if .frames aren't defined)
53230  *  frames: <THREE.TubeGeometry.FrenetFrames> // containing arrays of tangents, normals, binormals
53231  *
53232  *  material: <int> // material index for front and back faces
53233  *  extrudeMaterial: <int> // material index for extrusion and beveled faces
53234  *  uvGenerator: <Object> // object that provides UV generator functions
53235  *
53236  * }
53237  **/
53238
53239 THREE.ExtrudeGeometry = function ( shapes, options ) {
53240
53241     if ( typeof( shapes ) === "undefined" ) {
53242         shapes = [];
53243         return;
53244     }
53245
53246     THREE.Geometry.call( this );
53247
53248     shapes = shapes instanceof Array ? shapes : [ shapes ];
53249
53250     this.shapebb = shapes[ shapes.length - 1 ].getBoundingBox();
53251
53252     this.addShapeList( shapes, options );
53253
53254     this.computeCentroids();
53255     this.computeFaceNormals();
53256
53257     // can't really use automatic vertex normals
53258     // as then front and back sides get smoothed too
53259     // should do separate smoothing just for sides
53260
53261     //this.computeVertexNormals();
53262
53263     //console.log( "took", ( Date.now() - startTime ) );
53264
53265 };
53266
53267 THREE.ExtrudeGeometry.prototype = Object.create( THREE.Geometry.prototype );
53268
53269 THREE.ExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {
53270     var sl = shapes.length;
53271
53272     for ( var s = 0; s < sl; s ++ ) {
53273         var shape = shapes[ s ];
53274         this.addShape( shape, options );
53275     }
53276 };
53277
53278 THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
53279
53280     var amount = options.amount !== undefined ? options.amount : 100;
53281
53282     var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10
53283     var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8
53284     var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
53285
53286     var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false
53287
53288     var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
53289
53290     var steps = options.steps !== undefined ? options.steps : 1;
53291
53292     var extrudePath = options.extrudePath;
53293     var extrudePts, extrudeByPath = false;
53294
53295     var material = options.material;
53296     var extrudeMaterial = options.extrudeMaterial;
53297
53298     // Use default WorldUVGenerator if no UV generators are specified.
53299     var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : THREE.ExtrudeGeometry.WorldUVGenerator;
53300
53301     var shapebb = this.shapebb;
53302     //shapebb = shape.getBoundingBox();
53303
53304
53305
53306     var splineTube, binormal, normal, position2;
53307     if ( extrudePath ) {
53308
53309         extrudePts = extrudePath.getSpacedPoints( steps );
53310
53311         extrudeByPath = true;
53312         bevelEnabled = false; // bevels not supported for path extrusion
53313
53314         // SETUP TNB variables
53315
53316         // Reuse TNB from TubeGeomtry for now.
53317         // TODO1 - have a .isClosed in spline?
53318
53319         splineTube = options.frames !== undefined ? options.frames : new THREE.TubeGeometry.FrenetFrames(extrudePath, steps, false);
53320
53321         // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
53322
53323         binormal = new THREE.Vector3();
53324         normal = new THREE.Vector3();
53325         position2 = new THREE.Vector3();
53326
53327     }
53328
53329     // Safeguards if bevels are not enabled
53330
53331     if ( ! bevelEnabled ) {
53332
53333         bevelSegments = 0;
53334         bevelThickness = 0;
53335         bevelSize = 0;
53336
53337     }
53338
53339     // Variables initalization
53340
53341     var ahole, h, hl; // looping of holes
53342     var scope = this;
53343     var bevelPoints = [];
53344
53345     var shapesOffset = this.vertices.length;
53346
53347     var shapePoints = shape.extractPoints();
53348
53349     var vertices = shapePoints.shape;
53350     var holes = shapePoints.holes;
53351
53352     var reverse = !THREE.Shape.Utils.isClockWise( vertices ) ;
53353
53354     if ( reverse ) {
53355
53356         vertices = vertices.reverse();
53357
53358         // Maybe we should also check if holes are in the opposite direction, just to be safe ...
53359
53360         for ( h = 0, hl = holes.length; h < hl; h ++ ) {
53361
53362             ahole = holes[ h ];
53363
53364             if ( THREE.Shape.Utils.isClockWise( ahole ) ) {
53365
53366                 holes[ h ] = ahole.reverse();
53367
53368             }
53369
53370         }
53371
53372         reverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!
53373
53374     }
53375
53376
53377     var faces = THREE.Shape.Utils.triangulateShape ( vertices, holes );
53378
53379     /* Vertices */
53380
53381     var contour = vertices; // vertices has all points but contour has only points of circumference
53382
53383     for ( h = 0, hl = holes.length;  h < hl; h ++ ) {
53384
53385         ahole = holes[ h ];
53386
53387         vertices = vertices.concat( ahole );
53388
53389     }
53390
53391
53392     function scalePt2 ( pt, vec, size ) {
53393
53394         if ( !vec ) console.log( "die" );
53395
53396         return vec.clone().multiplyScalar( size ).addSelf( pt );
53397
53398     }
53399
53400     var b, bs, t, z,
53401         vert, vlen = vertices.length,
53402         face, flen = faces.length,
53403         cont, clen = contour.length;
53404
53405
53406     // Find directions for point movement
53407
53408     var RAD_TO_DEGREES = 180 / Math.PI;
53409
53410
53411     function getBevelVec( pt_i, pt_j, pt_k ) {
53412
53413         // Algorithm 2
53414
53415         return getBevelVec2( pt_i, pt_j, pt_k );
53416
53417     }
53418
53419     function getBevelVec1( pt_i, pt_j, pt_k ) {
53420
53421         var anglea = Math.atan2( pt_j.y - pt_i.y, pt_j.x - pt_i.x );
53422         var angleb = Math.atan2( pt_k.y - pt_i.y, pt_k.x - pt_i.x );
53423
53424         if ( anglea > angleb ) {
53425
53426             angleb += Math.PI * 2;
53427
53428         }
53429
53430         var anglec = ( anglea + angleb ) / 2;
53431
53432
53433         //console.log('angle1', anglea * RAD_TO_DEGREES,'angle2', angleb * RAD_TO_DEGREES, 'anglec', anglec *RAD_TO_DEGREES);
53434
53435         var x = - Math.cos( anglec );
53436         var y = - Math.sin( anglec );
53437
53438         var vec = new THREE.Vector2( x, y ); //.normalize();
53439
53440         return vec;
53441
53442     }
53443
53444     function getBevelVec2( pt_i, pt_j, pt_k ) {
53445
53446         var a = THREE.ExtrudeGeometry.__v1,
53447             b = THREE.ExtrudeGeometry.__v2,
53448             v_hat = THREE.ExtrudeGeometry.__v3,
53449             w_hat = THREE.ExtrudeGeometry.__v4,
53450             p = THREE.ExtrudeGeometry.__v5,
53451             q = THREE.ExtrudeGeometry.__v6,
53452             v, w,
53453             v_dot_w_hat, q_sub_p_dot_w_hat,
53454             s, intersection;
53455
53456         // good reading for line-line intersection
53457         // http://sputsoft.com/blog/2010/03/line-line-intersection.html
53458
53459         // define a as vector j->i
53460         // define b as vectot k->i
53461
53462         a.set( pt_i.x - pt_j.x, pt_i.y - pt_j.y );
53463         b.set( pt_i.x - pt_k.x, pt_i.y - pt_k.y );
53464
53465         // get unit vectors
53466
53467         v = a.normalize();
53468         w = b.normalize();
53469
53470         // normals from pt i
53471
53472         v_hat.set( -v.y, v.x );
53473         w_hat.set( w.y, -w.x );
53474
53475         // pts from i
53476
53477         p.copy( pt_i ).addSelf( v_hat );
53478         q.copy( pt_i ).addSelf( w_hat );
53479
53480         if ( p.equals( q ) ) {
53481
53482             //console.log("Warning: lines are straight");
53483             return w_hat.clone();
53484
53485         }
53486
53487         // Points from j, k. helps prevents points cross overover most of the time
53488
53489         p.copy( pt_j ).addSelf( v_hat );
53490         q.copy( pt_k ).addSelf( w_hat );
53491
53492         v_dot_w_hat = v.dot( w_hat );
53493         q_sub_p_dot_w_hat = q.subSelf( p ).dot( w_hat );
53494
53495         // We should not reach these conditions
53496
53497         if ( v_dot_w_hat === 0 ) {
53498
53499             console.log( "Either infinite or no solutions!" );
53500
53501             if ( q_sub_p_dot_w_hat === 0 ) {
53502
53503                 console.log( "Its finite solutions." );
53504
53505             } else {
53506
53507                 console.log( "Too bad, no solutions." );
53508
53509             }
53510
53511         }
53512
53513         s = q_sub_p_dot_w_hat / v_dot_w_hat;
53514
53515         if ( s < 0 ) {
53516
53517             // in case of emergecy, revert to algorithm 1.
53518
53519             return getBevelVec1( pt_i, pt_j, pt_k );
53520
53521         }
53522
53523         intersection = v.multiplyScalar( s ).addSelf( p );
53524
53525         return intersection.subSelf( pt_i ).clone(); // Don't normalize!, otherwise sharp corners become ugly
53526
53527     }
53528
53529     var contourMovements = [];
53530
53531     for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
53532
53533         if ( j === il ) j = 0;
53534         if ( k === il ) k = 0;
53535
53536         //  (j)---(i)---(k)
53537         // console.log('i,j,k', i, j , k)
53538
53539         var pt_i = contour[ i ];
53540         var pt_j = contour[ j ];
53541         var pt_k = contour[ k ];
53542
53543         contourMovements[ i ]= getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
53544
53545     }
53546
53547     var holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();
53548
53549     for ( h = 0, hl = holes.length; h < hl; h ++ ) {
53550
53551         ahole = holes[ h ];
53552
53553         oneHoleMovements = [];
53554
53555         for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
53556
53557             if ( j === il ) j = 0;
53558             if ( k === il ) k = 0;
53559
53560             //  (j)---(i)---(k)
53561             oneHoleMovements[ i ]= getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
53562
53563         }
53564
53565         holesMovements.push( oneHoleMovements );
53566         verticesMovements = verticesMovements.concat( oneHoleMovements );
53567
53568     }
53569
53570
53571     // Loop bevelSegments, 1 for the front, 1 for the back
53572
53573     for ( b = 0; b < bevelSegments; b ++ ) {
53574     //for ( b = bevelSegments; b > 0; b -- ) {
53575
53576         t = b / bevelSegments;
53577         z = bevelThickness * ( 1 - t );
53578
53579         //z = bevelThickness * t;
53580         bs = bevelSize * ( Math.sin ( t * Math.PI/2 ) ) ; // curved
53581         //bs = bevelSize * t ; // linear
53582
53583         // contract shape
53584
53585         for ( i = 0, il = contour.length; i < il; i ++ ) {
53586
53587             vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
53588             //vert = scalePt( contour[ i ], contourCentroid, bs, false );
53589             v( vert.x, vert.y,  - z );
53590
53591         }
53592
53593         // expand holes
53594
53595         for ( h = 0, hl = holes.length; h < hl; h++ ) {
53596
53597             ahole = holes[ h ];
53598             oneHoleMovements = holesMovements[ h ];
53599
53600             for ( i = 0, il = ahole.length; i < il; i++ ) {
53601
53602                 vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
53603                 //vert = scalePt( ahole[ i ], holesCentroids[ h ], bs, true );
53604
53605                 v( vert.x, vert.y,  -z );
53606
53607             }
53608
53609         }
53610
53611     }
53612
53613     bs = bevelSize;
53614
53615     // Back facing vertices
53616
53617     for ( i = 0; i < vlen; i ++ ) {
53618
53619         vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
53620
53621         if ( !extrudeByPath ) {
53622
53623             v( vert.x, vert.y, 0 );
53624
53625         } else {
53626
53627             // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
53628
53629             normal.copy( splineTube.normals[0] ).multiplyScalar(vert.x);
53630             binormal.copy( splineTube.binormals[0] ).multiplyScalar(vert.y);
53631
53632             position2.copy( extrudePts[0] ).addSelf(normal).addSelf(binormal);
53633
53634             v( position2.x, position2.y, position2.z );
53635
53636         }
53637
53638     }
53639
53640     // Add stepped vertices...
53641     // Including front facing vertices
53642
53643     var s;
53644
53645     for ( s = 1; s <= steps; s ++ ) {
53646
53647         for ( i = 0; i < vlen; i ++ ) {
53648
53649             vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
53650
53651             if ( !extrudeByPath ) {
53652
53653                 v( vert.x, vert.y, amount / steps * s );
53654
53655             } else {
53656
53657                 // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
53658
53659                 normal.copy( splineTube.normals[s] ).multiplyScalar( vert.x );
53660                 binormal.copy( splineTube.binormals[s] ).multiplyScalar( vert.y );
53661
53662                 position2.copy( extrudePts[s] ).addSelf( normal ).addSelf( binormal );
53663
53664                 v( position2.x, position2.y, position2.z );
53665
53666             }
53667
53668         }
53669
53670     }
53671
53672
53673     // Add bevel segments planes
53674
53675     //for ( b = 1; b <= bevelSegments; b ++ ) {
53676     for ( b = bevelSegments - 1; b >= 0; b -- ) {
53677
53678         t = b / bevelSegments;
53679         z = bevelThickness * ( 1 - t );
53680         //bs = bevelSize * ( 1-Math.sin ( ( 1 - t ) * Math.PI/2 ) );
53681         bs = bevelSize * Math.sin ( t * Math.PI/2 ) ;
53682
53683         // contract shape
53684
53685         for ( i = 0, il = contour.length; i < il; i ++ ) {
53686
53687             vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
53688             v( vert.x, vert.y,  amount + z );
53689
53690         }
53691
53692         // expand holes
53693
53694         for ( h = 0, hl = holes.length; h < hl; h ++ ) {
53695
53696             ahole = holes[ h ];
53697             oneHoleMovements = holesMovements[ h ];
53698
53699             for ( i = 0, il = ahole.length; i < il; i ++ ) {
53700
53701                 vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
53702
53703                 if ( !extrudeByPath ) {
53704
53705                     v( vert.x, vert.y,  amount + z );
53706
53707                 } else {
53708
53709                     v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );
53710
53711                 }
53712
53713             }
53714
53715         }
53716
53717     }
53718
53719     /* Faces */
53720
53721     // Top and bottom faces
53722
53723     buildLidFaces();
53724
53725     // Sides faces
53726
53727     buildSideFaces();
53728
53729
53730     /////  Internal functions
53731
53732     function buildLidFaces() {
53733
53734         if ( bevelEnabled ) {
53735
53736             var layer = 0 ; // steps + 1
53737             var offset = vlen * layer;
53738
53739             // Bottom faces
53740
53741             for ( i = 0; i < flen; i ++ ) {
53742
53743                 face = faces[ i ];
53744                 f3( face[ 2 ]+ offset, face[ 1 ]+ offset, face[ 0 ] + offset, true );
53745
53746             }
53747
53748             layer = steps + bevelSegments * 2;
53749             offset = vlen * layer;
53750
53751             // Top faces
53752
53753             for ( i = 0; i < flen; i ++ ) {
53754
53755                 face = faces[ i ];
53756                 f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset, false );
53757
53758             }
53759
53760         } else {
53761
53762             // Bottom faces
53763
53764             for ( i = 0; i < flen; i++ ) {
53765
53766                 face = faces[ i ];
53767                 f3( face[ 2 ], face[ 1 ], face[ 0 ], true );
53768
53769             }
53770
53771             // Top faces
53772
53773             for ( i = 0; i < flen; i ++ ) {
53774
53775                 face = faces[ i ];
53776                 f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps, false );
53777
53778             }
53779         }
53780
53781     }
53782
53783     // Create faces for the z-sides of the shape
53784
53785     function buildSideFaces() {
53786
53787         var layeroffset = 0;
53788         sidewalls( contour, layeroffset );
53789         layeroffset += contour.length;
53790
53791         for ( h = 0, hl = holes.length;  h < hl; h ++ ) {
53792
53793             ahole = holes[ h ];
53794             sidewalls( ahole, layeroffset );
53795
53796             //, true
53797             layeroffset += ahole.length;
53798
53799         }
53800
53801     }
53802
53803     function sidewalls( contour, layeroffset ) {
53804
53805         var j, k;
53806         i = contour.length;
53807
53808         while ( --i >= 0 ) {
53809
53810             j = i;
53811             k = i - 1;
53812             if ( k < 0 ) k = contour.length - 1;
53813
53814             //console.log('b', i,j, i-1, k,vertices.length);
53815
53816             var s = 0, sl = steps  + bevelSegments * 2;
53817
53818             for ( s = 0; s < sl; s ++ ) {
53819
53820                 var slen1 = vlen * s;
53821                 var slen2 = vlen * ( s + 1 );
53822
53823                 var a = layeroffset + j + slen1,
53824                     b = layeroffset + k + slen1,
53825                     c = layeroffset + k + slen2,
53826                     d = layeroffset + j + slen2;
53827
53828                 f4( a, b, c, d, contour, s, sl, j, k );
53829
53830             }
53831         }
53832
53833     }
53834
53835
53836     function v( x, y, z ) {
53837
53838         scope.vertices.push( new THREE.Vector3( x, y, z ) );
53839
53840     }
53841
53842     function f3( a, b, c, isBottom ) {
53843
53844         a += shapesOffset;
53845         b += shapesOffset;
53846         c += shapesOffset;
53847
53848         // normal, color, material
53849         scope.faces.push( new THREE.Face3( a, b, c, null, null, material ) );
53850
53851         var uvs = isBottom ? uvgen.generateBottomUV( scope, shape, options, a, b, c ) : uvgen.generateTopUV( scope, shape, options, a, b, c );
53852
53853          scope.faceVertexUvs[ 0 ].push( uvs );
53854
53855     }
53856
53857     function f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {
53858
53859         a += shapesOffset;
53860         b += shapesOffset;
53861         c += shapesOffset;
53862         d += shapesOffset;
53863
53864          scope.faces.push( new THREE.Face4( a, b, c, d, null, null, extrudeMaterial ) );
53865
53866          var uvs = uvgen.generateSideWallUV( scope, shape, wallContour, options, a, b, c, d,
53867                                              stepIndex, stepsLength, contourIndex1, contourIndex2 );
53868          scope.faceVertexUvs[ 0 ].push( uvs );
53869
53870     }
53871
53872 };
53873
53874 THREE.ExtrudeGeometry.WorldUVGenerator = {
53875
53876     generateTopUV: function( geometry, extrudedShape, extrudeOptions, indexA, indexB, indexC ) {
53877         var ax = geometry.vertices[ indexA ].x,
53878             ay = geometry.vertices[ indexA ].y,
53879
53880             bx = geometry.vertices[ indexB ].x,
53881             by = geometry.vertices[ indexB ].y,
53882
53883             cx = geometry.vertices[ indexC ].x,
53884             cy = geometry.vertices[ indexC ].y;
53885
53886         return [
53887             new THREE.UV( ax, ay ),
53888             new THREE.UV( bx, by ),
53889             new THREE.UV( cx, cy )
53890         ];
53891
53892     },
53893
53894     generateBottomUV: function( geometry, extrudedShape, extrudeOptions, indexA, indexB, indexC ) {
53895
53896         return this.generateTopUV( geometry, extrudedShape, extrudeOptions, indexA, indexB, indexC );
53897
53898     },
53899
53900     generateSideWallUV: function( geometry, extrudedShape, wallContour, extrudeOptions,
53901                                   indexA, indexB, indexC, indexD, stepIndex, stepsLength,
53902                                   contourIndex1, contourIndex2 ) {
53903
53904         var ax = geometry.vertices[ indexA ].x,
53905             ay = geometry.vertices[ indexA ].y,
53906             az = geometry.vertices[ indexA ].z,
53907
53908             bx = geometry.vertices[ indexB ].x,
53909             by = geometry.vertices[ indexB ].y,
53910             bz = geometry.vertices[ indexB ].z,
53911
53912             cx = geometry.vertices[ indexC ].x,
53913             cy = geometry.vertices[ indexC ].y,
53914             cz = geometry.vertices[ indexC ].z,
53915
53916             dx = geometry.vertices[ indexD ].x,
53917             dy = geometry.vertices[ indexD ].y,
53918             dz = geometry.vertices[ indexD ].z;
53919
53920         if ( Math.abs( ay - by ) < 0.01 ) {
53921             return [
53922                 new THREE.UV( ax, 1 - az ),
53923                 new THREE.UV( bx, 1 - bz ),
53924                 new THREE.UV( cx, 1 - cz ),
53925                 new THREE.UV( dx, 1 - dz )
53926             ];
53927         } else {
53928             return [
53929                 new THREE.UV( ay, 1 - az ),
53930                 new THREE.UV( by, 1 - bz ),
53931                 new THREE.UV( cy, 1 - cz ),
53932                 new THREE.UV( dy, 1 - dz )
53933             ];
53934         }
53935     }
53936 };
53937
53938 THREE.ExtrudeGeometry.__v1 = new THREE.Vector2();
53939 THREE.ExtrudeGeometry.__v2 = new THREE.Vector2();
53940 THREE.ExtrudeGeometry.__v3 = new THREE.Vector2();
53941 THREE.ExtrudeGeometry.__v4 = new THREE.Vector2();
53942 THREE.ExtrudeGeometry.__v5 = new THREE.Vector2();
53943 THREE.ExtrudeGeometry.__v6 = new THREE.Vector2();
53944 /**
53945  * @author jonobr1 / http://jonobr1.com
53946  *
53947  * Creates a one-sided polygonal geometry from a path shape. Similar to
53948  * ExtrudeGeometry.
53949  *
53950  * parameters = {
53951  *
53952  *    curveSegments: <int>, // number of points on the curves. NOT USED AT THE MOMENT.
53953  *
53954  *    material: <int> // material index for front and back faces
53955  *    uvGenerator: <Object> // object that provides UV generator functions
53956  *
53957  * }
53958  **/
53959
53960 THREE.ShapeGeometry = function ( shapes, options ) {
53961
53962     THREE.Geometry.call( this );
53963
53964     if ( shapes instanceof Array === false ) shapes = [ shapes ];
53965
53966     this.shapebb = shapes[ shapes.length - 1 ].getBoundingBox();
53967
53968     this.addShapeList( shapes, options );
53969
53970     this.computeCentroids();
53971     this.computeFaceNormals();
53972
53973 };
53974
53975 THREE.ShapeGeometry.prototype = Object.create( THREE.Geometry.prototype );
53976
53977 /**
53978  * Add an array of shapes to THREE.ShapeGeometry.
53979  */
53980 THREE.ShapeGeometry.prototype.addShapeList = function ( shapes, options ) {
53981
53982     for ( var i = 0, l = shapes.length; i < l; i++ ) {
53983
53984         this.addShape( shapes[ i ], options );
53985
53986     }
53987
53988     return this;
53989
53990 };
53991
53992 /**
53993  * Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry.
53994  */
53995 THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) {
53996
53997     if ( options === undefined ) options = {};
53998
53999     var material = options.material;
54000     var uvgen = options.UVGenerator === undefined ? THREE.ExtrudeGeometry.WorldUVGenerator : options.UVGenerator;
54001
54002     var shapebb = this.shapebb;
54003
54004     //
54005
54006     var i, l, hole, s;
54007
54008     var shapesOffset = this.vertices.length;
54009     var shapePoints = shape.extractPoints();
54010
54011     var vertices = shapePoints.shape;
54012     var holes = shapePoints.holes;
54013
54014     var reverse = !THREE.Shape.Utils.isClockWise( vertices );
54015
54016     if ( reverse ) {
54017
54018         vertices = vertices.reverse();
54019
54020         // Maybe we should also check if holes are in the opposite direction, just to be safe...
54021
54022         for ( i = 0, l = holes.length; i < l; i++ ) {
54023
54024             hole = holes[ i ];
54025
54026             if ( THREE.Shape.Utils.isClockWise( hole ) ) {
54027
54028                 holes[ i ] = hole.reverse();
54029
54030             }
54031
54032         }
54033
54034         reverse = false;
54035
54036     }
54037
54038     var faces = THREE.Shape.Utils.triangulateShape( vertices, holes );
54039
54040     // Vertices
54041
54042     var contour = vertices;
54043
54044     for ( i = 0, l = holes.length; i < l; i++ ) {
54045
54046         hole = holes[ i ];
54047         vertices = vertices.concat( hole );
54048
54049     }
54050
54051     //
54052
54053     var vert, vlen = vertices.length;
54054     var face, flen = faces.length;
54055     var cont, clen = contour.length;
54056
54057     for ( i = 0; i < vlen; i++ ) {
54058
54059         vert = vertices[ i ];
54060
54061         this.vertices.push( new THREE.Vector3( vert.x, vert.y, 0 ) );
54062
54063     }
54064
54065     for ( i = 0; i < flen; i++ ) {
54066
54067         face = faces[ i ];
54068
54069         var a = face[ 2 ] + shapesOffset;
54070         var b = face[ 1 ] + shapesOffset;
54071         var c = face[ 0 ] + shapesOffset;
54072
54073         this.faces.push( new THREE.Face3( a, b, c, null, null, material ) );
54074         this.faceVertexUvs[ 0 ].push( uvgen.generateBottomUV( this, shape, options, a, b, c ) );
54075
54076     }
54077
54078 };
54079 /**
54080  * @author astrodud / http://astrodud.isgreat.org/
54081  * @author zz85 / https://github.com/zz85
54082  */
54083
54084 THREE.LatheGeometry = function ( points, steps, angle ) {
54085
54086     THREE.Geometry.call( this );
54087
54088     var _steps = steps || 12;
54089     var _angle = angle || 2 * Math.PI;
54090
54091     var _newV = [];
54092     var _matrix = new THREE.Matrix4().makeRotationZ( _angle / _steps );
54093
54094     for ( var j = 0; j < points.length; j ++ ) {
54095
54096         _newV[ j ] = points[ j ].clone();
54097         this.vertices.push( _newV[ j ] );
54098
54099     }
54100
54101     var i, il = _steps + 1;
54102
54103     for ( i = 0; i < il; i ++ ) {
54104
54105         for ( var j = 0; j < _newV.length; j ++ ) {
54106
54107             _newV[ j ] = _matrix.multiplyVector3( _newV[ j ].clone() );
54108             this.vertices.push( _newV[ j ] );
54109
54110         }
54111
54112     }
54113
54114     for ( i = 0; i < _steps; i ++ ) {
54115
54116         for ( var k = 0, kl = points.length; k < kl - 1; k ++ ) {
54117
54118             var a = i * kl + k;
54119             var b = ( ( i + 1 ) % il ) * kl + k;
54120             var c = ( ( i + 1 ) % il ) * kl + ( k + 1 ) % kl;
54121             var d = i * kl + ( k + 1 ) % kl;
54122
54123             this.faces.push( new THREE.Face4( a, b, c, d ) );
54124
54125             this.faceVertexUvs[ 0 ].push( [
54126
54127                 new THREE.UV( 1 - i / _steps, k / kl ),
54128                 new THREE.UV( 1 - ( i + 1 ) / _steps, k / kl ),
54129                 new THREE.UV( 1 - ( i + 1 ) / _steps, ( k + 1 ) / kl ),
54130                 new THREE.UV( 1 - i / _steps, ( k + 1 ) / kl )
54131
54132             ] );
54133
54134         }
54135
54136     }
54137
54138     this.computeCentroids();
54139     this.computeFaceNormals();
54140     this.computeVertexNormals();
54141
54142 };
54143
54144 THREE.LatheGeometry.prototype = Object.create( THREE.Geometry.prototype );
54145 /**
54146  * @author mrdoob / http://mrdoob.com/
54147  * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as
54148  */
54149
54150 THREE.PlaneGeometry = function ( width, height, segmentsWidth, segmentsheight ) {
54151
54152     THREE.Geometry.call( this );
54153
54154     var ix, iz,
54155     width_half = width / 2,
54156     height_half = height / 2,
54157     gridX = segmentsWidth || 1,
54158     gridZ = segmentsheight || 1,
54159     gridX1 = gridX + 1,
54160     gridZ1 = gridZ + 1,
54161     segment_width = width / gridX,
54162     segment_height = height / gridZ,
54163     normal = new THREE.Vector3( 0, 0, 1 );
54164
54165     for ( iz = 0; iz < gridZ1; iz ++ ) {
54166
54167         for ( ix = 0; ix < gridX1; ix ++ ) {
54168
54169             var x = ix * segment_width - width_half;
54170             var y = iz * segment_height - height_half;
54171
54172             this.vertices.push( new THREE.Vector3( x, - y, 0 ) );
54173
54174         }
54175
54176     }
54177
54178     for ( iz = 0; iz < gridZ; iz ++ ) {
54179
54180         for ( ix = 0; ix < gridX; ix ++ ) {
54181
54182             var a = ix + gridX1 * iz;
54183             var b = ix + gridX1 * ( iz + 1 );
54184             var c = ( ix + 1 ) + gridX1 * ( iz + 1 );
54185             var d = ( ix + 1 ) + gridX1 * iz;
54186
54187             var face = new THREE.Face4( a, b, c, d );
54188             face.normal.copy( normal );
54189             face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone(), normal.clone() );
54190
54191             this.faces.push( face );
54192             this.faceVertexUvs[ 0 ].push( [
54193                 new THREE.UV( ix / gridX, 1 - iz / gridZ ),
54194                 new THREE.UV( ix / gridX, 1 - ( iz + 1 ) / gridZ ),
54195                 new THREE.UV( ( ix + 1 ) / gridX, 1 - ( iz + 1 ) / gridZ ),
54196                 new THREE.UV( ( ix + 1 ) / gridX, 1 - iz / gridZ )
54197             ] );
54198
54199         }
54200
54201     }
54202
54203     this.computeCentroids();
54204
54205 };
54206
54207 THREE.PlaneGeometry.prototype = Object.create( THREE.Geometry.prototype );
54208 /**
54209  * @author mrdoob / http://mrdoob.com/
54210  */
54211
54212 THREE.SphereGeometry = function ( radius, segmentsWidth, segmentsHeight, phiStart, phiLength, thetaStart, thetaLength ) {
54213
54214     THREE.Geometry.call( this );
54215
54216     radius = radius || 50;
54217
54218     phiStart = phiStart !== undefined ? phiStart : 0;
54219     phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
54220
54221     thetaStart = thetaStart !== undefined ? thetaStart : 0;
54222     thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
54223
54224     var segmentsX = Math.max( 3, Math.floor( segmentsWidth ) || 8 );
54225     var segmentsY = Math.max( 2, Math.floor( segmentsHeight ) || 6 );
54226
54227     var x, y, vertices = [], uvs = [];
54228
54229     for ( y = 0; y <= segmentsY; y ++ ) {
54230
54231         var verticesRow = [];
54232         var uvsRow = [];
54233
54234         for ( x = 0; x <= segmentsX; x ++ ) {
54235
54236             var u = x / segmentsX;
54237             var v = y / segmentsY;
54238
54239             var vertex = new THREE.Vector3();
54240             vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
54241             vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
54242             vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
54243
54244             this.vertices.push( vertex );
54245
54246             verticesRow.push( this.vertices.length - 1 );
54247             uvsRow.push( new THREE.UV( u, 1 - v ) );
54248
54249         }
54250
54251         vertices.push( verticesRow );
54252         uvs.push( uvsRow );
54253
54254     }
54255
54256     for ( y = 0; y < segmentsY; y ++ ) {
54257
54258         for ( x = 0; x < segmentsX; x ++ ) {
54259
54260             var v1 = vertices[ y ][ x + 1 ];
54261             var v2 = vertices[ y ][ x ];
54262             var v3 = vertices[ y + 1 ][ x ];
54263             var v4 = vertices[ y + 1 ][ x + 1 ];
54264
54265             var n1 = this.vertices[ v1 ].clone().normalize();
54266             var n2 = this.vertices[ v2 ].clone().normalize();
54267             var n3 = this.vertices[ v3 ].clone().normalize();
54268             var n4 = this.vertices[ v4 ].clone().normalize();
54269
54270             var uv1 = uvs[ y ][ x + 1 ].clone();
54271             var uv2 = uvs[ y ][ x ].clone();
54272             var uv3 = uvs[ y + 1 ][ x ].clone();
54273             var uv4 = uvs[ y + 1 ][ x + 1 ].clone();
54274
54275             if ( Math.abs( this.vertices[ v1 ].y ) == radius ) {
54276
54277                 this.faces.push( new THREE.Face3( v1, v3, v4, [ n1, n3, n4 ] ) );
54278                 this.faceVertexUvs[ 0 ].push( [ uv1, uv3, uv4 ] );
54279
54280             } else if ( Math.abs( this.vertices[ v3 ].y ) ==  radius ) {
54281
54282                 this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) );
54283                 this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] );
54284
54285             } else {
54286
54287                 this.faces.push( new THREE.Face4( v1, v2, v3, v4, [ n1, n2, n3, n4 ] ) );
54288                 this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3, uv4 ] );
54289
54290             }
54291
54292         }
54293
54294     }
54295
54296     this.computeCentroids();
54297     this.computeFaceNormals();
54298
54299     this.boundingSphere = { radius: radius };
54300
54301 };
54302
54303 THREE.SphereGeometry.prototype = Object.create( THREE.Geometry.prototype );
54304 /**
54305  * @author zz85 / http://www.lab4games.net/zz85/blog
54306  * @author alteredq / http://alteredqualia.com/
54307  *
54308  * For creating 3D text geometry in three.js
54309  *
54310  * Text = 3D Text
54311  *
54312  * parameters = {
54313  *  size:             <float>,     // size of the text
54314  *  height:         <float>,     // thickness to extrude text
54315  *  curveSegments:     <int>,        // number of points on the curves
54316  *
54317  *  font:             <string>,        // font name
54318  *  weight:         <string>,        // font weight (normal, bold)
54319  *  style:             <string>,        // font style  (normal, italics)
54320  *
54321  *  bevelEnabled:    <bool>,            // turn on bevel
54322  *  bevelThickness: <float>,         // how deep into text bevel goes
54323  *  bevelSize:        <float>,         // how far from text outline is bevel
54324  *  }
54325  *
54326  */
54327
54328 /*    Usage Examples
54329
54330     // TextGeometry wrapper
54331
54332     var text3d = new TextGeometry( text, options );
54333
54334     // Complete manner
54335
54336     var textShapes = THREE.FontUtils.generateShapes( text, options );
54337     var text3d = new ExtrudeGeometry( textShapes, options );
54338
54339 */
54340
54341
54342 THREE.TextGeometry = function ( text, parameters ) {
54343
54344     var textShapes = THREE.FontUtils.generateShapes( text, parameters );
54345
54346     // translate parameters to ExtrudeGeometry API
54347
54348     parameters.amount = parameters.height !== undefined ? parameters.height : 50;
54349
54350     // defaults
54351
54352     if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
54353     if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
54354     if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
54355
54356     THREE.ExtrudeGeometry.call( this, textShapes, parameters );
54357
54358 };
54359
54360 THREE.TextGeometry.prototype = Object.create( THREE.ExtrudeGeometry.prototype );
54361 /**
54362  * @author oosmoxiecode
54363  * @author mrdoob / http://mrdoob.com/
54364  * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888
54365  */
54366
54367 THREE.TorusGeometry = function ( radius, tube, segmentsR, segmentsT, arc ) {
54368
54369     THREE.Geometry.call( this );
54370
54371     var scope = this;
54372
54373     this.radius = radius || 100;
54374     this.tube = tube || 40;
54375     this.segmentsR = segmentsR || 8;
54376     this.segmentsT = segmentsT || 6;
54377     this.arc = arc || Math.PI * 2;
54378
54379     var center = new THREE.Vector3(), uvs = [], normals = [];
54380
54381     for ( var j = 0; j <= this.segmentsR; j ++ ) {
54382
54383         for ( var i = 0; i <= this.segmentsT; i ++ ) {
54384
54385             var u = i / this.segmentsT * this.arc;
54386             var v = j / this.segmentsR * Math.PI * 2;
54387
54388             center.x = this.radius * Math.cos( u );
54389             center.y = this.radius * Math.sin( u );
54390
54391             var vertex = new THREE.Vector3();
54392             vertex.x = ( this.radius + this.tube * Math.cos( v ) ) * Math.cos( u );
54393             vertex.y = ( this.radius + this.tube * Math.cos( v ) ) * Math.sin( u );
54394             vertex.z = this.tube * Math.sin( v );
54395
54396             this.vertices.push( vertex );
54397
54398             uvs.push( new THREE.UV( i / this.segmentsT, j / this.segmentsR ) );
54399             normals.push( vertex.clone().subSelf( center ).normalize() );
54400
54401         }
54402     }
54403
54404
54405     for ( var j = 1; j <= this.segmentsR; j ++ ) {
54406
54407         for ( var i = 1; i <= this.segmentsT; i ++ ) {
54408
54409             var a = ( this.segmentsT + 1 ) * j + i - 1;
54410             var b = ( this.segmentsT + 1 ) * ( j - 1 ) + i - 1;
54411             var c = ( this.segmentsT + 1 ) * ( j - 1 ) + i;
54412             var d = ( this.segmentsT + 1 ) * j + i;
54413
54414             var face = new THREE.Face4( a, b, c, d, [ normals[ a ], normals[ b ], normals[ c ], normals[ d ] ] );
54415             face.normal.addSelf( normals[ a ] );
54416             face.normal.addSelf( normals[ b ] );
54417             face.normal.addSelf( normals[ c ] );
54418             face.normal.addSelf( normals[ d ] );
54419             face.normal.normalize();
54420
54421             this.faces.push( face );
54422
54423             this.faceVertexUvs[ 0 ].push( [ uvs[ a ].clone(), uvs[ b ].clone(), uvs[ c ].clone(), uvs[ d ].clone() ] );
54424         }
54425
54426     }
54427
54428     this.computeCentroids();
54429
54430 };
54431
54432 THREE.TorusGeometry.prototype = Object.create( THREE.Geometry.prototype );
54433 /**
54434  * @author oosmoxiecode
54435  * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
54436  */
54437
54438 THREE.TorusKnotGeometry = function ( radius, tube, segmentsR, segmentsT, p, q, heightScale ) {
54439
54440     THREE.Geometry.call( this );
54441
54442     var scope = this;
54443
54444     this.radius = radius || 200;
54445     this.tube = tube || 40;
54446     this.segmentsR = segmentsR || 64;
54447     this.segmentsT = segmentsT || 8;
54448     this.p = p || 2;
54449     this.q = q || 3;
54450     this.heightScale = heightScale || 1;
54451     this.grid = new Array(this.segmentsR);
54452
54453     var tang = new THREE.Vector3();
54454     var n = new THREE.Vector3();
54455     var bitan = new THREE.Vector3();
54456
54457     for ( var i = 0; i < this.segmentsR; ++ i ) {
54458
54459         this.grid[ i ] = new Array( this.segmentsT );
54460
54461         for ( var j = 0; j < this.segmentsT; ++ j ) {
54462
54463             var u = i / this.segmentsR * 2 * this.p * Math.PI;
54464             var v = j / this.segmentsT * 2 * Math.PI;
54465             var p1 = getPos( u, v, this.q, this.p, this.radius, this.heightScale );
54466             var p2 = getPos( u + 0.01, v, this.q, this.p, this.radius, this.heightScale );
54467             var cx, cy;
54468
54469             tang.sub( p2, p1 );
54470             n.add( p2, p1 );
54471
54472             bitan.cross( tang, n );
54473             n.cross( bitan, tang );
54474             bitan.normalize();
54475             n.normalize();
54476
54477             cx = - this.tube * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
54478             cy = this.tube * Math.sin( v );
54479
54480             p1.x += cx * n.x + cy * bitan.x;
54481             p1.y += cx * n.y + cy * bitan.y;
54482             p1.z += cx * n.z + cy * bitan.z;
54483
54484             this.grid[ i ][ j ] = vert( p1.x, p1.y, p1.z );
54485
54486         }
54487
54488     }
54489
54490     for ( var i = 0; i < this.segmentsR; ++ i ) {
54491
54492         for ( var j = 0; j < this.segmentsT; ++ j ) {
54493
54494             var ip = ( i + 1 ) % this.segmentsR;
54495             var jp = ( j + 1 ) % this.segmentsT;
54496
54497             var a = this.grid[ i ][ j ];
54498             var b = this.grid[ ip ][ j ];
54499             var c = this.grid[ ip ][ jp ];
54500             var d = this.grid[ i ][ jp ];
54501
54502             var uva = new THREE.UV( i / this.segmentsR, j / this.segmentsT );
54503             var uvb = new THREE.UV( ( i + 1 ) / this.segmentsR, j / this.segmentsT );
54504             var uvc = new THREE.UV( ( i + 1 ) / this.segmentsR, ( j + 1 ) / this.segmentsT );
54505             var uvd = new THREE.UV( i / this.segmentsR, ( j + 1 ) / this.segmentsT );
54506
54507             this.faces.push( new THREE.Face4( a, b, c, d ) );
54508             this.faceVertexUvs[ 0 ].push( [ uva,uvb,uvc, uvd ] );
54509
54510         }
54511     }
54512
54513     this.computeCentroids();
54514     this.computeFaceNormals();
54515     this.computeVertexNormals();
54516
54517     function vert( x, y, z ) {
54518
54519         return scope.vertices.push( new THREE.Vector3( x, y, z ) ) - 1;
54520
54521     }
54522
54523     function getPos( u, v, in_q, in_p, radius, heightScale ) {
54524
54525         var cu = Math.cos( u );
54526         var cv = Math.cos( v );
54527         var su = Math.sin( u );
54528         var quOverP = in_q / in_p * u;
54529         var cs = Math.cos( quOverP );
54530
54531         var tx = radius * ( 2 + cs ) * 0.5 * cu;
54532         var ty = radius * ( 2 + cs ) * su * 0.5;
54533         var tz = heightScale * radius * Math.sin( quOverP ) * 0.5;
54534
54535         return new THREE.Vector3( tx, ty, tz );
54536
54537     }
54538
54539 };
54540
54541 THREE.TorusKnotGeometry.prototype = Object.create( THREE.Geometry.prototype );
54542 /**
54543  * @author WestLangley / https://github.com/WestLangley
54544  * @author zz85 / https://github.com/zz85
54545  * @author miningold / https://github.com/miningold
54546  *
54547  * Modified from the TorusKnotGeometry by @oosmoxiecode
54548  *
54549  * Creates a tube which extrudes along a 3d spline
54550  *
54551  * Uses parallel transport frames as described in
54552  * http://www.cs.indiana.edu/pub/techreports/TR425.pdf
54553  */
54554
54555 THREE.TubeGeometry = function( path, segments, radius, segmentsRadius, closed, debug ) {
54556
54557     THREE.Geometry.call( this );
54558
54559     this.path = path;
54560     this.segments = segments || 64;
54561     this.radius = radius || 1;
54562     this.segmentsRadius = segmentsRadius || 8;
54563     this.closed = closed || false;
54564     if ( debug ) this.debug = new THREE.Object3D();
54565
54566     this.grid = [];
54567
54568     var scope = this,
54569
54570         tangent,
54571         normal,
54572         binormal,
54573
54574         numpoints = this.segments + 1,
54575
54576         x, y, z,
54577         tx, ty, tz,
54578         u, v,
54579
54580         cx, cy,
54581         pos, pos2 = new THREE.Vector3(),
54582         i, j,
54583         ip, jp,
54584         a, b, c, d,
54585         uva, uvb, uvc, uvd;
54586
54587     var frames = new THREE.TubeGeometry.FrenetFrames(path, segments, closed),
54588         tangents = frames.tangents,
54589         normals = frames.normals,
54590         binormals = frames.binormals;
54591
54592     // proxy internals
54593     this.tangents = tangents;
54594     this.normals = normals;
54595     this.binormals = binormals;
54596
54597
54598     function vert( x, y, z ) {
54599
54600         return scope.vertices.push( new THREE.Vector3( x, y, z ) ) - 1;
54601
54602     }
54603
54604
54605
54606
54607     // consruct the grid
54608
54609     for ( i = 0; i < numpoints; i++ ) {
54610
54611         this.grid[ i ] = [];
54612
54613         u = i / ( numpoints - 1 );
54614
54615         pos = path.getPointAt( u );
54616
54617         tangent = tangents[ i ];
54618         normal = normals[ i ];
54619         binormal = binormals[ i ];
54620
54621         if ( this.debug ) {
54622
54623             this.debug.add(new THREE.ArrowHelper(tangent, pos, radius, 0x0000ff));
54624             this.debug.add(new THREE.ArrowHelper(normal, pos, radius, 0xff0000));
54625             this.debug.add(new THREE.ArrowHelper(binormal, pos, radius, 0x00ff00));
54626
54627         }
54628
54629         for ( j = 0; j < this.segmentsRadius; j++ ) {
54630
54631             v = j / this.segmentsRadius * 2 * Math.PI;
54632
54633             cx = -this.radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
54634             cy = this.radius * Math.sin( v );
54635
54636             pos2.copy( pos );
54637             pos2.x += cx * normal.x + cy * binormal.x;
54638             pos2.y += cx * normal.y + cy * binormal.y;
54639             pos2.z += cx * normal.z + cy * binormal.z;
54640
54641             this.grid[ i ][ j ] = vert( pos2.x, pos2.y, pos2.z );
54642
54643         }
54644     }
54645
54646
54647     // construct the mesh
54648
54649     for ( i = 0; i < this.segments; i++ ) {
54650
54651         for ( j = 0; j < this.segmentsRadius; j++ ) {
54652
54653             ip = ( closed ) ? (i + 1) % this.segments : i + 1;
54654             jp = (j + 1) % this.segmentsRadius;
54655
54656             a = this.grid[ i ][ j ];        // *** NOT NECESSARILY PLANAR ! ***
54657             b = this.grid[ ip ][ j ];
54658             c = this.grid[ ip ][ jp ];
54659             d = this.grid[ i ][ jp ];
54660
54661             uva = new THREE.UV( i / this.segments, j / this.segmentsRadius );
54662             uvb = new THREE.UV( ( i + 1 ) / this.segments, j / this.segmentsRadius );
54663             uvc = new THREE.UV( ( i + 1 ) / this.segments, ( j + 1 ) / this.segmentsRadius );
54664             uvd = new THREE.UV( i / this.segments, ( j + 1 ) / this.segmentsRadius );
54665
54666             this.faces.push( new THREE.Face4( a, b, c, d ) );
54667             this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvc, uvd ] );
54668
54669         }
54670     }
54671
54672     this.computeCentroids();
54673     this.computeFaceNormals();
54674     this.computeVertexNormals();
54675
54676 };
54677
54678 THREE.TubeGeometry.prototype = Object.create( THREE.Geometry.prototype );
54679
54680
54681 // For computing of Frenet frames, exposing the tangents, normals and binormals the spline
54682 THREE.TubeGeometry.FrenetFrames = function(path, segments, closed) {
54683
54684     var
54685         tangent = new THREE.Vector3(),
54686         normal = new THREE.Vector3(),
54687         binormal = new THREE.Vector3(),
54688
54689         tangents = [],
54690         normals = [],
54691         binormals = [],
54692
54693         vec = new THREE.Vector3(),
54694         mat = new THREE.Matrix4(),
54695
54696         numpoints = segments + 1,
54697         theta,
54698         epsilon = 0.0001,
54699         smallest,
54700
54701         tx, ty, tz,
54702         i, u, v;
54703
54704
54705     // expose internals
54706     this.tangents = tangents;
54707     this.normals = normals;
54708     this.binormals = binormals;
54709
54710     // compute the tangent vectors for each segment on the path
54711
54712     for ( i = 0; i < numpoints; i++ ) {
54713
54714         u = i / ( numpoints - 1 );
54715
54716         tangents[ i ] = path.getTangentAt( u );
54717         tangents[ i ].normalize();
54718
54719     }
54720
54721     initialNormal3();
54722
54723     function initialNormal1(lastBinormal) {
54724         // fixed start binormal. Has dangers of 0 vectors
54725         normals[ 0 ] = new THREE.Vector3();
54726         binormals[ 0 ] = new THREE.Vector3();
54727         if (lastBinormal===undefined) lastBinormal = new THREE.Vector3( 0, 0, 1 );
54728         normals[ 0 ].cross( lastBinormal, tangents[ 0 ] ).normalize();
54729         binormals[ 0 ].cross( tangents[ 0 ], normals[ 0 ] ).normalize();
54730     }
54731
54732     function initialNormal2() {
54733
54734         // This uses the Frenet-Serret formula for deriving binormal
54735         var t2 = path.getTangentAt( epsilon );
54736
54737         normals[ 0 ] = new THREE.Vector3().sub( t2, tangents[ 0 ] ).normalize();
54738         binormals[ 0 ] = new THREE.Vector3().cross( tangents[ 0 ], normals[ 0 ] );
54739
54740         normals[ 0 ].cross( binormals[ 0 ], tangents[ 0 ] ).normalize(); // last binormal x tangent
54741         binormals[ 0 ].cross( tangents[ 0 ], normals[ 0 ] ).normalize();
54742
54743     }
54744
54745     function initialNormal3() {
54746         // select an initial normal vector perpenicular to the first tangent vector,
54747         // and in the direction of the smallest tangent xyz component
54748
54749         normals[ 0 ] = new THREE.Vector3();
54750         binormals[ 0 ] = new THREE.Vector3();
54751         smallest = Number.MAX_VALUE;
54752         tx = Math.abs( tangents[ 0 ].x );
54753         ty = Math.abs( tangents[ 0 ].y );
54754         tz = Math.abs( tangents[ 0 ].z );
54755
54756         if ( tx <= smallest ) {
54757             smallest = tx;
54758             normal.set( 1, 0, 0 );
54759         }
54760
54761         if ( ty <= smallest ) {
54762             smallest = ty;
54763             normal.set( 0, 1, 0 );
54764         }
54765
54766         if ( tz <= smallest ) {
54767             normal.set( 0, 0, 1 );
54768         }
54769
54770         vec.cross( tangents[ 0 ], normal ).normalize();
54771
54772         normals[ 0 ].cross( tangents[ 0 ], vec );
54773         binormals[ 0 ].cross( tangents[ 0 ], normals[ 0 ] );
54774     }
54775
54776
54777     // compute the slowly-varying normal and binormal vectors for each segment on the path
54778
54779     for ( i = 1; i < numpoints; i++ ) {
54780
54781         normals[ i ] = normals[ i-1 ].clone();
54782
54783         binormals[ i ] = binormals[ i-1 ].clone();
54784
54785         vec.cross( tangents[ i-1 ], tangents[ i ] );
54786
54787         if ( vec.length() > epsilon ) {
54788
54789             vec.normalize();
54790
54791             theta = Math.acos( tangents[ i-1 ].dot( tangents[ i ] ) );
54792
54793             mat.makeRotationAxis( vec, theta ).multiplyVector3( normals[ i ] );
54794
54795         }
54796
54797         binormals[ i ].cross( tangents[ i ], normals[ i ] );
54798
54799     }
54800
54801
54802     // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
54803
54804     if ( closed ) {
54805
54806         theta = Math.acos( normals[ 0 ].dot( normals[ numpoints-1 ] ) );
54807         theta /= ( numpoints - 1 );
54808
54809         if ( tangents[ 0 ].dot( vec.cross( normals[ 0 ], normals[ numpoints-1 ] ) ) > 0 ) {
54810
54811             theta = -theta;
54812
54813         }
54814
54815         for ( i = 1; i < numpoints; i++ ) {
54816
54817             // twist a little...
54818             mat.makeRotationAxis( tangents[ i ], theta * i ).multiplyVector3( normals[ i ] );
54819             binormals[ i ].cross( tangents[ i ], normals[ i ] );
54820
54821         }
54822
54823     }
54824 };
54825 /**
54826  * @author clockworkgeek / https://github.com/clockworkgeek
54827  * @author timothypratley / https://github.com/timothypratley
54828  */
54829
54830 THREE.PolyhedronGeometry = function ( vertices, faces, radius, detail ) {
54831
54832     THREE.Geometry.call( this );
54833
54834     radius = radius || 1;
54835     detail = detail || 0;
54836
54837     var that = this;
54838
54839     for ( var i = 0, l = vertices.length; i < l; i ++ ) {
54840
54841         prepare( new THREE.Vector3( vertices[ i ][ 0 ], vertices[ i ][ 1 ], vertices[ i ][ 2 ] ) );
54842
54843     }
54844
54845     var midpoints = [], p = this.vertices;
54846
54847     for ( var i = 0, l = faces.length; i < l; i ++ ) {
54848
54849         make( p[ faces[ i ][ 0 ] ], p[ faces[ i ][ 1 ] ], p[ faces[ i ][ 2 ] ], detail );
54850
54851     }
54852
54853     this.mergeVertices();
54854
54855     // Apply radius
54856
54857     for ( var i = 0, l = this.vertices.length; i < l; i ++ ) {
54858
54859         this.vertices[ i ].multiplyScalar( radius );
54860
54861     }
54862
54863
54864     // Project vector onto sphere's surface
54865
54866     function prepare( vector ) {
54867
54868         var vertex = vector.normalize().clone();
54869         vertex.index = that.vertices.push( vertex ) - 1;
54870
54871         // Texture coords are equivalent to map coords, calculate angle and convert to fraction of a circle.
54872
54873         var u = azimuth( vector ) / 2 / Math.PI + 0.5;
54874         var v = inclination( vector ) / Math.PI + 0.5;
54875         vertex.uv = new THREE.UV( u, 1 - v );
54876
54877         return vertex;
54878
54879     }
54880
54881
54882     // Approximate a curved face with recursively sub-divided triangles.
54883
54884     function make( v1, v2, v3, detail ) {
54885
54886         if ( detail < 1 ) {
54887
54888             var face = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.clone(), v2.clone(), v3.clone() ] );
54889             face.centroid.addSelf( v1 ).addSelf( v2 ).addSelf( v3 ).divideScalar( 3 );
54890             face.normal = face.centroid.clone().normalize();
54891             that.faces.push( face );
54892
54893             var azi = azimuth( face.centroid );
54894             that.faceVertexUvs[ 0 ].push( [
54895                 correctUV( v1.uv, v1, azi ),
54896                 correctUV( v2.uv, v2, azi ),
54897                 correctUV( v3.uv, v3, azi )
54898             ] );
54899
54900         } else {
54901
54902             detail -= 1;
54903
54904             // split triangle into 4 smaller triangles
54905
54906             make( v1, midpoint( v1, v2 ), midpoint( v1, v3 ), detail ); // top quadrant
54907             make( midpoint( v1, v2 ), v2, midpoint( v2, v3 ), detail ); // left quadrant
54908             make( midpoint( v1, v3 ), midpoint( v2, v3 ), v3, detail ); // right quadrant
54909             make( midpoint( v1, v2 ), midpoint( v2, v3 ), midpoint( v1, v3 ), detail ); // center quadrant
54910
54911         }
54912
54913     }
54914
54915     function midpoint( v1, v2 ) {
54916
54917         if ( !midpoints[ v1.index ] ) midpoints[ v1.index ] = [];
54918         if ( !midpoints[ v2.index ] ) midpoints[ v2.index ] = [];
54919
54920         var mid = midpoints[ v1.index ][ v2.index ];
54921
54922         if ( mid === undefined ) {
54923
54924             // generate mean point and project to surface with prepare()
54925
54926             midpoints[ v1.index ][ v2.index ] = midpoints[ v2.index ][ v1.index ] = mid = prepare(
54927                 new THREE.Vector3().add( v1, v2 ).divideScalar( 2 )
54928             );
54929         }
54930
54931         return mid;
54932
54933     }
54934
54935
54936     // Angle around the Y axis, counter-clockwise when looking from above.
54937
54938     function azimuth( vector ) {
54939
54940         return Math.atan2( vector.z, -vector.x );
54941
54942     }
54943
54944
54945     // Angle above the XZ plane.
54946
54947     function inclination( vector ) {
54948
54949         return Math.atan2( -vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
54950
54951     }
54952
54953
54954     // Texture fixing helper. Spheres have some odd behaviours.
54955
54956     function correctUV( uv, vector, azimuth ) {
54957
54958         if ( ( azimuth < 0 ) && ( uv.u === 1 ) ) uv = new THREE.UV( uv.u - 1, uv.v );
54959         if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) uv = new THREE.UV( azimuth / 2 / Math.PI + 0.5, uv.v );
54960         return uv;
54961
54962     }
54963
54964     this.computeCentroids();
54965
54966     this.boundingSphere = { radius: radius };
54967
54968 };
54969
54970 THREE.PolyhedronGeometry.prototype = Object.create( THREE.Geometry.prototype );
54971 /**
54972  * @author timothypratley / https://github.com/timothypratley
54973  */
54974
54975 THREE.IcosahedronGeometry = function ( radius, detail ) {
54976
54977     var t = ( 1 + Math.sqrt( 5 ) ) / 2;
54978
54979     var vertices = [
54980         [ -1,  t,  0 ], [  1, t, 0 ], [ -1, -t,  0 ], [  1, -t,  0 ],
54981         [  0, -1,  t ], [  0, 1, t ], [  0, -1, -t ], [  0,  1, -t ],
54982         [  t,  0, -1 ], [  t, 0, 1 ], [ -t,  0, -1 ], [ -t,  0,  1 ]
54983     ];
54984
54985     var faces = [
54986         [ 0, 11,  5 ], [ 0,  5,  1 ], [  0,  1,  7 ], [  0,  7, 10 ], [  0, 10, 11 ],
54987         [ 1,  5,  9 ], [ 5, 11,  4 ], [ 11, 10,  2 ], [ 10,  7,  6 ], [  7,  1,  8 ],
54988         [ 3,  9,  4 ], [ 3,  4,  2 ], [  3,  2,  6 ], [  3,  6,  8 ], [  3,  8,  9 ],
54989         [ 4,  9,  5 ], [ 2,  4, 11 ], [  6,  2, 10 ], [  8,  6,  7 ], [  9,  8,  1 ]
54990     ];
54991
54992     THREE.PolyhedronGeometry.call( this, vertices, faces, radius, detail );
54993
54994 };
54995
54996 THREE.IcosahedronGeometry.prototype = Object.create( THREE.Geometry.prototype );
54997 /**
54998  * @author timothypratley / https://github.com/timothypratley
54999  */
55000
55001 THREE.OctahedronGeometry = function ( radius, detail ) {
55002
55003     var vertices = [
55004         [ 1, 0, 0 ], [ -1, 0, 0 ], [ 0, 1, 0 ], [ 0, -1, 0 ], [ 0, 0, 1 ], [ 0, 0, -1 ]
55005     ];
55006
55007     var faces = [
55008         [ 0, 2, 4 ], [ 0, 4, 3 ], [ 0, 3, 5 ], [ 0, 5, 2 ], [ 1, 2, 5 ], [ 1, 5, 3 ], [ 1, 3, 4 ], [ 1, 4, 2 ]
55009     ];
55010
55011     THREE.PolyhedronGeometry.call( this, vertices, faces, radius, detail );
55012 };
55013
55014 THREE.OctahedronGeometry.prototype = Object.create( THREE.Geometry.prototype );
55015 /**
55016  * @author timothypratley / https://github.com/timothypratley
55017  */
55018
55019 THREE.TetrahedronGeometry = function ( radius, detail ) {
55020
55021     var vertices = [
55022         [ 1,  1,  1 ], [ -1, -1, 1 ], [ -1, 1, -1 ], [ 1, -1, -1 ]
55023     ];
55024
55025     var faces = [
55026         [ 2, 1, 0 ], [ 0, 3, 2 ], [ 1, 3, 0 ], [ 2, 3, 1 ]
55027     ];
55028
55029     THREE.PolyhedronGeometry.call( this, vertices, faces, radius, detail );
55030
55031 };
55032
55033 THREE.TetrahedronGeometry.prototype = Object.create( THREE.Geometry.prototype );
55034 /**
55035  * @author zz85 / https://github.com/zz85
55036  * Parametric Surfaces Geometry
55037  * based on the brilliant article by @prideout http://prideout.net/blog/?p=44
55038  *
55039  * new THREE.ParametricGeometry( parametricFunction, uSegments, ySegements, useTris );
55040  *
55041  */
55042
55043 THREE.ParametricGeometry = function ( func, slices, stacks, useTris ) {
55044
55045     THREE.Geometry.call( this );
55046
55047     var verts = this.vertices;
55048     var faces = this.faces;
55049     var uvs = this.faceVertexUvs[ 0 ];
55050
55051     useTris = (useTris === undefined) ? false : useTris;
55052
55053     var i, il, j, p;
55054     var u, v;
55055
55056     var stackCount = stacks + 1;
55057     var sliceCount = slices + 1;
55058
55059     for ( i = 0; i <= stacks; i ++ ) {
55060
55061         v = i / stacks;
55062
55063         for ( j = 0; j <= slices; j ++ ) {
55064
55065             u = j / slices;
55066
55067             p = func( u, v );
55068             verts.push( p );
55069
55070         }
55071     }
55072
55073     var a, b, c, d;
55074     var uva, uvb, uvc, uvd;
55075
55076     for ( i = 0; i < stacks; i ++ ) {
55077
55078         for ( j = 0; j < slices; j ++ ) {
55079
55080             a = i * sliceCount + j;
55081             b = i * sliceCount + j + 1;
55082             c = (i + 1) * sliceCount + j;
55083             d = (i + 1) * sliceCount + j + 1;
55084
55085             uva = new THREE.UV( j / slices, i / stacks );
55086             uvb = new THREE.UV( ( j + 1 ) / slices, i / stacks );
55087             uvc = new THREE.UV( j / slices, ( i + 1 ) / stacks );
55088             uvd = new THREE.UV( ( j + 1 ) / slices, ( i + 1 ) / stacks );
55089
55090             if ( useTris ) {
55091
55092                 faces.push( new THREE.Face3( a, b, c ) );
55093                 faces.push( new THREE.Face3( b, d, c ) );
55094
55095                 uvs.push( [ uva, uvb, uvc ] );
55096                 uvs.push( [ uvb, uvd, uvc ] );
55097
55098             } else {
55099
55100                 faces.push( new THREE.Face4( a, b, d, c ) );
55101                 uvs.push( [ uva, uvb, uvd, uvc ] );
55102
55103             }
55104
55105         }
55106
55107     }
55108
55109     // console.log(this);
55110
55111     // magic bullet
55112     // var diff = this.mergeVertices();
55113     // console.log('removed ', diff, ' vertices by merging');
55114
55115     this.computeCentroids();
55116     this.computeFaceNormals();
55117     this.computeVertexNormals();
55118
55119 };
55120
55121 THREE.ParametricGeometry.prototype = Object.create( THREE.Geometry.prototype );
55122 /**
55123  * @author qiao / https://github.com/qiao
55124  * @fileoverview This is a convex hull generator using the incremental method.
55125  * The complexity is O(n^2) where n is the number of vertices.
55126  * O(nlogn) algorithms do exist, but they are much more complicated.
55127  *
55128  * Benchmark:
55129  *
55130  *  Platform: CPU: P7350 @2.00GHz Engine: V8
55131  *
55132  *  Num Vertices    Time(ms)
55133  *
55134  *     10           1
55135  *     20           3
55136  *     30           19
55137  *     40           48
55138  *     50           107
55139  */
55140
55141 THREE.ConvexGeometry = function( vertices ) {
55142
55143     THREE.Geometry.call( this );
55144
55145     var faces = [ [ 0, 1, 2 ], [ 0, 2, 1 ] ];
55146
55147     for ( var i = 3; i < vertices.length; i++ ) {
55148
55149         addPoint( i );
55150
55151     }
55152
55153
55154     function addPoint( vertexId ) {
55155
55156         var vertex = vertices[ vertexId ].clone();
55157
55158         var mag = vertex.length();
55159         vertex.x += mag * randomOffset();
55160         vertex.y += mag * randomOffset();
55161         vertex.z += mag * randomOffset();
55162
55163         var hole = [];
55164
55165         for ( var f = 0; f < faces.length; ) {
55166
55167             var face = faces[ f ];
55168
55169             // for each face, if the vertex can see it,
55170             // then we try to add the face's edges into the hole.
55171             if ( visible( face, vertex ) ) {
55172
55173                 for ( var e = 0; e < 3; e++ ) {
55174
55175                     var edge = [ face[ e ], face[ ( e + 1 ) % 3 ] ];
55176                     var boundary = true;
55177
55178                     // remove duplicated edges.
55179                     for ( var h = 0; h < hole.length; h++ ) {
55180
55181                         if ( equalEdge( hole[ h ], edge ) ) {
55182
55183                             hole[ h ] = hole[ hole.length - 1 ];
55184                             hole.pop();
55185                             boundary = false;
55186                             break;
55187
55188                         }
55189
55190                     }
55191
55192                     if ( boundary ) {
55193
55194                         hole.push( edge );
55195
55196                     }
55197
55198                 }
55199
55200                 // remove faces[ f ]
55201                 faces[ f ] = faces[ faces.length - 1 ];
55202                 faces.pop();
55203
55204             } else { // not visible
55205
55206                 f++;
55207
55208             }
55209         }
55210
55211         // construct the new faces formed by the edges of the hole and the vertex
55212         for ( var h = 0; h < hole.length; h++ ) {
55213
55214             faces.push( [
55215                 hole[ h ][ 0 ],
55216                 hole[ h ][ 1 ],
55217                 vertexId
55218             ] );
55219
55220         }
55221     }
55222
55223     /**
55224      * Whether the face is visible from the vertex
55225      */
55226     function visible( face, vertex ) {
55227
55228         var va = vertices[ face[ 0 ] ];
55229         var vb = vertices[ face[ 1 ] ];
55230         var vc = vertices[ face[ 2 ] ];
55231
55232         var n = normal( va, vb, vc );
55233
55234         // distance from face to origin
55235         var dist = n.dot( va );
55236
55237         return n.dot( vertex ) >= dist;
55238
55239     }
55240
55241     /**
55242      * Face normal
55243      */
55244     function normal( va, vb, vc ) {
55245
55246         var cb = new THREE.Vector3();
55247         var ab = new THREE.Vector3();
55248
55249         cb.sub( vc, vb );
55250         ab.sub( va, vb );
55251         cb.crossSelf( ab );
55252
55253         if ( !cb.isZero() ) {
55254
55255             cb.normalize();
55256
55257         }
55258
55259         return cb;
55260
55261     }
55262
55263     /**
55264      * Detect whether two edges are equal.
55265      * Note that when constructing the convex hull, two same edges can only
55266      * be of the negative direction.
55267      */
55268     function equalEdge( ea, eb ) {
55269
55270         return ea[ 0 ] === eb[ 1 ] && ea[ 1 ] === eb[ 0 ];
55271
55272     }
55273
55274     /**
55275      * Create a random offset between -1e-6 and 1e-6.
55276      */
55277     function randomOffset() {
55278
55279         return ( Math.random() - 0.5 ) * 2 * 1e-6;
55280
55281     }
55282
55283
55284     /**
55285      * XXX: Not sure if this is the correct approach. Need someone to review.
55286      */
55287     function vertexUv( vertex ) {
55288
55289         var mag = vertex.length();
55290         return new THREE.UV( vertex.x / mag, vertex.y / mag );
55291
55292     }
55293
55294     // Push vertices into `this.vertices`, skipping those inside the hull
55295     var id = 0;
55296     var newId = new Array( vertices.length ); // map from old vertex id to new id
55297
55298     for ( var i = 0; i < faces.length; i++ ) {
55299
55300          var face = faces[ i ];
55301
55302          for ( var j = 0; j < 3; j++ ) {
55303
55304                 if ( newId[ face[ j ] ] === undefined ) {
55305
55306                         newId[ face[ j ] ] = id++;
55307                         this.vertices.push( vertices[ face[ j ] ] );
55308
55309                 }
55310
55311                 face[ j ] = newId[ face[ j ] ];
55312
55313          }
55314
55315     }
55316
55317     // Convert faces into instances of THREE.Face3
55318     for ( var i = 0; i < faces.length; i++ ) {
55319
55320         this.faces.push( new THREE.Face3(
55321                 faces[ i ][ 0 ],
55322                 faces[ i ][ 1 ],
55323                 faces[ i ][ 2 ]
55324         ) );
55325
55326     }
55327
55328     // Compute UVs
55329     for ( var i = 0; i < this.faces.length; i++ ) {
55330
55331         var face = this.faces[ i ];
55332
55333         this.faceVertexUvs[ 0 ].push( [
55334             vertexUv( this.vertices[ face.a ] ),
55335             vertexUv( this.vertices[ face.b ] ),
55336             vertexUv( this.vertices[ face.c ])
55337         ] );
55338
55339     }
55340
55341
55342     this.computeCentroids();
55343     this.computeFaceNormals();
55344     this.computeVertexNormals();
55345
55346 };
55347
55348 THREE.ConvexGeometry.prototype = Object.create( THREE.Geometry.prototype );
55349 /**
55350  * @author sroucheray / http://sroucheray.org/
55351  * @author mrdoob / http://mrdoob.com/
55352  */
55353
55354 THREE.AxisHelper = function () {
55355
55356     THREE.Object3D.call( this );
55357
55358     var lineGeometry = new THREE.Geometry();
55359     lineGeometry.vertices.push( new THREE.Vector3() );
55360     lineGeometry.vertices.push( new THREE.Vector3( 0, 100, 0 ) );
55361
55362     var coneGeometry = new THREE.CylinderGeometry( 0, 5, 25, 5, 1 );
55363
55364     var line, cone;
55365
55366     // x
55367
55368     line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color : 0xff0000 } ) );
55369     line.rotation.z = - Math.PI / 2;
55370     this.add( line );
55371
55372     cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color : 0xff0000 } ) );
55373     cone.position.x = 100;
55374     cone.rotation.z = - Math.PI / 2;
55375     this.add( cone );
55376
55377     // y
55378
55379     line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color : 0x00ff00 } ) );
55380     this.add( line );
55381
55382     cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color : 0x00ff00 } ) );
55383     cone.position.y = 100;
55384     this.add( cone );
55385
55386     // z
55387
55388     line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color : 0x0000ff } ) );
55389     line.rotation.x = Math.PI / 2;
55390     this.add( line );
55391
55392     cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color : 0x0000ff } ) );
55393     cone.position.z = 100;
55394     cone.rotation.x = Math.PI / 2;
55395     this.add( cone );
55396
55397 };
55398
55399 THREE.AxisHelper.prototype = Object.create( THREE.Object3D.prototype );
55400 /**
55401  * @author WestLangley / http://github.com/WestLangley
55402  * @author zz85 / https://github.com/zz85
55403  *
55404  * Creates an arrow for visualizing directions
55405  *
55406  * Parameters:
55407  *  dir - Vector3
55408  *  origin - Vector3
55409  *  length - Number
55410  *  hex - color in hex value
55411  */
55412
55413 THREE.ArrowHelper = function ( dir, origin, length, hex ) {
55414
55415     THREE.Object3D.call( this );
55416
55417     if ( hex === undefined ) hex = 0xffff00;
55418     if ( length === undefined ) length = 20;
55419
55420     var lineGeometry = new THREE.Geometry();
55421     lineGeometry.vertices.push( new THREE.Vector3( 0, 0, 0 ) );
55422     lineGeometry.vertices.push( new THREE.Vector3( 0, 1, 0 ) );
55423
55424     this.line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color: hex } ) );
55425     this.add( this.line );
55426
55427     var coneGeometry = new THREE.CylinderGeometry( 0, 0.05, 0.25, 5, 1 );
55428
55429     this.cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color: hex } ) );
55430     this.cone.position.set( 0, 1, 0 );
55431     this.add( this.cone );
55432
55433     if ( origin instanceof THREE.Vector3 ) this.position = origin;
55434
55435     this.setDirection( dir );
55436     this.setLength( length );
55437
55438 };
55439
55440 THREE.ArrowHelper.prototype = Object.create( THREE.Object3D.prototype );
55441
55442 THREE.ArrowHelper.prototype.setDirection = function ( dir ) {
55443
55444     var axis = new THREE.Vector3( 0, 1, 0 ).crossSelf( dir );
55445
55446     var radians = Math.acos( new THREE.Vector3( 0, 1, 0 ).dot( dir.clone().normalize() ) );
55447
55448     this.matrix = new THREE.Matrix4().makeRotationAxis( axis.normalize(), radians );
55449
55450     this.rotation.setEulerFromRotationMatrix( this.matrix, this.eulerOrder );
55451
55452 };
55453
55454 THREE.ArrowHelper.prototype.setLength = function ( length ) {
55455
55456     this.scale.set( length, length, length );
55457
55458 };
55459
55460 THREE.ArrowHelper.prototype.setColor = function ( hex ) {
55461
55462     this.line.material.color.setHex( hex );
55463     this.cone.material.color.setHex( hex );
55464
55465 };
55466 /**
55467  * @author alteredq / http://alteredqualia.com/
55468  *
55469  *    - shows frustum, line of sight and up of the camera
55470  *    - suitable for fast updates
55471  *     - based on frustum visualization in lightgl.js shadowmap example
55472  *        http://evanw.github.com/lightgl.js/tests/shadowmap.html
55473  */
55474
55475 THREE.CameraHelper = function ( camera ) {
55476
55477     THREE.Line.call( this );
55478
55479     var scope = this;
55480
55481     this.geometry = new THREE.Geometry();
55482     this.material = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors } );
55483     this.type = THREE.LinePieces;
55484
55485     this.matrixWorld = camera.matrixWorld;
55486     this.matrixAutoUpdate = false;
55487
55488     this.pointMap = {};
55489
55490     // colors
55491
55492     var hexFrustum = 0xffaa00;
55493     var hexCone = 0xff0000;
55494     var hexUp = 0x00aaff;
55495     var hexTarget = 0xffffff;
55496     var hexCross = 0x333333;
55497
55498     // near
55499
55500     addLine( "n1", "n2", hexFrustum );
55501     addLine( "n2", "n4", hexFrustum );
55502     addLine( "n4", "n3", hexFrustum );
55503     addLine( "n3", "n1", hexFrustum );
55504
55505     // far
55506
55507     addLine( "f1", "f2", hexFrustum );
55508     addLine( "f2", "f4", hexFrustum );
55509     addLine( "f4", "f3", hexFrustum );
55510     addLine( "f3", "f1", hexFrustum );
55511
55512     // sides
55513
55514     addLine( "n1", "f1", hexFrustum );
55515     addLine( "n2", "f2", hexFrustum );
55516     addLine( "n3", "f3", hexFrustum );
55517     addLine( "n4", "f4", hexFrustum );
55518
55519     // cone
55520
55521     addLine( "p", "n1", hexCone );
55522     addLine( "p", "n2", hexCone );
55523     addLine( "p", "n3", hexCone );
55524     addLine( "p", "n4", hexCone );
55525
55526     // up
55527
55528     addLine( "u1", "u2", hexUp );
55529     addLine( "u2", "u3", hexUp );
55530     addLine( "u3", "u1", hexUp );
55531
55532     // target
55533
55534     addLine( "c", "t", hexTarget );
55535     addLine( "p", "c", hexCross );
55536
55537     // cross
55538
55539     addLine( "cn1", "cn2", hexCross );
55540     addLine( "cn3", "cn4", hexCross );
55541
55542     addLine( "cf1", "cf2", hexCross );
55543     addLine( "cf3", "cf4", hexCross );
55544
55545     this.camera = camera;
55546
55547     function addLine( a, b, hex ) {
55548
55549         addPoint( a, hex );
55550         addPoint( b, hex );
55551
55552     }
55553
55554     function addPoint( id, hex ) {
55555
55556         scope.geometry.vertices.push( new THREE.Vector3() );
55557         scope.geometry.colors.push( new THREE.Color( hex ) );
55558
55559         if ( scope.pointMap[ id ] === undefined ) scope.pointMap[ id ] = [];
55560
55561         scope.pointMap[ id ].push( scope.geometry.vertices.length - 1 );
55562
55563     }
55564
55565     this.update( camera );
55566
55567 };
55568
55569 THREE.CameraHelper.prototype = Object.create( THREE.Line.prototype );
55570
55571 THREE.CameraHelper.prototype.update = function () {
55572
55573     var scope = this;
55574
55575     var w = 1, h = 1;
55576
55577     // we need just camera projection matrix
55578     // world matrix must be identity
55579
55580     THREE.CameraHelper.__c.projectionMatrix.copy( this.camera.projectionMatrix );
55581
55582     // center / target
55583
55584     setPoint( "c", 0, 0, -1 );
55585     setPoint( "t", 0, 0,  1 );
55586
55587     // near
55588
55589     setPoint( "n1", -w, -h, -1 );
55590     setPoint( "n2",  w, -h, -1 );
55591     setPoint( "n3", -w,  h, -1 );
55592     setPoint( "n4",  w,  h, -1 );
55593
55594     // far
55595
55596     setPoint( "f1", -w, -h, 1 );
55597     setPoint( "f2",  w, -h, 1 );
55598     setPoint( "f3", -w,  h, 1 );
55599     setPoint( "f4",  w,  h, 1 );
55600
55601     // up
55602
55603     setPoint( "u1",  w * 0.7, h * 1.1, -1 );
55604     setPoint( "u2", -w * 0.7, h * 1.1, -1 );
55605     setPoint( "u3",        0, h * 2,   -1 );
55606
55607     // cross
55608
55609     setPoint( "cf1", -w,  0, 1 );
55610     setPoint( "cf2",  w,  0, 1 );
55611     setPoint( "cf3",  0, -h, 1 );
55612     setPoint( "cf4",  0,  h, 1 );
55613
55614     setPoint( "cn1", -w,  0, -1 );
55615     setPoint( "cn2",  w,  0, -1 );
55616     setPoint( "cn3",  0, -h, -1 );
55617     setPoint( "cn4",  0,  h, -1 );
55618
55619     function setPoint( point, x, y, z ) {
55620
55621         THREE.CameraHelper.__v.set( x, y, z );
55622         THREE.CameraHelper.__projector.unprojectVector( THREE.CameraHelper.__v, THREE.CameraHelper.__c );
55623
55624         var points = scope.pointMap[ point ];
55625
55626         if ( points !== undefined ) {
55627
55628             for ( var i = 0, il = points.length; i < il; i ++ ) {
55629
55630                 scope.geometry.vertices[ points[ i ] ].copy( THREE.CameraHelper.__v );
55631
55632             }
55633
55634         }
55635
55636     }
55637
55638     this.geometry.verticesNeedUpdate = true;
55639
55640 };
55641
55642 THREE.CameraHelper.__projector = new THREE.Projector();
55643 THREE.CameraHelper.__v = new THREE.Vector3();
55644 THREE.CameraHelper.__c = new THREE.Camera();
55645
55646 /*
55647  *    @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
55648  *
55649  *    Subdivision Geometry Modifier
55650  *        using Catmull-Clark Subdivision Surfaces
55651  *        for creating smooth geometry meshes
55652  *
55653  *    Note: a modifier modifies vertices and faces of geometry,
55654  *        so use THREE.GeometryUtils.clone() if orignal geoemtry needs to be retained
55655  *
55656  *    Readings:
55657  *        http://en.wikipedia.org/wiki/Catmull%E2%80%93Clark_subdivision_surface
55658  *        http://www.rorydriscoll.com/2008/08/01/catmull-clark-subdivision-the-basics/
55659  *        http://xrt.wikidot.com/blog:31
55660  *        "Subdivision Surfaces in Character Animation"
55661  *
55662  *    Supports:
55663  *        Closed and Open geometries.
55664  *
55665  *    TODO:
55666  *        crease vertex and "semi-sharp" features
55667  *        selective subdivision
55668  */
55669
55670 THREE.SubdivisionModifier = function( subdivisions ) {
55671
55672     this.subdivisions = (subdivisions === undefined ) ? 1 : subdivisions;
55673
55674     // Settings
55675     this.useOldVertexColors = false;
55676     this.supportUVs = true;
55677     this.debug = false;
55678
55679 };
55680
55681 // Applies the "modify" pattern
55682 THREE.SubdivisionModifier.prototype.modify = function ( geometry ) {
55683
55684     var repeats = this.subdivisions;
55685
55686     while ( repeats-- > 0 ) {
55687         this.smooth( geometry );
55688     }
55689
55690 };
55691
55692 // Performs an iteration of Catmull-Clark Subdivision
55693 THREE.SubdivisionModifier.prototype.smooth = function ( oldGeometry ) {
55694
55695     //debug( 'running smooth' );
55696
55697     // New set of vertices, faces and uvs
55698     var newVertices = [], newFaces = [], newUVs = [];
55699
55700     function v( x, y, z ) {
55701         newVertices.push( new THREE.Vector3( x, y, z ) );
55702     }
55703
55704     var scope = this;
55705
55706     function debug() {
55707         if (scope.debug) console.log.apply(console, arguments);
55708     }
55709
55710     function warn() {
55711         if (console)
55712         console.log.apply(console, arguments);
55713     }
55714
55715     function f4( a, b, c, d, oldFace, orders, facei ) {
55716
55717         // TODO move vertex selection over here!
55718
55719         var newFace = new THREE.Face4( a, b, c, d, null, oldFace.color, oldFace.materialIndex );
55720
55721         if (scope.useOldVertexColors) {
55722
55723             newFace.vertexColors = [];
55724
55725             var color, tmpColor, order;
55726             for (var i=0;i<4;i++) {
55727                 order = orders[i];
55728
55729                 color = new THREE.Color(),
55730                 color.setRGB(0,0,0);
55731
55732                 for (var j=0, jl=0; j<order.length;j++) {
55733                     tmpColor = oldFace.vertexColors[order[j]-1];
55734                     color.r += tmpColor.r;
55735                     color.g += tmpColor.g;
55736                     color.b += tmpColor.b;
55737                 }
55738
55739                 color.r /= order.length;
55740                 color.g /= order.length;
55741                 color.b /= order.length;
55742
55743                 newFace.vertexColors[i] = color;
55744
55745             }
55746
55747         }
55748
55749         newFaces.push( newFace );
55750
55751         if (scope.supportUVs) {
55752
55753             var aUv = [
55754                 getUV(a, ''),
55755                 getUV(b, facei),
55756                 getUV(c, facei),
55757                 getUV(d, facei)
55758             ];
55759
55760             if (!aUv[0]) debug('a :( ', a+':'+facei);
55761             else if (!aUv[1]) debug('b :( ', b+':'+facei);
55762             else if (!aUv[2]) debug('c :( ', c+':'+facei);
55763             else if (!aUv[3]) debug('d :( ', d+':'+facei);
55764             else
55765                 newUVs.push( aUv );
55766
55767         }
55768     }
55769
55770     function edge_hash( a, b ) {
55771
55772         return Math.min( a, b ) + "_" + Math.max( a, b );
55773
55774     }
55775
55776     function computeEdgeFaces( geometry ) {
55777
55778         var i, il, v1, v2, j, k,
55779             face, faceIndices, faceIndex,
55780             edge,
55781             hash,
55782             edgeFaceMap = {};
55783
55784         function mapEdgeHash( hash, i ) {
55785
55786             if ( edgeFaceMap[ hash ] === undefined ) {
55787
55788                 edgeFaceMap[ hash ] = [];
55789
55790             }
55791
55792             edgeFaceMap[ hash ].push( i );
55793         }
55794
55795
55796         // construct vertex -> face map
55797
55798         for( i = 0, il = geometry.faces.length; i < il; i ++ ) {
55799
55800             face = geometry.faces[ i ];
55801
55802             if ( face instanceof THREE.Face3 ) {
55803
55804                 hash = edge_hash( face.a, face.b );
55805                 mapEdgeHash( hash, i );
55806
55807                 hash = edge_hash( face.b, face.c );
55808                 mapEdgeHash( hash, i );
55809
55810                 hash = edge_hash( face.c, face.a );
55811                 mapEdgeHash( hash, i );
55812
55813             } else if ( face instanceof THREE.Face4 ) {
55814
55815                 hash = edge_hash( face.a, face.b );
55816                 mapEdgeHash( hash, i );
55817
55818                 hash = edge_hash( face.b, face.c );
55819                 mapEdgeHash( hash, i );
55820
55821                 hash = edge_hash( face.c, face.d );
55822                 mapEdgeHash( hash, i );
55823
55824                 hash = edge_hash( face.d, face.a );
55825                 mapEdgeHash( hash, i );
55826
55827             }
55828
55829         }
55830
55831         // extract faces
55832
55833         // var edges = [];
55834         //
55835         // var numOfEdges = 0;
55836         // for (i in edgeFaceMap) {
55837         //     numOfEdges++;
55838         //
55839         //     edge = edgeFaceMap[i];
55840         //     edges.push(edge);
55841         //
55842         // }
55843
55844         //debug('edgeFaceMap', edgeFaceMap, 'geometry.edges',geometry.edges, 'numOfEdges', numOfEdges);
55845
55846         return edgeFaceMap;
55847
55848     }
55849
55850     var originalPoints = oldGeometry.vertices;
55851     var originalFaces = oldGeometry.faces;
55852
55853     var newPoints = originalPoints.concat(); // Vertices
55854
55855     var facePoints = [], edgePoints = {};
55856
55857     var sharpEdges = {}, sharpVertices = [], sharpFaces = [];
55858
55859     var uvForVertices = {}; // Stored in {vertex}:{old face} format
55860
55861     var originalVerticesLength = originalPoints.length;
55862
55863     function getUV(vertexNo, oldFaceNo) {
55864         var j,jl;
55865
55866         var key = vertexNo+':'+oldFaceNo;
55867         var theUV = uvForVertices[key];
55868
55869         if (!theUV) {
55870             if (vertexNo>=originalVerticesLength && vertexNo < (originalVerticesLength + originalFaces.length)) {
55871                 debug('face pt');
55872             } else {
55873                 debug('edge pt');
55874             }
55875
55876             warn('warning, UV not found for', key);
55877
55878             return null;
55879         }
55880
55881         return theUV;
55882
55883         // Original faces -> Vertex Nos.
55884         // new Facepoint -> Vertex Nos.
55885         // edge Points
55886
55887     }
55888
55889     function addUV(vertexNo, oldFaceNo, value) {
55890
55891         var key = vertexNo+':'+oldFaceNo;
55892         if (!(key in uvForVertices)) {
55893             uvForVertices[key] = value;
55894         } else {
55895             warn('dup vertexNo', vertexNo, 'oldFaceNo', oldFaceNo, 'value', value, 'key', key, uvForVertices[key]);
55896         }
55897     }
55898
55899     // Step 1
55900     //    For each face, add a face point
55901     //    Set each face point to be the centroid of all original points for the respective face.
55902     // debug(oldGeometry);
55903     var i, il, j, jl, face;
55904
55905     // For Uvs
55906     var uvs = oldGeometry.faceVertexUvs[0];
55907     var abcd = 'abcd', vertice;
55908
55909     debug('originalFaces, uvs, originalVerticesLength', originalFaces.length, uvs.length, originalVerticesLength);
55910     if (scope.supportUVs)
55911     for (i=0, il = uvs.length; i<il; i++ ) {
55912         for (j=0,jl=uvs[i].length;j<jl;j++) {
55913             vertice = originalFaces[i][abcd.charAt(j)];
55914
55915             addUV(vertice, i, uvs[i][j]);
55916
55917         }
55918     }
55919
55920     if (uvs.length == 0) scope.supportUVs = false;
55921
55922     // Additional UVs check, if we index original
55923     var uvCount = 0;
55924     for (var u in uvForVertices) {
55925         uvCount++;
55926     }
55927     if (!uvCount) {
55928         scope.supportUVs = false;
55929         debug('no uvs');
55930     }
55931
55932     debug('-- Original Faces + Vertices UVs completed', uvForVertices, 'vs', uvs.length);
55933
55934     var avgUv ;
55935     for (i=0, il = originalFaces.length; i<il ;i++) {
55936         face = originalFaces[ i ];
55937         facePoints.push( face.centroid );
55938         newPoints.push( face.centroid );
55939
55940
55941         if (!scope.supportUVs) continue;
55942
55943         // Prepare subdivided uv
55944
55945         avgUv = new THREE.UV();
55946
55947         if ( face instanceof THREE.Face3 ) {
55948             avgUv.u = getUV( face.a, i ).u + getUV( face.b, i ).u + getUV( face.c, i ).u;
55949             avgUv.v = getUV( face.a, i ).v + getUV( face.b, i ).v + getUV( face.c, i ).v;
55950             avgUv.u /= 3;
55951             avgUv.v /= 3;
55952
55953         } else if ( face instanceof THREE.Face4 ) {
55954             avgUv.u = getUV( face.a, i ).u + getUV( face.b, i ).u + getUV( face.c, i ).u + getUV( face.d, i ).u;
55955             avgUv.v = getUV( face.a, i ).v + getUV( face.b, i ).v + getUV( face.c, i ).v + getUV( face.d, i ).v;
55956             avgUv.u /= 4;
55957             avgUv.v /= 4;
55958         }
55959
55960         addUV(originalVerticesLength + i, '', avgUv);
55961
55962     }
55963
55964     debug('-- added UVs for new Faces', uvForVertices);
55965
55966     // Step 2
55967     //    For each edge, add an edge point.
55968     //    Set each edge point to be the average of the two neighbouring face points and its two original endpoints.
55969
55970     var edgeFaceMap = computeEdgeFaces ( oldGeometry ); // Edge Hash -> Faces Index
55971     var edge, faceIndexA, faceIndexB, avg;
55972
55973     // debug('edgeFaceMap', edgeFaceMap);
55974
55975     var edgeCount = 0;
55976
55977     var edgeVertex, edgeVertexA, edgeVertexB;
55978
55979     ////
55980
55981     var vertexEdgeMap = {}; // Gives edges connecting from each vertex
55982     var vertexFaceMap = {}; // Gives faces connecting from each vertex
55983
55984     function addVertexEdgeMap(vertex, edge) {
55985         if (vertexEdgeMap[vertex]===undefined) {
55986             vertexEdgeMap[vertex] = [];
55987         }
55988
55989         vertexEdgeMap[vertex].push(edge);
55990     }
55991
55992     function addVertexFaceMap(vertex, face, edge) {
55993         if (vertexFaceMap[vertex]===undefined) {
55994             vertexFaceMap[vertex] = {};
55995         }
55996
55997         vertexFaceMap[vertex][face] = edge;
55998         // vertexFaceMap[vertex][face] = null;
55999     }
56000
56001     // Prepares vertexEdgeMap and vertexFaceMap
56002     for (i in edgeFaceMap) { // This is for every edge
56003         edge = edgeFaceMap[i];
56004
56005         edgeVertex = i.split('_');
56006         edgeVertexA = edgeVertex[0];
56007         edgeVertexB = edgeVertex[1];
56008
56009         // Maps an edgeVertex to connecting edges
56010         addVertexEdgeMap(edgeVertexA, [edgeVertexA, edgeVertexB] );
56011         addVertexEdgeMap(edgeVertexB, [edgeVertexA, edgeVertexB] );
56012
56013
56014         for (j=0,jl=edge.length;j<jl;j++) {
56015             face = edge[j];
56016
56017             addVertexFaceMap(edgeVertexA, face, i);
56018             addVertexFaceMap(edgeVertexB, face, i);
56019         }
56020
56021         if (edge.length < 2) {
56022             // edge is "sharp";
56023             sharpEdges[i] = true;
56024             sharpVertices[edgeVertexA] = true;
56025             sharpVertices[edgeVertexB] = true;
56026
56027         }
56028
56029     }
56030
56031     debug('vertexEdgeMap',vertexEdgeMap, 'vertexFaceMap', vertexFaceMap);
56032
56033
56034     for (i in edgeFaceMap) {
56035         edge = edgeFaceMap[i];
56036
56037         faceIndexA = edge[0]; // face index a
56038         faceIndexB = edge[1]; // face index b
56039
56040         edgeVertex = i.split('_');
56041         edgeVertexA = edgeVertex[0];
56042         edgeVertexB = edgeVertex[1];
56043
56044
56045         avg = new THREE.Vector3();
56046
56047         //debug(i, faceIndexB,facePoints[faceIndexB]);
56048
56049         if (sharpEdges[i]) {
56050             //debug('warning, ', i, 'edge has only 1 connecting face', edge);
56051
56052             // For a sharp edge, average the edge end points.
56053             avg.addSelf(originalPoints[edgeVertexA]);
56054             avg.addSelf(originalPoints[edgeVertexB]);
56055
56056             avg.multiplyScalar(0.5);
56057
56058             sharpVertices[newPoints.length] = true;
56059
56060         } else {
56061
56062             avg.addSelf(facePoints[faceIndexA]);
56063             avg.addSelf(facePoints[faceIndexB]);
56064
56065             avg.addSelf(originalPoints[edgeVertexA]);
56066             avg.addSelf(originalPoints[edgeVertexB]);
56067
56068             avg.multiplyScalar(0.25);
56069
56070         }
56071
56072         edgePoints[i] = originalVerticesLength + originalFaces.length + edgeCount;
56073
56074         newPoints.push( avg );
56075
56076         edgeCount ++;
56077
56078         if (!scope.supportUVs) {
56079             continue;
56080         }
56081
56082         // debug('faceIndexAB', faceIndexA, faceIndexB, sharpEdges[i]);
56083
56084         // Prepare subdivided uv
56085
56086         avgUv = new THREE.UV();
56087
56088         avgUv.u = getUV(edgeVertexA, faceIndexA).u + getUV(edgeVertexB, faceIndexA).u;
56089         avgUv.v = getUV(edgeVertexA, faceIndexA).v + getUV(edgeVertexB, faceIndexA).v;
56090         avgUv.u /= 2;
56091         avgUv.v /= 2;
56092
56093         addUV(edgePoints[i], faceIndexA, avgUv);
56094
56095         if (!sharpEdges[i]) {
56096         avgUv = new THREE.UV();
56097
56098         avgUv.u = getUV(edgeVertexA, faceIndexB).u + getUV(edgeVertexB, faceIndexB).u;
56099         avgUv.v = getUV(edgeVertexA, faceIndexB).v + getUV(edgeVertexB, faceIndexB).v;
56100         avgUv.u /= 2;
56101         avgUv.v /= 2;
56102
56103         addUV(edgePoints[i], faceIndexB, avgUv);
56104         }
56105
56106     }
56107
56108     debug('-- Step 2 done');
56109
56110     // Step 3
56111     //    For each face point, add an edge for every edge of the face,
56112     //    connecting the face point to each edge point for the face.
56113
56114
56115     var facePt, currentVerticeIndex;
56116
56117     var hashAB, hashBC, hashCD, hashDA, hashCA;
56118
56119     var abc123 = ['123', '12', '2', '23'];
56120     var bca123 = ['123', '23', '3', '31'];
56121     var cab123 = ['123', '31', '1', '12'];
56122     var abc1234 = ['1234', '12', '2', '23'];
56123     var bcd1234 = ['1234', '23', '3', '34'];
56124     var cda1234 = ['1234', '34', '4', '41'];
56125     var dab1234 = ['1234', '41', '1', '12'];
56126
56127
56128     for (i=0, il = facePoints.length; i<il ;i++) { // for every face
56129         facePt = facePoints[i];
56130         face = originalFaces[i];
56131         currentVerticeIndex = originalVerticesLength+ i;
56132
56133         if ( face instanceof THREE.Face3 ) {
56134
56135             // create 3 face4s
56136
56137             hashAB = edge_hash( face.a, face.b );
56138             hashBC = edge_hash( face.b, face.c );
56139             hashCA = edge_hash( face.c, face.a );
56140
56141             f4( currentVerticeIndex, edgePoints[hashAB], face.b, edgePoints[hashBC], face, abc123, i );
56142             f4( currentVerticeIndex, edgePoints[hashBC], face.c, edgePoints[hashCA], face, bca123, i );
56143             f4( currentVerticeIndex, edgePoints[hashCA], face.a, edgePoints[hashAB], face, cab123, i );
56144
56145         } else if ( face instanceof THREE.Face4 ) {
56146             // create 4 face4s
56147
56148             hashAB = edge_hash( face.a, face.b );
56149             hashBC = edge_hash( face.b, face.c );
56150             hashCD = edge_hash( face.c, face.d );
56151             hashDA = edge_hash( face.d, face.a );
56152
56153             f4( currentVerticeIndex, edgePoints[hashAB], face.b, edgePoints[hashBC], face, abc1234, i );
56154             f4( currentVerticeIndex, edgePoints[hashBC], face.c, edgePoints[hashCD], face, bcd1234, i );
56155             f4( currentVerticeIndex, edgePoints[hashCD], face.d, edgePoints[hashDA], face, cda1234, i );
56156             f4( currentVerticeIndex, edgePoints[hashDA], face.a, edgePoints[hashAB], face, dab1234, i );
56157
56158
56159         } else {
56160             debug('face should be a face!', face);
56161         }
56162     }
56163
56164     newVertices = newPoints;
56165
56166     // debug('original ', oldGeometry.vertices.length, oldGeometry.faces.length );
56167     // debug('new points', newPoints.length, 'faces', newFaces.length );
56168
56169     // Step 4
56170
56171     //    For each original point P,
56172     //        take the average F of all n face points for faces touching P,
56173     //        and take the average R of all n edge midpoints for edges touching P,
56174     //        where each edge midpoint is the average of its two endpoint vertices.
56175     //    Move each original point to the point
56176
56177
56178     var F = new THREE.Vector3();
56179     var R = new THREE.Vector3();
56180
56181     var n;
56182     for (i=0, il = originalPoints.length; i<il; i++) {
56183         // (F + 2R + (n-3)P) / n
56184
56185         if (vertexEdgeMap[i]===undefined) continue;
56186
56187         F.set(0,0,0);
56188         R.set(0,0,0);
56189         var newPos =  new THREE.Vector3(0,0,0);
56190
56191         var f =0;
56192         for (j in vertexFaceMap[i]) {
56193             F.addSelf(facePoints[j]);
56194             f++;
56195         }
56196
56197         var sharpEdgeCount = 0;
56198
56199         n = vertexEdgeMap[i].length;
56200
56201         for (j=0;j<n;j++) {
56202             if (
56203                 sharpEdges[
56204                     edge_hash(vertexEdgeMap[i][j][0],vertexEdgeMap[i][j][1])
56205                 ]) {
56206                     sharpEdgeCount++;
56207                 }
56208         }
56209
56210         if ( sharpEdgeCount==2 ) {
56211             continue;
56212             // Do not move vertex if there's 2 connecting sharp edges.
56213         }
56214
56215         /*
56216         if (sharpEdgeCount>2) {
56217             // TODO
56218         }
56219         */
56220
56221         F.divideScalar(f);
56222
56223
56224
56225         for (j=0; j<n;j++) {
56226             edge = vertexEdgeMap[i][j];
56227             var midPt = originalPoints[edge[0]].clone().addSelf(originalPoints[edge[1]]).divideScalar(2);
56228             R.addSelf(midPt);
56229             // R.addSelf(originalPoints[edge[0]]);
56230             // R.addSelf(originalPoints[edge[1]]);
56231         }
56232
56233         R.divideScalar(n);
56234
56235         newPos.addSelf(originalPoints[i]);
56236         newPos.multiplyScalar(n - 3);
56237
56238         newPos.addSelf(F);
56239         newPos.addSelf(R.multiplyScalar(2));
56240         newPos.divideScalar(n);
56241
56242         newVertices[i] = newPos;
56243
56244
56245     }
56246
56247     var newGeometry = oldGeometry; // Let's pretend the old geometry is now new :P
56248
56249     newGeometry.vertices = newVertices;
56250     newGeometry.faces = newFaces;
56251     newGeometry.faceVertexUvs[ 0 ] = newUVs;
56252
56253     delete newGeometry.__tmpVertices; // makes __tmpVertices undefined :P
56254
56255     newGeometry.computeCentroids();
56256     newGeometry.computeFaceNormals();
56257     newGeometry.computeVertexNormals();
56258
56259 };
56260 /**
56261  * @author alteredq / http://alteredqualia.com/
56262  */
56263
56264 THREE.ImmediateRenderObject = function ( ) {
56265
56266     THREE.Object3D.call( this );
56267
56268     this.render = function ( renderCallback ) { };
56269
56270 };
56271
56272 THREE.ImmediateRenderObject.prototype = Object.create( THREE.Object3D.prototype );
56273 /**
56274  * @author mikael emtinger / http://gomo.se/
56275  * @author alteredq / http://alteredqualia.com/
56276  */
56277
56278 THREE.LensFlare = function ( texture, size, distance, blending, color ) {
56279
56280     THREE.Object3D.call( this );
56281
56282     this.lensFlares = [];
56283
56284     this.positionScreen = new THREE.Vector3();
56285     this.customUpdateCallback = undefined;
56286
56287     if( texture !== undefined ) {
56288
56289         this.add( texture, size, distance, blending, color );
56290
56291     }
56292
56293 };
56294
56295 THREE.LensFlare.prototype = Object.create( THREE.Object3D.prototype );
56296
56297
56298 /*
56299  * Add: adds another flare
56300  */
56301
56302 THREE.LensFlare.prototype.add = function ( texture, size, distance, blending, color, opacity ) {
56303
56304     if( size === undefined ) size = -1;
56305     if( distance === undefined ) distance = 0;
56306     if( opacity === undefined ) opacity = 1;
56307     if( color === undefined ) color = new THREE.Color( 0xffffff );
56308     if( blending === undefined ) blending = THREE.NormalBlending;
56309
56310     distance = Math.min( distance, Math.max( 0, distance ) );
56311
56312     this.lensFlares.push( { texture: texture,             // THREE.Texture
56313                             size: size,                 // size in pixels (-1 = use texture.width)
56314                             distance: distance,         // distance (0-1) from light source (0=at light source)
56315                             x: 0, y: 0, z: 0,            // screen position (-1 => 1) z = 0 is ontop z = 1 is back
56316                             scale: 1,                     // scale
56317                             rotation: 1,                 // rotation
56318                             opacity: opacity,            // opacity
56319                             color: color,                // color
56320                             blending: blending } );        // blending
56321
56322 };
56323
56324
56325 /*
56326  * Update lens flares update positions on all flares based on the screen position
56327  * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.
56328  */
56329
56330 THREE.LensFlare.prototype.updateLensFlares = function () {
56331
56332     var f, fl = this.lensFlares.length;
56333     var flare;
56334     var vecX = -this.positionScreen.x * 2;
56335     var vecY = -this.positionScreen.y * 2;
56336
56337     for( f = 0; f < fl; f ++ ) {
56338
56339         flare = this.lensFlares[ f ];
56340
56341         flare.x = this.positionScreen.x + vecX * flare.distance;
56342         flare.y = this.positionScreen.y + vecY * flare.distance;
56343
56344         flare.wantedRotation = flare.x * Math.PI * 0.25;
56345         flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;
56346
56347     }
56348
56349 };
56350
56351
56352
56353
56354
56355
56356
56357
56358
56359
56360
56361
56362 /**
56363  * @author alteredq / http://alteredqualia.com/
56364  */
56365
56366 THREE.MorphBlendMesh = function( geometry, material ) {
56367
56368     THREE.Mesh.call( this, geometry, material );
56369
56370     this.animationsMap = {};
56371     this.animationsList = [];
56372
56373     // prepare default animation
56374     // (all frames played together in 1 second)
56375
56376     var numFrames = this.geometry.morphTargets.length;
56377
56378     var name = "__default";
56379
56380     var startFrame = 0;
56381     var endFrame = numFrames - 1;
56382
56383     var fps = numFrames / 1;
56384
56385     this.createAnimation( name, startFrame, endFrame, fps );
56386     this.setAnimationWeight( name, 1 );
56387
56388 };
56389
56390 THREE.MorphBlendMesh.prototype = Object.create( THREE.Mesh.prototype );
56391
56392 THREE.MorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {
56393
56394     var animation = {
56395
56396         startFrame: start,
56397         endFrame: end,
56398
56399         length: end - start + 1,
56400
56401         fps: fps,
56402         duration: ( end - start ) / fps,
56403
56404         lastFrame: 0,
56405         currentFrame: 0,
56406
56407         active: false,
56408
56409         time: 0,
56410         direction: 1,
56411         weight: 1,
56412
56413         directionBackwards: false,
56414         mirroredLoop: false
56415
56416     };
56417
56418     this.animationsMap[ name ] = animation;
56419     this.animationsList.push( animation );
56420
56421 };
56422
56423 THREE.MorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {
56424
56425     var pattern = /([a-z]+)(\d+)/;
56426
56427     var firstAnimation, frameRanges = {};
56428
56429     var geometry = this.geometry;
56430
56431     for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
56432
56433         var morph = geometry.morphTargets[ i ];
56434         var chunks = morph.name.match( pattern );
56435
56436         if ( chunks && chunks.length > 1 ) {
56437
56438             var name = chunks[ 1 ];
56439             var num = chunks[ 2 ];
56440
56441             if ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: -Infinity };
56442
56443             var range = frameRanges[ name ];
56444
56445             if ( i < range.start ) range.start = i;
56446             if ( i > range.end ) range.end = i;
56447
56448             if ( ! firstAnimation ) firstAnimation = name;
56449
56450         }
56451
56452     }
56453
56454     for ( var name in frameRanges ) {
56455
56456         var range = frameRanges[ name ];
56457         this.createAnimation( name, range.start, range.end, fps );
56458
56459     }
56460
56461     this.firstAnimation = firstAnimation;
56462
56463 };
56464
56465 THREE.MorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {
56466
56467     var animation = this.animationsMap[ name ];
56468
56469     if ( animation ) {
56470
56471         animation.direction = 1;
56472         animation.directionBackwards = false;
56473
56474     }
56475
56476 };
56477
56478 THREE.MorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {
56479
56480     var animation = this.animationsMap[ name ];
56481
56482     if ( animation ) {
56483
56484         animation.direction = -1;
56485         animation.directionBackwards = true;
56486
56487     }
56488
56489 };
56490
56491 THREE.MorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {
56492
56493     var animation = this.animationsMap[ name ];
56494
56495     if ( animation ) {
56496
56497         animation.fps = fps;
56498         animation.duration = ( animation.end - animation.start ) / animation.fps;
56499
56500     }
56501
56502 };
56503
56504 THREE.MorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {
56505
56506     var animation = this.animationsMap[ name ];
56507
56508     if ( animation ) {
56509
56510         animation.duration = duration;
56511         animation.fps = ( animation.end - animation.start ) / animation.duration;
56512
56513     }
56514
56515 };
56516
56517 THREE.MorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {
56518
56519     var animation = this.animationsMap[ name ];
56520
56521     if ( animation ) {
56522
56523         animation.weight = weight;
56524
56525     }
56526
56527 };
56528
56529 THREE.MorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {
56530
56531     var animation = this.animationsMap[ name ];
56532
56533     if ( animation ) {
56534
56535         animation.time = time;
56536
56537     }
56538
56539 };
56540
56541 THREE.MorphBlendMesh.prototype.getAnimationTime = function ( name ) {
56542
56543     var time = 0;
56544
56545     var animation = this.animationsMap[ name ];
56546
56547     if ( animation ) {
56548
56549         time = animation.time;
56550
56551     }
56552
56553     return time;
56554
56555 };
56556
56557 THREE.MorphBlendMesh.prototype.getAnimationDuration = function ( name ) {
56558
56559     var duration = -1;
56560
56561     var animation = this.animationsMap[ name ];
56562
56563     if ( animation ) {
56564
56565         duration = animation.duration;
56566
56567     }
56568
56569     return duration;
56570
56571 };
56572
56573 THREE.MorphBlendMesh.prototype.playAnimation = function ( name ) {
56574
56575     var animation = this.animationsMap[ name ];
56576
56577     if ( animation ) {
56578
56579         animation.time = 0;
56580         animation.active = true;
56581
56582     } else {
56583
56584         console.warn( "animation[" + name + "] undefined" );
56585
56586     }
56587
56588 };
56589
56590 THREE.MorphBlendMesh.prototype.stopAnimation = function ( name ) {
56591
56592     var animation = this.animationsMap[ name ];
56593
56594     if ( animation ) {
56595
56596         animation.active = false;
56597
56598     }
56599
56600 };
56601
56602 THREE.MorphBlendMesh.prototype.update = function ( delta ) {
56603
56604     for ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {
56605
56606         var animation = this.animationsList[ i ];
56607
56608         if ( ! animation.active ) continue;
56609
56610         var frameTime = animation.duration / animation.length;
56611
56612         animation.time += animation.direction * delta;
56613
56614         if ( animation.mirroredLoop ) {
56615
56616             if ( animation.time > animation.duration || animation.time < 0 ) {
56617
56618                 animation.direction *= -1;
56619
56620                 if ( animation.time > animation.duration ) {
56621
56622                     animation.time = animation.duration;
56623                     animation.directionBackwards = true;
56624
56625                 }
56626
56627                 if ( animation.time < 0 ) {
56628
56629                     animation.time = 0;
56630                     animation.directionBackwards = false;
56631
56632                 }
56633
56634             }
56635
56636         } else {
56637
56638             animation.time = animation.time % animation.duration;
56639
56640             if ( animation.time < 0 ) animation.time += animation.duration;
56641
56642         }
56643
56644         var keyframe = animation.startFrame + THREE.Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );
56645         var weight = animation.weight;
56646
56647         if ( keyframe !== animation.currentFrame ) {
56648
56649             this.morphTargetInfluences[ animation.lastFrame ] = 0;
56650             this.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;
56651
56652             this.morphTargetInfluences[ keyframe ] = 0;
56653
56654             animation.lastFrame = animation.currentFrame;
56655             animation.currentFrame = keyframe;
56656
56657         }
56658
56659         var mix = ( animation.time % frameTime ) / frameTime;
56660
56661         if ( animation.directionBackwards ) mix = 1 - mix;
56662
56663         this.morphTargetInfluences[ animation.currentFrame ] = mix * weight;
56664         this.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;
56665
56666     }
56667
56668 };
56669 /**
56670  * @author mikael emtinger / http://gomo.se/
56671  * @author alteredq / http://alteredqualia.com/
56672  */
56673
56674 THREE.LensFlarePlugin = function ( ) {
56675
56676     var _gl, _renderer, _lensFlare = {};
56677
56678     this.init = function ( renderer ) {
56679
56680         _gl = renderer.context;
56681         _renderer = renderer;
56682
56683         _lensFlare.vertices = new Float32Array( 8 + 8 );
56684         _lensFlare.faces = new Uint16Array( 6 );
56685
56686         var i = 0;
56687         _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = -1;    // vertex
56688         _lensFlare.vertices[ i++ ] = 0;  _lensFlare.vertices[ i++ ] = 0;    // uv... etc.
56689
56690         _lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = -1;
56691         _lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 0;
56692
56693         _lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 1;
56694         _lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 1;
56695
56696         _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = 1;
56697         _lensFlare.vertices[ i++ ] = 0;  _lensFlare.vertices[ i++ ] = 1;
56698
56699         i = 0;
56700         _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 1; _lensFlare.faces[ i++ ] = 2;
56701         _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 2; _lensFlare.faces[ i++ ] = 3;
56702
56703         // buffers
56704
56705         _lensFlare.vertexBuffer     = _gl.createBuffer();
56706         _lensFlare.elementBuffer    = _gl.createBuffer();
56707
56708         _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
56709         _gl.bufferData( _gl.ARRAY_BUFFER, _lensFlare.vertices, _gl.STATIC_DRAW );
56710
56711         _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
56712         _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.faces, _gl.STATIC_DRAW );
56713
56714         // textures
56715
56716         _lensFlare.tempTexture      = _gl.createTexture();
56717         _lensFlare.occlusionTexture = _gl.createTexture();
56718
56719         _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
56720         _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, 16, 16, 0, _gl.RGB, _gl.UNSIGNED_BYTE, null );
56721         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
56722         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
56723         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
56724         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
56725
56726         _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
56727         _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, 16, 16, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, null );
56728         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
56729         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
56730         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
56731         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
56732
56733         if ( _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) <= 0 ) {
56734
56735             _lensFlare.hasVertexTexture = false;
56736             _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlare" ] );
56737
56738         } else {
56739
56740             _lensFlare.hasVertexTexture = true;
56741             _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlareVertexTexture" ] );
56742
56743         }
56744
56745         _lensFlare.attributes = {};
56746         _lensFlare.uniforms = {};
56747
56748         _lensFlare.attributes.vertex       = _gl.getAttribLocation ( _lensFlare.program, "position" );
56749         _lensFlare.attributes.uv           = _gl.getAttribLocation ( _lensFlare.program, "uv" );
56750
56751         _lensFlare.uniforms.renderType     = _gl.getUniformLocation( _lensFlare.program, "renderType" );
56752         _lensFlare.uniforms.map            = _gl.getUniformLocation( _lensFlare.program, "map" );
56753         _lensFlare.uniforms.occlusionMap   = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
56754         _lensFlare.uniforms.opacity        = _gl.getUniformLocation( _lensFlare.program, "opacity" );
56755         _lensFlare.uniforms.color          = _gl.getUniformLocation( _lensFlare.program, "color" );
56756         _lensFlare.uniforms.scale          = _gl.getUniformLocation( _lensFlare.program, "scale" );
56757         _lensFlare.uniforms.rotation       = _gl.getUniformLocation( _lensFlare.program, "rotation" );
56758         _lensFlare.uniforms.screenPosition = _gl.getUniformLocation( _lensFlare.program, "screenPosition" );
56759
56760         _lensFlare.attributesEnabled = false;
56761
56762     };
56763
56764
56765     /*
56766      * Render lens flares
56767      * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,
56768      *         reads these back and calculates occlusion.
56769      *         Then _lensFlare.update_lensFlares() is called to re-position and
56770      *         update transparency of flares. Then they are rendered.
56771      *
56772      */
56773
56774     this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
56775
56776         var flares = scene.__webglFlares,
56777             nFlares = flares.length;
56778
56779         if ( ! nFlares ) return;
56780
56781         var tempPosition = new THREE.Vector3();
56782
56783         var invAspect = viewportHeight / viewportWidth,
56784             halfViewportWidth = viewportWidth * 0.5,
56785             halfViewportHeight = viewportHeight * 0.5;
56786
56787         var size = 16 / viewportHeight,
56788             scale = new THREE.Vector2( size * invAspect, size );
56789
56790         var screenPosition = new THREE.Vector3( 1, 1, 0 ),
56791             screenPositionPixels = new THREE.Vector2( 1, 1 );
56792
56793         var uniforms = _lensFlare.uniforms,
56794             attributes = _lensFlare.attributes;
56795
56796         // set _lensFlare program and reset blending
56797
56798         _gl.useProgram( _lensFlare.program );
56799
56800         if ( ! _lensFlare.attributesEnabled ) {
56801
56802             _gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
56803             _gl.enableVertexAttribArray( _lensFlare.attributes.uv );
56804
56805             _lensFlare.attributesEnabled = true;
56806
56807         }
56808
56809         // loop through all lens flares to update their occlusion and positions
56810         // setup gl and common used attribs/unforms
56811
56812         _gl.uniform1i( uniforms.occlusionMap, 0 );
56813         _gl.uniform1i( uniforms.map, 1 );
56814
56815         _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
56816         _gl.vertexAttribPointer( attributes.vertex, 2, _gl.FLOAT, false, 2 * 8, 0 );
56817         _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
56818
56819         _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
56820
56821         _gl.disable( _gl.CULL_FACE );
56822         _gl.depthMask( false );
56823
56824         var i, j, jl, flare, sprite;
56825
56826         for ( i = 0; i < nFlares; i ++ ) {
56827
56828             size = 16 / viewportHeight;
56829             scale.set( size * invAspect, size );
56830
56831             // calc object screen position
56832
56833             flare = flares[ i ];
56834
56835             tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] );
56836
56837             camera.matrixWorldInverse.multiplyVector3( tempPosition );
56838             camera.projectionMatrix.multiplyVector3( tempPosition );
56839
56840             // setup arrays for gl programs
56841
56842             screenPosition.copy( tempPosition )
56843
56844             screenPositionPixels.x = screenPosition.x * halfViewportWidth + halfViewportWidth;
56845             screenPositionPixels.y = screenPosition.y * halfViewportHeight + halfViewportHeight;
56846
56847             // screen cull
56848
56849             if ( _lensFlare.hasVertexTexture || (
56850                 screenPositionPixels.x > 0 &&
56851                 screenPositionPixels.x < viewportWidth &&
56852                 screenPositionPixels.y > 0 &&
56853                 screenPositionPixels.y < viewportHeight ) ) {
56854
56855                 // save current RGB to temp texture
56856
56857                 _gl.activeTexture( _gl.TEXTURE1 );
56858                 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
56859                 _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
56860
56861
56862                 // render pink quad
56863
56864                 _gl.uniform1i( uniforms.renderType, 0 );
56865                 _gl.uniform2f( uniforms.scale, scale.x, scale.y );
56866                 _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
56867
56868                 _gl.disable( _gl.BLEND );
56869                 _gl.enable( _gl.DEPTH_TEST );
56870
56871                 _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
56872
56873
56874                 // copy result to occlusionMap
56875
56876                 _gl.activeTexture( _gl.TEXTURE0 );
56877                 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
56878                 _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
56879
56880
56881                 // restore graphics
56882
56883                 _gl.uniform1i( uniforms.renderType, 1 );
56884                 _gl.disable( _gl.DEPTH_TEST );
56885
56886                 _gl.activeTexture( _gl.TEXTURE1 );
56887                 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
56888                 _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
56889
56890
56891                 // update object positions
56892
56893                 flare.positionScreen.copy( screenPosition )
56894
56895                 if ( flare.customUpdateCallback ) {
56896
56897                     flare.customUpdateCallback( flare );
56898
56899                 } else {
56900
56901                     flare.updateLensFlares();
56902
56903                 }
56904
56905                 // render flares
56906
56907                 _gl.uniform1i( uniforms.renderType, 2 );
56908                 _gl.enable( _gl.BLEND );
56909
56910                 for ( j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {
56911
56912                     sprite = flare.lensFlares[ j ];
56913
56914                     if ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {
56915
56916                         screenPosition.x = sprite.x;
56917                         screenPosition.y = sprite.y;
56918                         screenPosition.z = sprite.z;
56919
56920                         size = sprite.size * sprite.scale / viewportHeight;
56921
56922                         scale.x = size * invAspect;
56923                         scale.y = size;
56924
56925                         _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
56926                         _gl.uniform2f( uniforms.scale, scale.x, scale.y );
56927                         _gl.uniform1f( uniforms.rotation, sprite.rotation );
56928
56929                         _gl.uniform1f( uniforms.opacity, sprite.opacity );
56930                         _gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
56931
56932                         _renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
56933                         _renderer.setTexture( sprite.texture, 1 );
56934
56935                         _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
56936
56937                     }
56938
56939                 }
56940
56941             }
56942
56943         }
56944
56945         // restore gl
56946
56947         _gl.enable( _gl.CULL_FACE );
56948         _gl.enable( _gl.DEPTH_TEST );
56949         _gl.depthMask( true );
56950
56951     };
56952
56953     function createProgram ( shader ) {
56954
56955         var program = _gl.createProgram();
56956
56957         var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
56958         var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
56959
56960         _gl.shaderSource( fragmentShader, shader.fragmentShader );
56961         _gl.shaderSource( vertexShader, shader.vertexShader );
56962
56963         _gl.compileShader( fragmentShader );
56964         _gl.compileShader( vertexShader );
56965
56966         _gl.attachShader( program, fragmentShader );
56967         _gl.attachShader( program, vertexShader );
56968
56969         _gl.linkProgram( program );
56970
56971         return program;
56972
56973     };
56974
56975 };/**
56976  * @author alteredq / http://alteredqualia.com/
56977  */
56978
56979 THREE.ShadowMapPlugin = function ( ) {
56980
56981     var _gl,
56982     _renderer,
56983     _depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,
56984
56985     _frustum = new THREE.Frustum(),
56986     _projScreenMatrix = new THREE.Matrix4(),
56987
56988     _min = new THREE.Vector3(),
56989     _max = new THREE.Vector3();
56990
56991     this.init = function ( renderer ) {
56992
56993         _gl = renderer.context;
56994         _renderer = renderer;
56995
56996         var depthShader = THREE.ShaderLib[ "depthRGBA" ];
56997         var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
56998
56999         _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
57000         _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
57001         _depthMaterialSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, skinning: true } );
57002         _depthMaterialMorphSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true, skinning: true } );
57003
57004         _depthMaterial._shadowPass = true;
57005         _depthMaterialMorph._shadowPass = true;
57006         _depthMaterialSkin._shadowPass = true;
57007         _depthMaterialMorphSkin._shadowPass = true;
57008
57009     };
57010
57011     this.render = function ( scene, camera ) {
57012
57013         if ( ! ( _renderer.shadowMapEnabled && _renderer.shadowMapAutoUpdate ) ) return;
57014
57015         this.update( scene, camera );
57016
57017     };
57018
57019     this.update = function ( scene, camera ) {
57020
57021         var i, il, j, jl, n,
57022
57023         shadowMap, shadowMatrix, shadowCamera,
57024         program, buffer, material,
57025         webglObject, object, light,
57026         renderList,
57027
57028         lights = [],
57029         k = 0,
57030
57031         fog = null;
57032
57033         // set GL state for depth map
57034
57035         _gl.clearColor( 1, 1, 1, 1 );
57036         _gl.disable( _gl.BLEND );
57037
57038         _gl.enable( _gl.CULL_FACE );
57039         _gl.frontFace( _gl.CCW );
57040
57041         if ( _renderer.shadowMapCullFrontFaces ) {
57042
57043             _gl.cullFace( _gl.FRONT );
57044
57045         } else {
57046
57047             _gl.cullFace( _gl.BACK );
57048
57049         }
57050
57051         _renderer.setDepthTest( true );
57052
57053         // preprocess lights
57054         //     - skip lights that are not casting shadows
57055         //    - create virtual lights for cascaded shadow maps
57056
57057         for ( i = 0, il = scene.__lights.length; i < il; i ++ ) {
57058
57059             light = scene.__lights[ i ];
57060
57061             if ( ! light.castShadow ) continue;
57062
57063             if ( ( light instanceof THREE.DirectionalLight ) && light.shadowCascade ) {
57064
57065                 for ( n = 0; n < light.shadowCascadeCount; n ++ ) {
57066
57067                     var virtualLight;
57068
57069                     if ( ! light.shadowCascadeArray[ n ] ) {
57070
57071                         virtualLight = createVirtualLight( light, n );
57072                         virtualLight.originalCamera = camera;
57073
57074                         var gyro = new THREE.Gyroscope();
57075                         gyro.position = light.shadowCascadeOffset;
57076
57077                         gyro.add( virtualLight );
57078                         gyro.add( virtualLight.target );
57079
57080                         camera.add( gyro );
57081
57082                         light.shadowCascadeArray[ n ] = virtualLight;
57083
57084                         console.log( "Created virtualLight", virtualLight );
57085
57086                     } else {
57087
57088                         virtualLight = light.shadowCascadeArray[ n ];
57089
57090                     }
57091
57092                     updateVirtualLight( light, n );
57093
57094                     lights[ k ] = virtualLight;
57095                     k ++;
57096
57097                 }
57098
57099             } else {
57100
57101                 lights[ k ] = light;
57102                 k ++;
57103
57104             }
57105
57106         }
57107
57108         // render depth map
57109
57110         for ( i = 0, il = lights.length; i < il; i ++ ) {
57111
57112             light = lights[ i ];
57113
57114             if ( ! light.shadowMap ) {
57115
57116                 var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
57117
57118                 light.shadowMap = new THREE.WebGLRenderTarget( light.shadowMapWidth, light.shadowMapHeight, pars );
57119                 light.shadowMapSize = new THREE.Vector2( light.shadowMapWidth, light.shadowMapHeight );
57120
57121                 light.shadowMatrix = new THREE.Matrix4();
57122
57123             }
57124
57125             if ( ! light.shadowCamera ) {
57126
57127                 if ( light instanceof THREE.SpotLight ) {
57128
57129                     light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, light.shadowMapWidth / light.shadowMapHeight, light.shadowCameraNear, light.shadowCameraFar );
57130
57131                 } else if ( light instanceof THREE.DirectionalLight ) {
57132
57133                     light.shadowCamera = new THREE.OrthographicCamera( light.shadowCameraLeft, light.shadowCameraRight, light.shadowCameraTop, light.shadowCameraBottom, light.shadowCameraNear, light.shadowCameraFar );
57134
57135                 } else {
57136
57137                     console.error( "Unsupported light type for shadow" );
57138                     continue;
57139
57140                 }
57141
57142                 scene.add( light.shadowCamera );
57143
57144                 if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
57145
57146             }
57147
57148             if ( light.shadowCameraVisible && ! light.cameraHelper ) {
57149
57150                 light.cameraHelper = new THREE.CameraHelper( light.shadowCamera );
57151                 light.shadowCamera.add( light.cameraHelper );
57152
57153             }
57154
57155             if ( light.isVirtual && virtualLight.originalCamera == camera ) {
57156
57157                 updateShadowCamera( camera, light );
57158
57159             }
57160
57161             shadowMap = light.shadowMap;
57162             shadowMatrix = light.shadowMatrix;
57163             shadowCamera = light.shadowCamera;
57164
57165             shadowCamera.position.copy( light.matrixWorld.getPosition() );
57166             shadowCamera.lookAt( light.target.matrixWorld.getPosition() );
57167             shadowCamera.updateMatrixWorld();
57168
57169             shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
57170
57171             if ( light.cameraHelper ) light.cameraHelper.visible = light.shadowCameraVisible;
57172             if ( light.shadowCameraVisible ) light.cameraHelper.update();
57173
57174             // compute shadow matrix
57175
57176             shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
57177                               0.0, 0.5, 0.0, 0.5,
57178                               0.0, 0.0, 0.5, 0.5,
57179                               0.0, 0.0, 0.0, 1.0 );
57180
57181             shadowMatrix.multiplySelf( shadowCamera.projectionMatrix );
57182             shadowMatrix.multiplySelf( shadowCamera.matrixWorldInverse );
57183
57184             // update camera matrices and frustum
57185
57186             if ( ! shadowCamera._viewMatrixArray ) shadowCamera._viewMatrixArray = new Float32Array( 16 );
57187             if ( ! shadowCamera._projectionMatrixArray ) shadowCamera._projectionMatrixArray = new Float32Array( 16 );
57188
57189             shadowCamera.matrixWorldInverse.flattenToArray( shadowCamera._viewMatrixArray );
57190             shadowCamera.projectionMatrix.flattenToArray( shadowCamera._projectionMatrixArray );
57191
57192             _projScreenMatrix.multiply( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
57193             _frustum.setFromMatrix( _projScreenMatrix );
57194
57195             // render shadow map
57196
57197             _renderer.setRenderTarget( shadowMap );
57198             _renderer.clear();
57199
57200             // set object matrices & frustum culling
57201
57202             renderList = scene.__webglObjects;
57203
57204             for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57205
57206                 webglObject = renderList[ j ];
57207                 object = webglObject.object;
57208
57209                 webglObject.render = false;
57210
57211                 if ( object.visible && object.castShadow ) {
57212
57213                     if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
57214
57215                         object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld );
57216
57217                         webglObject.render = true;
57218
57219                     }
57220
57221                 }
57222
57223             }
57224
57225             // render regular objects
57226
57227             for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57228
57229                 webglObject = renderList[ j ];
57230
57231                 if ( webglObject.render ) {
57232
57233                     object = webglObject.object;
57234                     buffer = webglObject.buffer;
57235
57236                     // culling is overriden globally for all objects
57237                     // while rendering depth map
57238
57239                     if ( object.customDepthMaterial ) {
57240
57241                         material = object.customDepthMaterial;
57242
57243                     } else if ( object instanceof THREE.SkinnedMesh ) {
57244
57245                         material = object.geometry.morphTargets.length ? _depthMaterialMorphSkin : _depthMaterialSkin;
57246
57247                     } else if ( object.geometry.morphTargets.length ) {
57248
57249                         material = _depthMaterialMorph;
57250
57251                     } else {
57252
57253                         material = _depthMaterial;
57254
57255                     }
57256
57257                     if ( buffer instanceof THREE.BufferGeometry ) {
57258
57259                         _renderer.renderBufferDirect( shadowCamera, scene.__lights, fog, material, buffer, object );
57260
57261                     } else {
57262
57263                         _renderer.renderBuffer( shadowCamera, scene.__lights, fog, material, buffer, object );
57264
57265                     }
57266
57267                 }
57268
57269             }
57270
57271             // set matrices and render immediate objects
57272
57273             renderList = scene.__webglObjectsImmediate;
57274
57275             for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57276
57277                 webglObject = renderList[ j ];
57278                 object = webglObject.object;
57279
57280                 if ( object.visible && object.castShadow ) {
57281
57282                     object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld );
57283
57284                     _renderer.renderImmediateObject( shadowCamera, scene.__lights, fog, _depthMaterial, object );
57285
57286                 }
57287
57288             }
57289
57290         }
57291
57292         // restore GL state
57293
57294         var clearColor = _renderer.getClearColor(),
57295         clearAlpha = _renderer.getClearAlpha();
57296
57297         _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
57298         _gl.enable( _gl.BLEND );
57299
57300         if ( _renderer.shadowMapCullFrontFaces ) {
57301
57302             _gl.cullFace( _gl.BACK );
57303
57304         }
57305
57306     };
57307
57308     function createVirtualLight( light, cascade ) {
57309
57310         var virtualLight = new THREE.DirectionalLight();
57311
57312         virtualLight.isVirtual = true;
57313
57314         virtualLight.onlyShadow = true;
57315         virtualLight.castShadow = true;
57316
57317         virtualLight.shadowCameraNear = light.shadowCameraNear;
57318         virtualLight.shadowCameraFar = light.shadowCameraFar;
57319
57320         virtualLight.shadowCameraLeft = light.shadowCameraLeft;
57321         virtualLight.shadowCameraRight = light.shadowCameraRight;
57322         virtualLight.shadowCameraBottom = light.shadowCameraBottom;
57323         virtualLight.shadowCameraTop = light.shadowCameraTop;
57324
57325         virtualLight.shadowCameraVisible = light.shadowCameraVisible;
57326
57327         virtualLight.shadowDarkness = light.shadowDarkness;
57328
57329         virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
57330         virtualLight.shadowMapWidth = light.shadowCascadeWidth[ cascade ];
57331         virtualLight.shadowMapHeight = light.shadowCascadeHeight[ cascade ];
57332
57333         virtualLight.pointsWorld = [];
57334         virtualLight.pointsFrustum = [];
57335
57336         var pointsWorld = virtualLight.pointsWorld,
57337             pointsFrustum = virtualLight.pointsFrustum;
57338
57339         for ( var i = 0; i < 8; i ++ ) {
57340
57341             pointsWorld[ i ] = new THREE.Vector3();
57342             pointsFrustum[ i ] = new THREE.Vector3();
57343
57344         }
57345
57346         var nearZ = light.shadowCascadeNearZ[ cascade ];
57347         var farZ = light.shadowCascadeFarZ[ cascade ];
57348
57349         pointsFrustum[ 0 ].set( -1, -1, nearZ );
57350         pointsFrustum[ 1 ].set(  1, -1, nearZ );
57351         pointsFrustum[ 2 ].set( -1,  1, nearZ );
57352         pointsFrustum[ 3 ].set(  1,  1, nearZ );
57353
57354         pointsFrustum[ 4 ].set( -1, -1, farZ );
57355         pointsFrustum[ 5 ].set(  1, -1, farZ );
57356         pointsFrustum[ 6 ].set( -1,  1, farZ );
57357         pointsFrustum[ 7 ].set(  1,  1, farZ );
57358
57359         return virtualLight;
57360
57361     }
57362
57363     // Synchronize virtual light with the original light
57364
57365     function updateVirtualLight( light, cascade ) {
57366
57367         var virtualLight = light.shadowCascadeArray[ cascade ];
57368
57369         virtualLight.position.copy( light.position );
57370         virtualLight.target.position.copy( light.target.position );
57371         virtualLight.lookAt( virtualLight.target );
57372
57373         virtualLight.shadowCameraVisible = light.shadowCameraVisible;
57374         virtualLight.shadowDarkness = light.shadowDarkness;
57375
57376         virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
57377
57378         var nearZ = light.shadowCascadeNearZ[ cascade ];
57379         var farZ = light.shadowCascadeFarZ[ cascade ];
57380
57381         var pointsFrustum = virtualLight.pointsFrustum;
57382
57383         pointsFrustum[ 0 ].z = nearZ;
57384         pointsFrustum[ 1 ].z = nearZ;
57385         pointsFrustum[ 2 ].z = nearZ;
57386         pointsFrustum[ 3 ].z = nearZ;
57387
57388         pointsFrustum[ 4 ].z = farZ;
57389         pointsFrustum[ 5 ].z = farZ;
57390         pointsFrustum[ 6 ].z = farZ;
57391         pointsFrustum[ 7 ].z = farZ;
57392
57393     }
57394
57395     // Fit shadow camera's ortho frustum to camera frustum
57396
57397     function updateShadowCamera( camera, light ) {
57398
57399         var shadowCamera = light.shadowCamera,
57400             pointsFrustum = light.pointsFrustum,
57401             pointsWorld = light.pointsWorld;
57402
57403         _min.set( Infinity, Infinity, Infinity );
57404         _max.set( -Infinity, -Infinity, -Infinity );
57405
57406         for ( var i = 0; i < 8; i ++ ) {
57407
57408             var p = pointsWorld[ i ];
57409
57410             p.copy( pointsFrustum[ i ] );
57411             THREE.ShadowMapPlugin.__projector.unprojectVector( p, camera );
57412
57413             shadowCamera.matrixWorldInverse.multiplyVector3( p );
57414
57415             if ( p.x < _min.x ) _min.x = p.x;
57416             if ( p.x > _max.x ) _max.x = p.x;
57417
57418             if ( p.y < _min.y ) _min.y = p.y;
57419             if ( p.y > _max.y ) _max.y = p.y;
57420
57421             if ( p.z < _min.z ) _min.z = p.z;
57422             if ( p.z > _max.z ) _max.z = p.z;
57423
57424         }
57425
57426         shadowCamera.left = _min.x;
57427         shadowCamera.right = _max.x;
57428         shadowCamera.top = _max.y;
57429         shadowCamera.bottom = _min.y;
57430
57431         // can't really fit near/far
57432         //shadowCamera.near = _min.z;
57433         //shadowCamera.far = _max.z;
57434
57435         shadowCamera.updateProjectionMatrix();
57436
57437     }
57438
57439 };
57440
57441 THREE.ShadowMapPlugin.__projector = new THREE.Projector();
57442 /**
57443  * @author mikael emtinger / http://gomo.se/
57444  * @author alteredq / http://alteredqualia.com/
57445  */
57446
57447 THREE.SpritePlugin = function ( ) {
57448
57449     var _gl, _renderer, _sprite = {};
57450
57451     this.init = function ( renderer ) {
57452
57453         _gl = renderer.context;
57454         _renderer = renderer;
57455
57456         _sprite.vertices = new Float32Array( 8 + 8 );
57457         _sprite.faces    = new Uint16Array( 6 );
57458
57459         var i = 0;
57460
57461         _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = -1;    // vertex 0
57462         _sprite.vertices[ i++ ] = 0;  _sprite.vertices[ i++ ] = 0;    // uv 0
57463
57464         _sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = -1;    // vertex 1
57465         _sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 0;    // uv 1
57466
57467         _sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 1;    // vertex 2
57468         _sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 1;    // uv 2
57469
57470         _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = 1;    // vertex 3
57471         _sprite.vertices[ i++ ] = 0;  _sprite.vertices[ i++ ] = 1;    // uv 3
57472
57473         i = 0;
57474
57475         _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 1; _sprite.faces[ i++ ] = 2;
57476         _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 2; _sprite.faces[ i++ ] = 3;
57477
57478         _sprite.vertexBuffer  = _gl.createBuffer();
57479         _sprite.elementBuffer = _gl.createBuffer();
57480
57481         _gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
57482         _gl.bufferData( _gl.ARRAY_BUFFER, _sprite.vertices, _gl.STATIC_DRAW );
57483
57484         _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
57485         _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _sprite.faces, _gl.STATIC_DRAW );
57486
57487         _sprite.program = createProgram( THREE.ShaderSprite[ "sprite" ] );
57488
57489         _sprite.attributes = {};
57490         _sprite.uniforms = {};
57491
57492         _sprite.attributes.position           = _gl.getAttribLocation ( _sprite.program, "position" );
57493         _sprite.attributes.uv                 = _gl.getAttribLocation ( _sprite.program, "uv" );
57494
57495         _sprite.uniforms.uvOffset             = _gl.getUniformLocation( _sprite.program, "uvOffset" );
57496         _sprite.uniforms.uvScale              = _gl.getUniformLocation( _sprite.program, "uvScale" );
57497
57498         _sprite.uniforms.rotation             = _gl.getUniformLocation( _sprite.program, "rotation" );
57499         _sprite.uniforms.scale                = _gl.getUniformLocation( _sprite.program, "scale" );
57500         _sprite.uniforms.alignment            = _gl.getUniformLocation( _sprite.program, "alignment" );
57501
57502         _sprite.uniforms.color                = _gl.getUniformLocation( _sprite.program, "color" );
57503         _sprite.uniforms.map                  = _gl.getUniformLocation( _sprite.program, "map" );
57504         _sprite.uniforms.opacity              = _gl.getUniformLocation( _sprite.program, "opacity" );
57505
57506         _sprite.uniforms.useScreenCoordinates = _gl.getUniformLocation( _sprite.program, "useScreenCoordinates" );
57507         _sprite.uniforms.affectedByDistance   = _gl.getUniformLocation( _sprite.program, "affectedByDistance" );
57508         _sprite.uniforms.screenPosition          = _gl.getUniformLocation( _sprite.program, "screenPosition" );
57509         _sprite.uniforms.modelViewMatrix      = _gl.getUniformLocation( _sprite.program, "modelViewMatrix" );
57510         _sprite.uniforms.projectionMatrix     = _gl.getUniformLocation( _sprite.program, "projectionMatrix" );
57511
57512         _sprite.attributesEnabled = false;
57513
57514     };
57515
57516     this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
57517
57518         var sprites = scene.__webglSprites,
57519             nSprites = sprites.length;
57520
57521         if ( ! nSprites ) return;
57522
57523         var attributes = _sprite.attributes,
57524             uniforms = _sprite.uniforms;
57525
57526         var invAspect = viewportHeight / viewportWidth;
57527
57528         var halfViewportWidth = viewportWidth * 0.5,
57529             halfViewportHeight = viewportHeight * 0.5;
57530
57531         var mergeWith3D = true;
57532
57533         // setup gl
57534
57535         _gl.useProgram( _sprite.program );
57536
57537         if ( ! _sprite.attributesEnabled ) {
57538
57539             _gl.enableVertexAttribArray( attributes.position );
57540             _gl.enableVertexAttribArray( attributes.uv );
57541
57542             _sprite.attributesEnabled = true;
57543
57544         }
57545
57546         _gl.disable( _gl.CULL_FACE );
57547         _gl.enable( _gl.BLEND );
57548         _gl.depthMask( true );
57549
57550         _gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
57551         _gl.vertexAttribPointer( attributes.position, 2, _gl.FLOAT, false, 2 * 8, 0 );
57552         _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
57553
57554         _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
57555
57556         _gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera._projectionMatrixArray );
57557
57558         _gl.activeTexture( _gl.TEXTURE0 );
57559         _gl.uniform1i( uniforms.map, 0 );
57560
57561         // update positions and sort
57562
57563         var i, sprite, screenPosition, size, scale = [];
57564
57565         for( i = 0; i < nSprites; i ++ ) {
57566
57567             sprite = sprites[ i ];
57568
57569             if ( ! sprite.visible || sprite.opacity === 0 ) continue;
57570
57571             if( ! sprite.useScreenCoordinates ) {
57572
57573                 sprite._modelViewMatrix.multiply( camera.matrixWorldInverse, sprite.matrixWorld );
57574                 sprite.z = - sprite._modelViewMatrix.elements[14];
57575
57576             } else {
57577
57578                 sprite.z = - sprite.position.z;
57579
57580             }
57581
57582         }
57583
57584         sprites.sort( painterSort );
57585
57586         // render all sprites
57587
57588         for( i = 0; i < nSprites; i ++ ) {
57589
57590             sprite = sprites[ i ];
57591
57592             if ( ! sprite.visible || sprite.opacity === 0 ) continue;
57593
57594             if ( sprite.map && sprite.map.image && sprite.map.image.width ) {
57595
57596                 if ( sprite.useScreenCoordinates ) {
57597
57598                     _gl.uniform1i( uniforms.useScreenCoordinates, 1 );
57599                     _gl.uniform3f( uniforms.screenPosition, ( sprite.position.x - halfViewportWidth  ) / halfViewportWidth,
57600                                                             ( halfViewportHeight - sprite.position.y ) / halfViewportHeight,
57601                                                               Math.max( 0, Math.min( 1, sprite.position.z ) ) );
57602
57603                 } else {
57604
57605                     _gl.uniform1i( uniforms.useScreenCoordinates, 0 );
57606                     _gl.uniform1i( uniforms.affectedByDistance, sprite.affectedByDistance ? 1 : 0 );
57607                     _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite._modelViewMatrix.elements );
57608
57609                 }
57610
57611                 size = sprite.map.image.width / ( sprite.scaleByViewport ? viewportHeight : 1 );
57612
57613                 scale[ 0 ] = size * invAspect * sprite.scale.x;
57614                 scale[ 1 ] = size * sprite.scale.y;
57615
57616                 _gl.uniform2f( uniforms.uvScale, sprite.uvScale.x, sprite.uvScale.y );
57617                 _gl.uniform2f( uniforms.uvOffset, sprite.uvOffset.x, sprite.uvOffset.y );
57618                 _gl.uniform2f( uniforms.alignment, sprite.alignment.x, sprite.alignment.y );
57619
57620                 _gl.uniform1f( uniforms.opacity, sprite.opacity );
57621                 _gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
57622
57623                 _gl.uniform1f( uniforms.rotation, sprite.rotation );
57624                 _gl.uniform2fv( uniforms.scale, scale );
57625
57626                 if ( sprite.mergeWith3D && !mergeWith3D ) {
57627
57628                     _gl.enable( _gl.DEPTH_TEST );
57629                     mergeWith3D = true;
57630
57631                 } else if ( ! sprite.mergeWith3D && mergeWith3D ) {
57632
57633                     _gl.disable( _gl.DEPTH_TEST );
57634                     mergeWith3D = false;
57635
57636                 }
57637
57638                 _renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
57639                 _renderer.setTexture( sprite.map, 0 );
57640
57641                 _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
57642
57643             }
57644
57645         }
57646
57647         // restore gl
57648
57649         _gl.enable( _gl.CULL_FACE );
57650         _gl.enable( _gl.DEPTH_TEST );
57651         _gl.depthMask( true );
57652
57653     };
57654
57655     function createProgram ( shader ) {
57656
57657         var program = _gl.createProgram();
57658
57659         var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
57660         var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
57661
57662         _gl.shaderSource( fragmentShader, shader.fragmentShader );
57663         _gl.shaderSource( vertexShader, shader.vertexShader );
57664
57665         _gl.compileShader( fragmentShader );
57666         _gl.compileShader( vertexShader );
57667
57668         _gl.attachShader( program, fragmentShader );
57669         _gl.attachShader( program, vertexShader );
57670
57671         _gl.linkProgram( program );
57672
57673         return program;
57674
57675     };
57676
57677     function painterSort ( a, b ) {
57678
57679         return b.z - a.z;
57680
57681     };
57682
57683 };/**
57684  * @author alteredq / http://alteredqualia.com/
57685  */
57686
57687 THREE.DepthPassPlugin = function ( ) {
57688
57689     this.enabled = false;
57690     this.renderTarget = null;
57691
57692     var _gl,
57693     _renderer,
57694     _depthMaterial, _depthMaterialMorph,
57695
57696     _frustum = new THREE.Frustum(),
57697     _projScreenMatrix = new THREE.Matrix4();
57698
57699     this.init = function ( renderer ) {
57700
57701         _gl = renderer.context;
57702         _renderer = renderer;
57703
57704         var depthShader = THREE.ShaderLib[ "depthRGBA" ];
57705         var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
57706
57707         _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
57708         _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
57709
57710         _depthMaterial._shadowPass = true;
57711         _depthMaterialMorph._shadowPass = true;
57712
57713     };
57714
57715     this.render = function ( scene, camera ) {
57716
57717         if ( ! this.enabled ) return;
57718
57719         this.update( scene, camera );
57720
57721     };
57722
57723     this.update = function ( scene, camera ) {
57724
57725         var i, il, j, jl, n,
57726
57727         program, buffer, material,
57728         webglObject, object, light,
57729         renderList,
57730
57731         fog = null;
57732
57733         // set GL state for depth map
57734
57735         _gl.clearColor( 1, 1, 1, 1 );
57736         _gl.disable( _gl.BLEND );
57737
57738         _renderer.setDepthTest( true );
57739
57740         // update scene
57741
57742         if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
57743
57744         // update camera matrices and frustum
57745
57746         if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
57747         if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
57748
57749         camera.matrixWorldInverse.getInverse( camera.matrixWorld );
57750
57751         camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );
57752         camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
57753
57754         _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
57755         _frustum.setFromMatrix( _projScreenMatrix );
57756
57757         // render depth map
57758
57759         _renderer.setRenderTarget( this.renderTarget );
57760         _renderer.clear();
57761
57762         // set object matrices & frustum culling
57763
57764         renderList = scene.__webglObjects;
57765
57766         for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57767
57768             webglObject = renderList[ j ];
57769             object = webglObject.object;
57770
57771             webglObject.render = false;
57772
57773             if ( object.visible ) {
57774
57775                 if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
57776
57777                     //object.matrixWorld.flattenToArray( object._modelMatrixArray );
57778                     object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld);
57779
57780                     webglObject.render = true;
57781
57782                 }
57783
57784             }
57785
57786         }
57787
57788         // render regular objects
57789
57790         for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57791
57792             webglObject = renderList[ j ];
57793
57794             if ( webglObject.render ) {
57795
57796                 object = webglObject.object;
57797                 buffer = webglObject.buffer;
57798
57799                 if ( object.material ) _renderer.setMaterialFaces( object.material );
57800
57801                 if ( object.customDepthMaterial ) {
57802
57803                     material = object.customDepthMaterial;
57804
57805                 } else if ( object.geometry.morphTargets.length ) {
57806
57807                     material = _depthMaterialMorph;
57808
57809                 } else {
57810
57811                     material = _depthMaterial;
57812
57813                 }
57814
57815                 if ( buffer instanceof THREE.BufferGeometry ) {
57816
57817                     _renderer.renderBufferDirect( camera, scene.__lights, fog, material, buffer, object );
57818
57819                 } else {
57820
57821                     _renderer.renderBuffer( camera, scene.__lights, fog, material, buffer, object );
57822
57823                 }
57824
57825             }
57826
57827         }
57828
57829         // set matrices and render immediate objects
57830
57831         renderList = scene.__webglObjectsImmediate;
57832
57833         for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57834
57835             webglObject = renderList[ j ];
57836             object = webglObject.object;
57837
57838             if ( object.visible && object.castShadow ) {
57839
57840                 /*
57841                 if ( object.matrixAutoUpdate ) {
57842
57843                     object.matrixWorld.flattenToArray( object._modelMatrixArray );
57844
57845                 }
57846                 */
57847
57848                 object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld);
57849
57850                 _renderer.renderImmediateObject( camera, scene.__lights, fog, _depthMaterial, object );
57851
57852             }
57853
57854         }
57855
57856         // restore GL state
57857
57858         var clearColor = _renderer.getClearColor(),
57859         clearAlpha = _renderer.getClearAlpha();
57860
57861         _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
57862         _gl.enable( _gl.BLEND );
57863
57864     };
57865
57866 };
57867
57868 /**
57869  * @author mikael emtinger / http://gomo.se/
57870  *
57871  */
57872
57873 THREE.ShaderFlares = {
57874
57875     'lensFlareVertexTexture': {
57876
57877         vertexShader: [
57878
57879             "uniform vec3 screenPosition;",
57880             "uniform vec2 scale;",
57881             "uniform float rotation;",
57882             "uniform int renderType;",
57883
57884             "uniform sampler2D occlusionMap;",
57885
57886             "attribute vec2 position;",
57887             "attribute vec2 uv;",
57888
57889             "varying vec2 vUV;",
57890             "varying float vVisibility;",
57891
57892             "void main() {",
57893
57894                 "vUV = uv;",
57895
57896                 "vec2 pos = position;",
57897
57898                 "if( renderType == 2 ) {",
57899
57900                     "vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) ) +",
57901                                       "texture2D( occlusionMap, vec2( 0.5, 0.1 ) ) +",
57902                                       "texture2D( occlusionMap, vec2( 0.9, 0.1 ) ) +",
57903                                       "texture2D( occlusionMap, vec2( 0.9, 0.5 ) ) +",
57904                                       "texture2D( occlusionMap, vec2( 0.9, 0.9 ) ) +",
57905                                       "texture2D( occlusionMap, vec2( 0.5, 0.9 ) ) +",
57906                                       "texture2D( occlusionMap, vec2( 0.1, 0.9 ) ) +",
57907                                       "texture2D( occlusionMap, vec2( 0.1, 0.5 ) ) +",
57908                                       "texture2D( occlusionMap, vec2( 0.5, 0.5 ) );",
57909
57910                     "vVisibility = (       visibility.r / 9.0 ) *",
57911                                   "( 1.0 - visibility.g / 9.0 ) *",
57912                                   "(       visibility.b / 9.0 ) *",
57913                                   "( 1.0 - visibility.a / 9.0 );",
57914
57915                     "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
57916                     "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
57917
57918                 "}",
57919
57920                 "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
57921
57922             "}"
57923
57924         ].join( "\n" ),
57925
57926         fragmentShader: [
57927
57928             "precision mediump float;",
57929
57930             "uniform sampler2D map;",
57931             "uniform float opacity;",
57932             "uniform int renderType;",
57933             "uniform vec3 color;",
57934
57935             "varying vec2 vUV;",
57936             "varying float vVisibility;",
57937
57938             "void main() {",
57939
57940                 // pink square
57941
57942                 "if( renderType == 0 ) {",
57943
57944                     "gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );",
57945
57946                 // restore
57947
57948                 "} else if( renderType == 1 ) {",
57949
57950                     "gl_FragColor = texture2D( map, vUV );",
57951
57952                 // flare
57953
57954                 "} else {",
57955
57956                     "vec4 texture = texture2D( map, vUV );",
57957                     "texture.a *= opacity * vVisibility;",
57958                     "gl_FragColor = texture;",
57959                     "gl_FragColor.rgb *= color;",
57960
57961                 "}",
57962
57963             "}"
57964         ].join( "\n" )
57965
57966     },
57967
57968
57969     'lensFlare': {
57970
57971         vertexShader: [
57972
57973             "uniform vec3 screenPosition;",
57974             "uniform vec2 scale;",
57975             "uniform float rotation;",
57976             "uniform int renderType;",
57977
57978             "attribute vec2 position;",
57979             "attribute vec2 uv;",
57980
57981             "varying vec2 vUV;",
57982
57983             "void main() {",
57984
57985                 "vUV = uv;",
57986
57987                 "vec2 pos = position;",
57988
57989                 "if( renderType == 2 ) {",
57990
57991                     "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
57992                     "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
57993
57994                 "}",
57995
57996                 "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
57997
57998             "}"
57999
58000         ].join( "\n" ),
58001
58002         fragmentShader: [
58003
58004             "precision mediump float;",
58005
58006             "uniform sampler2D map;",
58007             "uniform sampler2D occlusionMap;",
58008             "uniform float opacity;",
58009             "uniform int renderType;",
58010             "uniform vec3 color;",
58011
58012             "varying vec2 vUV;",
58013
58014             "void main() {",
58015
58016                 // pink square
58017
58018                 "if( renderType == 0 ) {",
58019
58020                     "gl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );",
58021
58022                 // restore
58023
58024                 "} else if( renderType == 1 ) {",
58025
58026                     "gl_FragColor = texture2D( map, vUV );",
58027
58028                 // flare
58029
58030                 "} else {",
58031
58032                     "float visibility = texture2D( occlusionMap, vec2( 0.5, 0.1 ) ).a +",
58033                                        "texture2D( occlusionMap, vec2( 0.9, 0.5 ) ).a +",
58034                                        "texture2D( occlusionMap, vec2( 0.5, 0.9 ) ).a +",
58035                                        "texture2D( occlusionMap, vec2( 0.1, 0.5 ) ).a;",
58036
58037                     "visibility = ( 1.0 - visibility / 4.0 );",
58038
58039                     "vec4 texture = texture2D( map, vUV );",
58040                     "texture.a *= opacity * visibility;",
58041                     "gl_FragColor = texture;",
58042                     "gl_FragColor.rgb *= color;",
58043
58044                 "}",
58045
58046             "}"
58047
58048         ].join( "\n" )
58049
58050     }
58051
58052 };
58053 /**
58054  * @author mikael emtinger / http://gomo.se/
58055  *
58056  */
58057
58058 THREE.ShaderSprite = {
58059
58060     'sprite': {
58061
58062         vertexShader: [
58063
58064             "uniform int useScreenCoordinates;",
58065             "uniform int affectedByDistance;",
58066             "uniform vec3 screenPosition;",
58067             "uniform mat4 modelViewMatrix;",
58068             "uniform mat4 projectionMatrix;",
58069             "uniform float rotation;",
58070             "uniform vec2 scale;",
58071             "uniform vec2 alignment;",
58072             "uniform vec2 uvOffset;",
58073             "uniform vec2 uvScale;",
58074
58075             "attribute vec2 position;",
58076             "attribute vec2 uv;",
58077
58078             "varying vec2 vUV;",
58079
58080             "void main() {",
58081
58082                 "vUV = uvOffset + uv * uvScale;",
58083
58084                 "vec2 alignedPosition = position + alignment;",
58085
58086                 "vec2 rotatedPosition;",
58087                 "rotatedPosition.x = ( cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y ) * scale.x;",
58088                 "rotatedPosition.y = ( sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y ) * scale.y;",
58089
58090                 "vec4 finalPosition;",
58091
58092                 "if( useScreenCoordinates != 0 ) {",
58093
58094                     "finalPosition = vec4( screenPosition.xy + rotatedPosition, screenPosition.z, 1.0 );",
58095
58096                 "} else {",
58097
58098                     "finalPosition = projectionMatrix * modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );",
58099                     "finalPosition.xy += rotatedPosition * ( affectedByDistance == 1 ? 1.0 : finalPosition.z );",
58100
58101                 "}",
58102
58103                 "gl_Position = finalPosition;",
58104
58105             "}"
58106
58107         ].join( "\n" ),
58108
58109         fragmentShader: [
58110
58111             "precision mediump float;",
58112
58113             "uniform vec3 color;",
58114             "uniform sampler2D map;",
58115             "uniform float opacity;",
58116
58117             "varying vec2 vUV;",
58118
58119             "void main() {",
58120
58121                 "vec4 texture = texture2D( map, vUV );",
58122                 "gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );",
58123
58124             "}"
58125
58126         ].join( "\n" )
58127
58128     }
58129
58130 };
58131 /**
58132  * @author alteredq / http://alteredqualia.com/
58133  *
58134  */
58135
58136
58137 THREE.ShaderSkin = {
58138
58139     /* ------------------------------------------------------------------------------------------
58140     //    Simple skin shader
58141     //        - per-pixel Blinn-Phong diffuse term mixed with half-Lambert wrap-around term (per color component)
58142     //        - physically based specular term (Kelemen/Szirmay-Kalos specular reflectance)
58143     //
58144     //        - diffuse map
58145     //        - bump map
58146     //        - specular map
58147     //        - point, directional and hemisphere lights (use with "lights: true" material option)
58148     //        - fog (use with "fog: true" material option)
58149     //        - shadow maps
58150     //
58151     // ------------------------------------------------------------------------------------------ */
58152
58153     'skinSimple' : {
58154
58155         uniforms: THREE.UniformsUtils.merge( [
58156
58157             THREE.UniformsLib[ "fog" ],
58158             THREE.UniformsLib[ "lights" ],
58159             THREE.UniformsLib[ "shadowmap" ],
58160
58161             {
58162
58163             "enableBump"    : { type: "i", value: 0 },
58164             "enableSpecular": { type: "i", value: 0 },
58165
58166             "tDiffuse"    : { type: "t", value: null },
58167             "tBeckmann"    : { type: "t", value: null },
58168
58169             "uDiffuseColor":  { type: "c", value: new THREE.Color( 0xeeeeee ) },
58170             "uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) },
58171             "uAmbientColor":  { type: "c", value: new THREE.Color( 0x050505 ) },
58172             "uOpacity":       { type: "f", value: 1 },
58173
58174             "uRoughness":               { type: "f", value: 0.15 },
58175             "uSpecularBrightness":     { type: "f", value: 0.75 },
58176
58177             "bumpMap"    : { type: "t", value: null },
58178             "bumpScale" : { type: "f", value: 1 },
58179
58180             "specularMap" : { type: "t", value: null },
58181
58182             "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
58183
58184             "uWrapRGB":    { type: "v3", value: new THREE.Vector3( 0.75, 0.375, 0.1875 ) }
58185
58186             }
58187
58188         ] ),
58189
58190         fragmentShader: [
58191
58192             "#define USE_BUMPMAP",
58193             "#extension GL_OES_standard_derivatives : enable",
58194
58195             "uniform bool enableBump;",
58196             "uniform bool enableSpecular;",
58197
58198             "uniform vec3 uAmbientColor;",
58199             "uniform vec3 uDiffuseColor;",
58200             "uniform vec3 uSpecularColor;",
58201             "uniform float uOpacity;",
58202
58203             "uniform float uRoughness;",
58204             "uniform float uSpecularBrightness;",
58205
58206             "uniform vec3 uWrapRGB;",
58207
58208             "uniform sampler2D tDiffuse;",
58209             "uniform sampler2D tBeckmann;",
58210
58211             "uniform sampler2D specularMap;",
58212
58213             "varying vec3 vNormal;",
58214             "varying vec2 vUv;",
58215
58216             "uniform vec3 ambientLightColor;",
58217
58218             "#if MAX_DIR_LIGHTS > 0",
58219
58220                 "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
58221                 "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
58222
58223             "#endif",
58224
58225             "#if MAX_HEMI_LIGHTS > 0",
58226
58227                 "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
58228                 "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
58229                 "uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
58230
58231             "#endif",
58232
58233             "#if MAX_POINT_LIGHTS > 0",
58234
58235                 "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
58236                 "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
58237                 "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
58238
58239             "#endif",
58240
58241             "varying vec3 vViewPosition;",
58242
58243             THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
58244             THREE.ShaderChunk[ "fog_pars_fragment" ],
58245             THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
58246
58247             // Fresnel term
58248
58249             "float fresnelReflectance( vec3 H, vec3 V, float F0 ) {",
58250
58251                 "float base = 1.0 - dot( V, H );",
58252                 "float exponential = pow( base, 5.0 );",
58253
58254                 "return exponential + F0 * ( 1.0 - exponential );",
58255
58256             "}",
58257
58258             // Kelemen/Szirmay-Kalos specular BRDF
58259
58260             "float KS_Skin_Specular( vec3 N,",         // Bumped surface normal
58261                                     "vec3 L,",         // Points to light
58262                                     "vec3 V,",         // Points to eye
58263                                     "float m,",      // Roughness
58264                                     "float rho_s",     // Specular brightness
58265                                     ") {",
58266
58267                 "float result = 0.0;",
58268                 "float ndotl = dot( N, L );",
58269
58270                 "if( ndotl > 0.0 ) {",
58271
58272                     "vec3 h = L + V;", // Unnormalized half-way vector
58273                     "vec3 H = normalize( h );",
58274
58275                     "float ndoth = dot( N, H );",
58276
58277                     "float PH = pow( 2.0 * texture2D( tBeckmann, vec2( ndoth, m ) ).x, 10.0 );",
58278
58279                     "float F = fresnelReflectance( H, V, 0.028 );",
58280                     "float frSpec = max( PH * F / dot( h, h ), 0.0 );",
58281
58282                     "result = ndotl * rho_s * frSpec;", // BRDF * dot(N,L) * rho_s
58283
58284                 "}",
58285
58286                 "return result;",
58287
58288             "}",
58289
58290             "void main() {",
58291
58292                 "gl_FragColor = vec4( vec3( 1.0 ), uOpacity );",
58293
58294                 "vec4 colDiffuse = texture2D( tDiffuse, vUv );",
58295                 "colDiffuse.rgb *= colDiffuse.rgb;",
58296
58297                 "gl_FragColor = gl_FragColor * colDiffuse;",
58298
58299                 "vec3 normal = normalize( vNormal );",
58300                 "vec3 viewPosition = normalize( vViewPosition );",
58301
58302                 "float specularStrength;",
58303
58304                 "if ( enableSpecular ) {",
58305
58306                     "vec4 texelSpecular = texture2D( specularMap, vUv );",
58307                     "specularStrength = texelSpecular.r;",
58308
58309                 "} else {",
58310
58311                     "specularStrength = 1.0;",
58312
58313                 "}",
58314
58315                 "#ifdef USE_BUMPMAP",
58316
58317                     "if ( enableBump ) normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );",
58318
58319                 "#endif",
58320
58321                 // point lights
58322
58323                 "vec3 specularTotal = vec3( 0.0 );",
58324
58325                 "#if MAX_POINT_LIGHTS > 0",
58326
58327                     "vec3 pointTotal = vec3( 0.0 );",
58328
58329                     "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
58330
58331                         "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
58332
58333                         "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",
58334
58335                         "float lDistance = 1.0;",
58336
58337                         "if ( pointLightDistance[ i ] > 0.0 )",
58338                             "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
58339
58340                         "lVector = normalize( lVector );",
58341
58342                         "float pointDiffuseWeightFull = max( dot( normal, lVector ), 0.0 );",
58343                         "float pointDiffuseWeightHalf = max( 0.5 * dot( normal, lVector ) + 0.5, 0.0 );",
58344                         "vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), uWrapRGB );",
58345
58346                         "float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
58347
58348                         "pointTotal    += lDistance * uDiffuseColor * pointLightColor[ i ] * pointDiffuseWeight;",
58349                         "specularTotal += lDistance * uSpecularColor * pointLightColor[ i ] * pointSpecularWeight * specularStrength;",
58350
58351                     "}",
58352
58353                 "#endif",
58354
58355                 // directional lights
58356
58357                 "#if MAX_DIR_LIGHTS > 0",
58358
58359                     "vec3 dirTotal = vec3( 0.0 );",
58360
58361                     "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
58362
58363                         "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
58364
58365                         "vec3 dirVector = normalize( lDirection.xyz );",
58366
58367                         "float dirDiffuseWeightFull = max( dot( normal, dirVector ), 0.0 );",
58368                         "float dirDiffuseWeightHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );",
58369                         "vec3 dirDiffuseWeight = mix( vec3 ( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), uWrapRGB );",
58370
58371                         "float dirSpecularWeight =  KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
58372
58373                         "dirTotal        += uDiffuseColor * directionalLightColor[ i ] * dirDiffuseWeight;",
58374                         "specularTotal += uSpecularColor * directionalLightColor[ i ] * dirSpecularWeight * specularStrength;",
58375
58376                     "}",
58377
58378                 "#endif",
58379
58380                 // hemisphere lights
58381
58382                 "#if MAX_HEMI_LIGHTS > 0",
58383
58384                     "vec3 hemiTotal = vec3( 0.0 );",
58385
58386                     "for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
58387
58388                         "vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
58389                         "vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
58390
58391                         "float dotProduct = dot( normal, lVector );",
58392                         "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
58393
58394                         "hemiTotal += uDiffuseColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
58395
58396                         // specular (sky light)
58397
58398                         "float hemiSpecularWeight = 0.0;",
58399                         "hemiSpecularWeight += KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
58400
58401                         // specular (ground light)
58402
58403                         "vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
58404                         "hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewPosition, uRoughness, uSpecularBrightness );",
58405
58406                         "specularTotal += uSpecularColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * specularStrength;",
58407
58408                     "}",
58409
58410                 "#endif",
58411
58412                 // all lights contribution summation
58413
58414                 "vec3 totalLight = vec3( 0.0 );",
58415
58416                 "#if MAX_DIR_LIGHTS > 0",
58417                     "totalLight += dirTotal;",
58418                 "#endif",
58419
58420                 "#if MAX_POINT_LIGHTS > 0",
58421                     "totalLight += pointTotal;",
58422                 "#endif",
58423
58424                 "#if MAX_HEMI_LIGHTS > 0",
58425                     "totalLight += hemiTotal;",
58426                 "#endif",
58427
58428                 "gl_FragColor.xyz = gl_FragColor.xyz * ( totalLight + ambientLightColor * uAmbientColor ) + specularTotal;",
58429
58430                 THREE.ShaderChunk[ "shadowmap_fragment" ],
58431                 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
58432                 THREE.ShaderChunk[ "fog_fragment" ],
58433
58434             "}"
58435
58436         ].join("\n"),
58437
58438         vertexShader: [
58439
58440             "uniform vec4 offsetRepeat;",
58441
58442             "varying vec3 vNormal;",
58443             "varying vec2 vUv;",
58444
58445             "varying vec3 vViewPosition;",
58446
58447             THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
58448
58449             "void main() {",
58450
58451                 "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
58452                 "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
58453
58454                 "vViewPosition = -mvPosition.xyz;",
58455
58456                 "vNormal = normalMatrix * normal;",
58457
58458                 "vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
58459
58460                 "gl_Position = projectionMatrix * mvPosition;",
58461
58462                 THREE.ShaderChunk[ "shadowmap_vertex" ],
58463
58464             "}"
58465
58466         ].join( "\n" )
58467
58468     },
58469
58470     /* ------------------------------------------------------------------------------------------
58471     //    Skin shader
58472     //        - Blinn-Phong diffuse term (using normal + diffuse maps)
58473     //        - subsurface scattering approximation by four blur layers
58474     //        - physically based specular term (Kelemen/Szirmay-Kalos specular reflectance)
58475     //
58476     //        - point and directional lights (use with "lights: true" material option)
58477     //
58478     //        - based on Nvidia Advanced Skin Rendering GDC 2007 presentation
58479     //          and GPU Gems 3 Chapter 14. Advanced Techniques for Realistic Real-Time Skin Rendering
58480     //
58481     //            http://developer.download.nvidia.com/presentations/2007/gdc/Advanced_Skin.pdf
58482     //            http://http.developer.nvidia.com/GPUGems3/gpugems3_ch14.html
58483     // ------------------------------------------------------------------------------------------ */
58484
58485     'skin' : {
58486
58487         uniforms: THREE.UniformsUtils.merge( [
58488
58489             THREE.UniformsLib[ "fog" ],
58490             THREE.UniformsLib[ "lights" ],
58491
58492             {
58493
58494             "passID": { type: "i", value: 0 },
58495
58496             "tDiffuse"    : { type: "t", value: null },
58497             "tNormal"    : { type: "t", value: null },
58498
58499             "tBlur1"    : { type: "t", value: null },
58500             "tBlur2"    : { type: "t", value: null },
58501             "tBlur3"    : { type: "t", value: null },
58502             "tBlur4"    : { type: "t", value: null },
58503
58504             "tBeckmann"    : { type: "t", value: null },
58505
58506             "uNormalScale": { type: "f", value: 1.0 },
58507
58508             "uDiffuseColor":  { type: "c", value: new THREE.Color( 0xeeeeee ) },
58509             "uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) },
58510             "uAmbientColor":  { type: "c", value: new THREE.Color( 0x050505 ) },
58511             "uOpacity":       { type: "f", value: 1 },
58512
58513             "uRoughness":               { type: "f", value: 0.15 },
58514             "uSpecularBrightness":     { type: "f", value: 0.75 }
58515
58516             }
58517
58518         ] ),
58519
58520         fragmentShader: [
58521
58522             "uniform vec3 uAmbientColor;",
58523             "uniform vec3 uDiffuseColor;",
58524             "uniform vec3 uSpecularColor;",
58525             "uniform float uOpacity;",
58526
58527             "uniform float uRoughness;",
58528             "uniform float uSpecularBrightness;",
58529
58530             "uniform int passID;",
58531
58532             "uniform sampler2D tDiffuse;",
58533             "uniform sampler2D tNormal;",
58534
58535             "uniform sampler2D tBlur1;",
58536             "uniform sampler2D tBlur2;",
58537             "uniform sampler2D tBlur3;",
58538             "uniform sampler2D tBlur4;",
58539
58540             "uniform sampler2D tBeckmann;",
58541
58542             "uniform float uNormalScale;",
58543
58544             "varying vec3 vTangent;",
58545             "varying vec3 vBinormal;",
58546             "varying vec3 vNormal;",
58547             "varying vec2 vUv;",
58548
58549             "uniform vec3 ambientLightColor;",
58550
58551             "#if MAX_DIR_LIGHTS > 0",
58552                 "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
58553                 "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
58554             "#endif",
58555
58556             "#if MAX_POINT_LIGHTS > 0",
58557                 "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
58558                 "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
58559             "#endif",
58560
58561             "varying vec3 vViewPosition;",
58562
58563             THREE.ShaderChunk[ "fog_pars_fragment" ],
58564
58565             "float fresnelReflectance( vec3 H, vec3 V, float F0 ) {",
58566
58567                 "float base = 1.0 - dot( V, H );",
58568                 "float exponential = pow( base, 5.0 );",
58569
58570                 "return exponential + F0 * ( 1.0 - exponential );",
58571
58572             "}",
58573
58574             // Kelemen/Szirmay-Kalos specular BRDF
58575
58576             "float KS_Skin_Specular( vec3 N,",         // Bumped surface normal
58577                                     "vec3 L,",         // Points to light
58578                                     "vec3 V,",         // Points to eye
58579                                     "float m,",      // Roughness
58580                                     "float rho_s",     // Specular brightness
58581                                     ") {",
58582
58583                 "float result = 0.0;",
58584                 "float ndotl = dot( N, L );",
58585
58586                 "if( ndotl > 0.0 ) {",
58587
58588                     "vec3 h = L + V;", // Unnormalized half-way vector
58589                     "vec3 H = normalize( h );",
58590
58591                     "float ndoth = dot( N, H );",
58592
58593                     "float PH = pow( 2.0 * texture2D( tBeckmann, vec2( ndoth, m ) ).x, 10.0 );",
58594                     "float F = fresnelReflectance( H, V, 0.028 );",
58595                     "float frSpec = max( PH * F / dot( h, h ), 0.0 );",
58596
58597                     "result = ndotl * rho_s * frSpec;", // BRDF * dot(N,L) * rho_s
58598
58599                 "}",
58600
58601                 "return result;",
58602
58603             "}",
58604
58605             "void main() {",
58606
58607                 "gl_FragColor = vec4( 1.0 );",
58608
58609                 "vec4 mColor = vec4( uDiffuseColor, uOpacity );",
58610                 "vec4 mSpecular = vec4( uSpecularColor, uOpacity );",
58611
58612                 "vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
58613                 "normalTex.xy *= uNormalScale;",
58614                 "normalTex = normalize( normalTex );",
58615
58616                 "vec4 colDiffuse = texture2D( tDiffuse, vUv );",
58617                 "colDiffuse *= colDiffuse;",
58618
58619                 "gl_FragColor = gl_FragColor * colDiffuse;",
58620
58621                 "mat3 tsb = mat3( vTangent, vBinormal, vNormal );",
58622                 "vec3 finalNormal = tsb * normalTex;",
58623
58624                 "vec3 normal = normalize( finalNormal );",
58625                 "vec3 viewPosition = normalize( vViewPosition );",
58626
58627                 // point lights
58628
58629                 "vec3 specularTotal = vec3( 0.0 );",
58630
58631                 "#if MAX_POINT_LIGHTS > 0",
58632
58633                     "vec4 pointTotal = vec4( vec3( 0.0 ), 1.0 );",
58634
58635                     "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
58636
58637                         "vec3 pointVector = normalize( vPointLight[ i ].xyz );",
58638                         "float pointDistance = vPointLight[ i ].w;",
58639
58640                         "float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
58641
58642                         "pointTotal  += pointDistance * vec4( pointLightColor[ i ], 1.0 ) * ( mColor * pointDiffuseWeight );",
58643
58644                         "if ( passID == 1 )",
58645                             "specularTotal += pointDistance * mSpecular.xyz * pointLightColor[ i ] * KS_Skin_Specular( normal, pointVector, viewPosition, uRoughness, uSpecularBrightness );",
58646
58647                     "}",
58648
58649                 "#endif",
58650
58651                 // directional lights
58652
58653                 "#if MAX_DIR_LIGHTS > 0",
58654
58655                     "vec4 dirTotal = vec4( vec3( 0.0 ), 1.0 );",
58656
58657                     "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
58658
58659                         "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
58660
58661                         "vec3 dirVector = normalize( lDirection.xyz );",
58662
58663                         "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
58664
58665                         "dirTotal  += vec4( directionalLightColor[ i ], 1.0 ) * ( mColor * dirDiffuseWeight );",
58666
58667                         "if ( passID == 1 )",
58668                             "specularTotal += mSpecular.xyz * directionalLightColor[ i ] * KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
58669
58670                     "}",
58671
58672                 "#endif",
58673
58674                 // all lights contribution summation
58675
58676                 "vec4 totalLight = vec4( vec3( 0.0 ), uOpacity );",
58677
58678                 "#if MAX_DIR_LIGHTS > 0",
58679                     "totalLight += dirTotal;",
58680                 "#endif",
58681
58682                 "#if MAX_POINT_LIGHTS > 0",
58683                     "totalLight += pointTotal;",
58684                 "#endif",
58685
58686                 "gl_FragColor = gl_FragColor * totalLight;",
58687
58688                 "if ( passID == 0 ) {",
58689
58690                     "gl_FragColor = vec4( sqrt( gl_FragColor.xyz ), gl_FragColor.w );",
58691
58692                 "} else if ( passID == 1 ) {",
58693
58694                     //"#define VERSION1",
58695
58696                     "#ifdef VERSION1",
58697
58698                         "vec3 nonblurColor = sqrt( gl_FragColor.xyz );",
58699
58700                     "#else",
58701
58702                         "vec3 nonblurColor = gl_FragColor.xyz;",
58703
58704                     "#endif",
58705
58706                     "vec3 blur1Color = texture2D( tBlur1, vUv ).xyz;",
58707                     "vec3 blur2Color = texture2D( tBlur2, vUv ).xyz;",
58708                     "vec3 blur3Color = texture2D( tBlur3, vUv ).xyz;",
58709                     "vec3 blur4Color = texture2D( tBlur4, vUv ).xyz;",
58710
58711
58712                     //"gl_FragColor = vec4( blur1Color, gl_FragColor.w );",
58713
58714                     //"gl_FragColor = vec4( vec3( 0.22, 0.5, 0.7 ) * nonblurColor + vec3( 0.2, 0.5, 0.3 ) * blur1Color + vec3( 0.58, 0.0, 0.0 ) * blur2Color, gl_FragColor.w );",
58715
58716                     //"gl_FragColor = vec4( vec3( 0.25, 0.6, 0.8 ) * nonblurColor + vec3( 0.15, 0.25, 0.2 ) * blur1Color + vec3( 0.15, 0.15, 0.0 ) * blur2Color + vec3( 0.45, 0.0, 0.0 ) * blur3Color, gl_FragColor.w );",
58717
58718
58719                     "gl_FragColor = vec4( vec3( 0.22,  0.437, 0.635 ) * nonblurColor + ",
58720                                          "vec3( 0.101, 0.355, 0.365 ) * blur1Color + ",
58721                                          "vec3( 0.119, 0.208, 0.0 )   * blur2Color + ",
58722                                          "vec3( 0.114, 0.0,   0.0 )   * blur3Color + ",
58723                                          "vec3( 0.444, 0.0,   0.0 )   * blur4Color",
58724                                          ", gl_FragColor.w );",
58725
58726                     "gl_FragColor.xyz *= pow( colDiffuse.xyz, vec3( 0.5 ) );",
58727
58728                     "gl_FragColor.xyz += ambientLightColor * uAmbientColor * colDiffuse.xyz + specularTotal;",
58729
58730                     "#ifndef VERSION1",
58731
58732                         "gl_FragColor.xyz = sqrt( gl_FragColor.xyz );",
58733
58734                     "#endif",
58735
58736                 "}",
58737
58738                 THREE.ShaderChunk[ "fog_fragment" ],
58739
58740             "}"
58741
58742         ].join("\n"),
58743
58744         vertexShader: [
58745
58746             "attribute vec4 tangent;",
58747
58748             "#ifdef VERTEX_TEXTURES",
58749
58750                 "uniform sampler2D tDisplacement;",
58751                 "uniform float uDisplacementScale;",
58752                 "uniform float uDisplacementBias;",
58753
58754             "#endif",
58755
58756             "varying vec3 vTangent;",
58757             "varying vec3 vBinormal;",
58758             "varying vec3 vNormal;",
58759             "varying vec2 vUv;",
58760
58761             "#if MAX_POINT_LIGHTS > 0",
58762
58763                 "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
58764                 "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
58765
58766                 "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
58767
58768             "#endif",
58769
58770             "varying vec3 vViewPosition;",
58771
58772             "void main() {",
58773
58774                 "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
58775
58776                 "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
58777
58778                 "vViewPosition = -mvPosition.xyz;",
58779
58780                 "vNormal = normalize( normalMatrix * normal );",
58781
58782                 // tangent and binormal vectors
58783
58784                 "vTangent = normalize( normalMatrix * tangent.xyz );",
58785
58786                 "vBinormal = cross( vNormal, vTangent ) * tangent.w;",
58787                 "vBinormal = normalize( vBinormal );",
58788
58789                 "vUv = uv;",
58790
58791                 // point lights
58792
58793                 "#if MAX_POINT_LIGHTS > 0",
58794
58795                     "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
58796
58797                         "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
58798
58799                         "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
58800
58801                         "float lDistance = 1.0;",
58802
58803                         "if ( pointLightDistance[ i ] > 0.0 )",
58804                             "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
58805
58806                         "lVector = normalize( lVector );",
58807
58808                         "vPointLight[ i ] = vec4( lVector, lDistance );",
58809
58810                     "}",
58811
58812                 "#endif",
58813
58814                 // displacement mapping
58815
58816                 "#ifdef VERTEX_TEXTURES",
58817
58818                     "vec3 dv = texture2D( tDisplacement, uv ).xyz;",
58819                     "float df = uDisplacementScale * dv.x + uDisplacementBias;",
58820                     "vec4 displacedPosition = vec4( vNormal.xyz * df, 0.0 ) + mvPosition;",
58821                     "gl_Position = projectionMatrix * displacedPosition;",
58822
58823                 "#else",
58824
58825                     "gl_Position = projectionMatrix * mvPosition;",
58826
58827                 "#endif",
58828
58829             "}"
58830
58831         ].join("\n"),
58832
58833         vertexShaderUV: [
58834
58835             "attribute vec4 tangent;",
58836
58837             "#ifdef VERTEX_TEXTURES",
58838
58839                 "uniform sampler2D tDisplacement;",
58840                 "uniform float uDisplacementScale;",
58841                 "uniform float uDisplacementBias;",
58842
58843             "#endif",
58844
58845             "varying vec3 vTangent;",
58846             "varying vec3 vBinormal;",
58847             "varying vec3 vNormal;",
58848             "varying vec2 vUv;",
58849
58850             "#if MAX_POINT_LIGHTS > 0",
58851
58852                 "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
58853                 "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
58854
58855                 "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
58856
58857             "#endif",
58858
58859             "varying vec3 vViewPosition;",
58860
58861             "void main() {",
58862
58863                 "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
58864
58865                 "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
58866
58867                 "vViewPosition = -mvPosition.xyz;",
58868
58869                 "vNormal = normalize( normalMatrix * normal );",
58870
58871                 // tangent and binormal vectors
58872
58873                 "vTangent = normalize( normalMatrix * tangent.xyz );",
58874
58875                 "vBinormal = cross( vNormal, vTangent ) * tangent.w;",
58876                 "vBinormal = normalize( vBinormal );",
58877
58878                 "vUv = uv;",
58879
58880                 // point lights
58881
58882                 "#if MAX_POINT_LIGHTS > 0",
58883
58884                     "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
58885
58886                         "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
58887
58888                         "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
58889
58890                         "float lDistance = 1.0;",
58891
58892                         "if ( pointLightDistance[ i ] > 0.0 )",
58893                             "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
58894
58895                         "lVector = normalize( lVector );",
58896
58897                         "vPointLight[ i ] = vec4( lVector, lDistance );",
58898
58899                     "}",
58900
58901                 "#endif",
58902
58903                 "gl_Position = vec4( uv.x * 2.0 - 1.0, uv.y * 2.0 - 1.0, 0.0, 1.0 );",
58904
58905             "}"
58906
58907         ].join("\n")
58908
58909     },
58910
58911     /* ------------------------------------------------------------------------------------------
58912     // Beckmann distribution function
58913     //    - to be used in specular term of skin shader
58914     //    - render a screen-aligned quad to precompute a 512 x 512 texture
58915     //
58916     //        - from http://developer.nvidia.com/node/171
58917      ------------------------------------------------------------------------------------------ */
58918
58919     "beckmann" : {
58920
58921         uniforms: {},
58922
58923         vertexShader: [
58924
58925             "varying vec2 vUv;",
58926
58927             "void main() {",
58928
58929                 "vUv = uv;",
58930                 "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
58931
58932             "}"
58933
58934         ].join("\n"),
58935
58936         fragmentShader: [
58937
58938             "varying vec2 vUv;",
58939
58940             "float PHBeckmann( float ndoth, float m ) {",
58941
58942                 "float alpha = acos( ndoth );",
58943                 "float ta = tan( alpha );",
58944
58945                 "float val = 1.0 / ( m * m * pow( ndoth, 4.0 ) ) * exp( -( ta * ta ) / ( m * m ) );",
58946                 "return val;",
58947
58948             "}",
58949
58950             "float KSTextureCompute( vec2 tex ) {",
58951
58952                 // Scale the value to fit within [0,1]  invert upon lookup.
58953
58954                 "return 0.5 * pow( PHBeckmann( tex.x, tex.y ), 0.1 );",
58955
58956             "}",
58957
58958             "void main() {",
58959
58960                 "float x = KSTextureCompute( vUv );",
58961
58962                 "gl_FragColor = vec4( x, x, x, 1.0 );",
58963
58964             "}"
58965
58966         ].join("\n")
58967
58968     }
58969
58970 };
58971 //////////////////////////////////////////////////////////////////////////////
58972 //                                                                          //
58973 // Wii Opera SDK - Drawing Class v2.6.16 2008-12-14                         //
58974 // (c) 2007-2008 Daniel Gump. All Rights Reserved.                          //
58975 // http://wiioperasdk.com, http://hullbreachonline.com                      //
58976 // hullbreach@hullbreachonline.com                                          //
58977 //                                                                          //
58978 //  Wii is a trademark of Nintendo Co., Ltd.                                //
58979 //  Opera is a trademark of Opera, ASA.                                     //
58980 //  This software package is not associated with either company             //
58981 //  but was created to support users of both.  Its alternative name         //
58982 //  when supporting other products is the HULLBREACH SDK.                   //
58983 //                                                                          //
58984 //  Redistribution and use in source and binary forms, with or without      //
58985 //  modification, are permitted provided that the following conditions      //
58986 //  are met:                                                                //
58987 //    * Redistributions of source code must retain the above copyright      //
58988 //      notice, this list of conditions and the following disclaimer.       //
58989 //    * Redistributions in binary form must reproduce the above copyright   //
58990 //      notice, this list of conditions and the following disclaimer in     //
58991 //      the documentation and/or other materials provided with the          //
58992 //      distribution.                                                       //
58993 //    * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names //
58994 //      of its contributors may be used to endorse or promote products      //
58995 //      derived from this software without specific prior written           //
58996 //      permission.                                                         //
58997 //    * If the explicit purpose of the software is not to support the       //
58998 //      Nintendo Wii or the Opera Web browser, then the names of such must  //
58999 //      not be used in any derived product. The name shall be the           //
59000 //      HULLBREACH SDK with a reference link to http://hullbreachonline.    //
59001 //                                                                          //
59002 //  THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   //
59003 //  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          //
59004 //  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  //
59005 //  DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     //
59006 //  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      //
59007 //  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      //
59008 //  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      //
59009 //  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     //
59010 //  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   //
59011 //  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      //
59012 //  POSSIBILITY OF SUCH DAMAGE.                                             //
59013 //////////////////////////////////////////////////////////////////////////////
59014
59015 function Drawing(){
59016         this.WIREFRAME = 1; this.FILL = 2;
59017         ZOOM = 1;
59018         CANVAS = null;
59019         TEXTURES = null;
59020 }
59021 Drawing.prototype.initialize = function(canvas){
59022         CANVAS = canvas.getContext("2d");
59023         CANVAS.lineJoin = "round";
59024         CANVAS.lineWidth = 1;
59025 }
59026 Drawing.prototype.loadTextures = function(textures){ TEXTURES = textures; }
59027 Drawing.prototype.setFillColor = function(r,g,b){ CANVAS.fillStyle = "rgb("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+")"; }
59028 Drawing.prototype.setFillColorA = function(r,g,b,a){ CANVAS.fillStyle = "rgba("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+", "+(a>255?1:(a<0?0:a/255))+")"; }
59029 Drawing.prototype.setLineColor = function(r,g,b){ CANVAS.strokeStyle = "rgb("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+")"; }
59030 Drawing.prototype.setLineColorA = function(r,g,b,a){ CANVAS.strokeStyle = "rgba("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+", "+(a>255?1:(a<0?0:a/255))+")"; }
59031 Drawing.prototype.clipCircle = function(centerx,centery,radius){ CANVAS.beginPath(); CANVAS.arc(centerx,centery,radius,0,6.28318531,false); CANVAS.clip(); }
59032 Drawing.prototype.clipRectangle = function(x1,y1,x2,y2){ CANVAS.beginPath(); CANVAS.strokeRect(x1,y1,x2-x1,y2-y1); CANVAS.clip(); }
59033 Drawing.prototype.drawCircle = function(centerx,centery,radius,style){
59034         CANVAS.beginPath();
59035         CANVAS.arc(centerx, centery, radius, 0, Math.PI*2, false);
59036         if(style & this.FILL) CANVAS.fill();
59037         if(style & this.WIREFRAME) CANVAS.stroke();
59038 }
59039 Drawing.prototype.drawImage = function(x1,y1,x2,y2,img,angle){
59040         if(img.complete){
59041                 x1|=0;
59042                 y1|=0;
59043                 x2|=0;
59044                 y2|=0;
59045                 if(x2<x1) x2=x1+1;
59046                 if(y2<y1) y2=y1+1;
59047                 var centerx = (x1+x2)>>1;
59048                 var centery = (y1+y2)>>1;
59049
59050                 CANVAS.save();
59051                 CANVAS.translate(centerx, centery);
59052                 if(angle) CANVAS.rotate(angle*0.01745329);
59053                 CANVAS.drawImage(img, x1-centerx, y1-centery, x2-x1, y2-y1);
59054                 CANVAS.restore();
59055         }
59056 }
59057 Drawing.prototype.drawLine = function(x1, y1, x2, y2){ CANVAS.beginPath(); CANVAS.moveTo(x1|0, y1|0); CANVAS.lineTo(x2|0, y2|0); CANVAS.stroke(); }
59058 Drawing.prototype.drawRectangle = function(x1, y1, x2, y2, style, angle){
59059         x1|=0;
59060         y1|=0;
59061         x2|=0;
59062         y2|=0;
59063         
59064         if(!angle){
59065                 if(style & this.FILL) CANVAS.fillRect(x1, y1, x2-x1, y2-y1);
59066                 if(style & this.WIREFRAME) CANVAS.strokeRect(x1, y1, x2-x1, y2-y1);
59067         }else{
59068                 var centerx = (x1+x2)>>1; var centery = (y1+y2)>>1;
59069
59070                 CANVAS.save();
59071                 CANVAS.translate(centerx, centery);
59072                 CANVAS.rotate(angle*DEGTORAD);
59073                 if(style & this.FILL) CANVAS.fillRect(x1-centerx, y1-centery, x2-x1, y2-y1);
59074                 if(style & this.WIREFRAME) CANVAS.strokeRect(x1-centerx, y1-centery, x2-x1, y2-y1);
59075                 CANVAS.restore();
59076         }
59077 }
59078 Drawing.prototype.drawScene = function(array,style){
59079         var piOver2 = 1.570796326794897;
59080         var piOver4 = 0.785398163397448;
59081         var sqrt2half = 1.414213562373095;
59082
59083         for(tri=array.length;--tri>=0;){
59084                 var x1 = array[tri][0];
59085                 var y1 = array[tri][1];
59086                 var x2 = array[tri][2];
59087                 var y2 = array[tri][3];
59088                 var x3 = array[tri][4];
59089                 var y3 = array[tri][5];
59090                 shade=array[tri][10];
59091
59092                 if(TEXTURES && array[tri][9]>=0){
59093                         CANVAS.save();
59094
59095                         var u = (x2-x3)*(x2-x3)+(y2-y3)*(y2-y3);
59096                         var v = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
59097                         var w = (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
59098
59099                         var canvasRot = 0.5*Math.acos((w+v-u)/(2*Math.sqrt(w*v)));
59100                         var scale = Math.cos(canvasRot)*sqrt2half;
59101
59102                         CANVAS.translate(x1,y1);
59103                         CANVAS.rotate(Math.atan2(y2-y1,x2-x1)-piOver2+canvasRot);
59104                         CANVAS.scale(Math.tan(canvasRot),1);
59105                         CANVAS.rotate(piOver4);
59106                         CANVAS.scale(Math.sqrt(w)*scale,Math.sqrt(v)*scale);
59107                         //CANVAS.transform(x2-x1,y2-y1,x3-x1,y3-y1, x1,y1);
59108                         CANVAS.drawImage((canvasimg = TEXTURES[array[tri][9]]), 0,0, canvasimg.width,canvasimg.height, 0,0, 1,1);
59109                         CANVAS.restore();
59110
59111                         if(shade!=0){
59112                                 CANVAS.beginPath();
59113                                 CANVAS.moveTo(x1,y1);
59114                                 CANVAS.lineTo(x2,y2);
59115                                 CANVAS.lineTo(x3,y3);
59116                                 CANVAS.lineTo(x1,y1);
59117                                 if(shade>0){
59118                                         if(shade>1) shade=1;
59119                                         CANVAS.fillStyle = "rgba(255,255,255,"+(shade)+")";
59120                                         CANVAS.strokeStyle = "rgba(255,255,255,"+(shade*.5)+")";
59121                                 }else if(shade<0){
59122                                         if(shade<-1) shade=-1;
59123                                         CANVAS.fillStyle = "rgba(0,0,0,"+(-shade)+")";
59124                                         CANVAS.strokeStyle = "rgba(0,0,0,"+(-shade*.5)+")";
59125                                 }
59126                                 if(style & this.FILL) CANVAS.fill();
59127                                 if(style & this.WIREFRAME) CANVAS.stroke();
59128                         }
59129                 }else{
59130                         var red = array[tri][6];
59131                         var green = array[tri][7];
59132                         var blue = array[tri][8];
59133                         if(shade!=0){
59134                                 red=(red*=++shade)>255?255:(red<0?0:red);
59135                                 green=(green*=shade)>255?255:(green<0?0:green);
59136                                 blue=(blue*=shade)>255?255:(blue<0?0:blue);
59137                         }
59138                         var color = "rgb("+(red|0)+","+(green|0)+","+(blue|0)+")";
59139                         CANVAS.beginPath();
59140                         CANVAS.moveTo(x1,y1);
59141                         CANVAS.lineTo(x2,y2);
59142                         CANVAS.lineTo(x3,y3);
59143                         CANVAS.lineTo(x1,y1);
59144                         if(style & this.FILL){ CANVAS.fillStyle = color; CANVAS.fill(); }
59145                         if(style & this.WIREFRAME){ CANVAS.strokeStyle = color; CANVAS.stroke(); }
59146                 }
59147         }
59148 }
59149
59150 Drawing.prototype.drawFloor = function(x1,x2,y1,x3,x4,y2,img){
59151         if((x2|=0)==(x1|=0)) x2++;
59152         if((y2|=0)==(y1|=0)) y2++;
59153         if((x4|=0)==(x3|=0)) x4++;
59154         var absdy=(dy = y2-y1)<0?-dy:dy;
59155
59156         var sourceD = img.width-1, sourceY = (img.height-1)*(dx2 = x4-x3)/dy;
59157         var destX = (x3-x1)/dy;
59158         var tempY = 0;
59159         var destW2 = (dx1 = x2-x1);
59160
59161         var absscale = (fullscale = 1.5*(dy>>31?-1:1)+dy/img.height)>>31?-(fullscale-1):(fullscale+1);
59162         var destwfullscale = fullscale*(dx2-dx1+1)/dy;
59163
59164         while(tempY<0?-tempY:tempY<=absdy){
59165                 CANVAS.drawImage(img, 0, sourceY*tempY/destW2, sourceD, 1, x1+destX*tempY, tempY+y1, destW2, absscale);
59166                 tempY+=fullscale;
59167                 destW2+=destwfullscale;
59168         }       
59169 }
59170 Drawing.prototype.drawWall = function(x1,y1,y2,x2,y3,y4,img){
59171         if(x2==x1) x2++;
59172         if(y2==y1) y2++;
59173         if(y4==y3) y4++;
59174         var dx = x2-x1, dy1 = y2-y1, dy2 = y4-y3;
59175         var absdx=dx<0?-dx:dx;
59176
59177         var sourceH = img.height-1, sourceX = (img.width-1)*dy2/dx;
59178         var destY = (y3-y1)/dx;
59179         var tempX = 0;
59180
59181         var fullscale = 1.5*(dx<0?-1:1)+dx/img.width;
59182         var absscale = fullscale<0?(-fullscale-1):(fullscale+1);
59183         var desthfullscale = fullscale*(dy2-dy1+1)/dx;
59184
59185         while(tempX<0?-tempX:tempX<=absdx){
59186                 CANVAS.drawImage(img, sourceX*tempX/dy1, 0, 1, sourceH, tempX+x1, y1+destY*tempX, absscale, dy1);
59187                 tempX+=fullscale;
59188                 dy1+=desthfullscale;
59189         }       
59190 }
59191 Drawing.prototype.zoom = function(zoom,width,height){
59192         ZOOM = zoom;
59193         CANVAS.translate(width>>1, height>>1);
59194         CANVAS.scale(ZOOM, ZOOM);
59195         CANVAS.translate(-width>>1, -height>>1);
59196 }
59197 Drawing.prototype.unZoom = function(width,height){
59198         CANVAS.translate(width>>1, height>>1);
59199         CANVAS.scale(1/ZOOM, 1/ZOOM);
59200         CANVAS.translate(-width>>1, -height>>1);
59201         ZOOM = 1;
59202 }
59203 Drawing.prototype.clear = function(x1, y1, x2, y2){ CANVAS.clearRect(x1, y1, x2-x1, y2-y1); }
59204
59205 Draw = new Drawing();var jWorkflow=function(){return{order:function(h,j){var i=[],f,d=null,g=function(){var a=false;return{take:function(){a=true},pass:function(b){var c;a=false;if(f.length){c=f.shift();b=c.func.apply(c.context,[b,g]);a||g.pass(b)}else d.func&&d.func.apply(d.context,[])}}}(),e={andThen:function(a,b){if(typeof a!=="function")throw"expected function but was "+typeof a;i.push({func:a,context:b});return e},chill:function(a){return e.andThen(function(b,c){c.take();setTimeout(function(){c.pass(b)},a)})},start:function(a,
59206 b){d={func:a,context:b};f=i.slice();g.pass()}};return h?e.andThen(h,j):e}}}();if(typeof module==="object"&&typeof require==="function")module.exports=jWorkflow;
59207 /*
59208   OpenLayers.js -- OpenLayers Map Viewer Library
59209
59210   Copyright 2005-2010 OpenLayers Contributors, released under the Clear BSD
59211   license. Full license text below taken from http://svn.openlayers.org/trunk/openlayers/license.txt
59212
59213         Copyright 2005-2011 OpenLayers Contributors. All rights reserved. See
59214         authors.txt for full list.
59215          
59216         Redistribution and use in source and binary forms, with or without modification,
59217         are permitted provided that the following conditions are met:
59218          
59219         1. Redistributions of source code must retain the above copyright notice, this
59220         list of conditions and the following disclaimer.
59221          
59222         2. Redistributions in binary form must reproduce the above copyright notice,
59223         this list of conditions and the following disclaimer in the documentation and/or
59224         other materials provided with the distribution.
59225          
59226         THIS SOFTWARE IS PROVIDED BY OPENLAYERS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
59227         OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
59228         MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
59229         SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
59230         INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
59231         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
59232         PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
59233         LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
59234         OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
59235         ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59236          
59237         The views and conclusions contained in the software and documentation are those
59238         of the authors and should not be interpreted as representing official policies,
59239         either expressed or implied, of OpenLayers Contributors.
59240
59241   Includes compressed code under the following licenses:
59242
59243   (For uncompressed versions of the code used please see the
59244   OpenLayers SVN repository: <http://openlayers.org/>)
59245
59246 */
59247
59248 /**  
59249 *  
59250 *  Contains portions of Rico <http://openrico.org/>
59251
59252 *  Copyright 2005 Sabre Airline Solutions  
59253 *  
59254 *  Licensed under the Apache License, Version 2.0 (the "License"); you
59255 *  may not use this file except in compliance with the License. You
59256 *  may obtain a copy of the License at
59257 *  
59258 *         http://www.apache.org/licenses/LICENSE-2.0  
59259 *  
59260 *  Unless required by applicable law or agreed to in writing, software
59261 *  distributed under the License is distributed on an "AS IS" BASIS,
59262 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
59263 *  implied. See the License for the specific language governing
59264 *  permissions and limitations under the License. 
59265 *
59266 **/
59267
59268 /**
59269  * Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
59270  * Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
59271  *
59272  * Licensed under the Apache License, Version 2.0 (the "License");
59273  * you may not use this file except in compliance with the License.
59274  * You may obtain a copy of the License at
59275  * http://www.apache.org/licenses/LICENSE-2.0
59276  */
59277
59278 /**
59279  * Contains portions of Gears <http://code.google.com/apis/gears/>
59280  *
59281  * Copyright 2007, Google Inc.
59282  *
59283  * Redistribution and use in source and binary forms, with or without
59284  * modification, are permitted provided that the following conditions are met:
59285  *
59286  *  1. Redistributions of source code must retain the above copyright notice,
59287  *     this list of conditions and the following disclaimer.
59288  *  2. Redistributions in binary form must reproduce the above copyright notice,
59289  *     this list of conditions and the following disclaimer in the documentation
59290  *     and/or other materials provided with the distribution.
59291  *  3. Neither the name of Google Inc. nor the names of its contributors may be
59292  *     used to endorse or promote products derived from this software without
59293  *     specific prior written permission.
59294  *
59295  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
59296  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
59297  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
59298  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
59299  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59300  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
59301  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59302  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
59303  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
59304  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59305  *
59306  * Sets up google.gears.*, which is *the only* supported way to access Gears.
59307  *
59308  * Circumvent this file at your own risk!
59309  *
59310  * In the future, Gears may automatically define google.gears.* without this
59311  * file. Gears may use these objects to transparently fix bugs and compatibility
59312  * issues. Applications that use the code below will continue to work seamlessly
59313  * when that happens.
59314  */
59315 var OpenLayers={singleFile:true};(function(){var singleFile=(typeof OpenLayers=="object"&&OpenLayers.singleFile);var scriptLocation;window.OpenLayers={_scriptName:(!singleFile)?"lib/OpenLayers.js":"OpenLayers.js",_getScriptLocation:function(){if(scriptLocation!=undefined){return scriptLocation;}
59316 scriptLocation="";var isOL=new RegExp("(^|(.*?\\/))("+OpenLayers._scriptName+")(\\?|$)");var scripts=document.getElementsByTagName('script');for(var i=0,len=scripts.length;i<len;i++){var src=scripts[i].getAttribute('src');if(src){var match=src.match(isOL);if(match){scriptLocation=match[1];break;}}}
59317 return scriptLocation;}};if(!singleFile){var jsfiles=new Array("OpenLayers/Util.js","OpenLayers/BaseTypes.js","OpenLayers/BaseTypes/Class.js","OpenLayers/BaseTypes/Bounds.js","OpenLayers/BaseTypes/Element.js","OpenLayers/BaseTypes/LonLat.js","OpenLayers/BaseTypes/Pixel.js","OpenLayers/BaseTypes/Size.js","OpenLayers/Console.js","OpenLayers/Tween.js","Rico/Corner.js","Rico/Color.js","OpenLayers/Ajax.js","OpenLayers/Events.js","OpenLayers/Request.js","OpenLayers/Request/XMLHttpRequest.js","OpenLayers/Projection.js","OpenLayers/Map.js","OpenLayers/Layer.js","OpenLayers/Icon.js","OpenLayers/Marker.js","OpenLayers/Marker/Box.js","OpenLayers/Popup.js","OpenLayers/Tile.js","OpenLayers/Tile/Image.js","OpenLayers/Tile/Image/IFrame.js","OpenLayers/Tile/WFS.js","OpenLayers/Layer/Image.js","OpenLayers/Layer/SphericalMercator.js","OpenLayers/Layer/EventPane.js","OpenLayers/Layer/FixedZoomLevels.js","OpenLayers/Layer/Google.js","OpenLayers/Layer/Google/v3.js","OpenLayers/Layer/VirtualEarth.js","OpenLayers/Layer/Yahoo.js","OpenLayers/Layer/HTTPRequest.js","OpenLayers/Layer/Grid.js","OpenLayers/Layer/MapGuide.js","OpenLayers/Layer/MapServer.js","OpenLayers/Layer/MapServer/Untiled.js","OpenLayers/Layer/KaMap.js","OpenLayers/Layer/KaMapCache.js","OpenLayers/Layer/MultiMap.js","OpenLayers/Layer/Markers.js","OpenLayers/Layer/Text.js","OpenLayers/Layer/WorldWind.js","OpenLayers/Layer/ArcGIS93Rest.js","OpenLayers/Layer/WMS.js","OpenLayers/Layer/WMS/Untiled.js","OpenLayers/Layer/WMS/Post.js","OpenLayers/Layer/WMTS.js","OpenLayers/Layer/ArcIMS.js","OpenLayers/Layer/GeoRSS.js","OpenLayers/Layer/Boxes.js","OpenLayers/Layer/XYZ.js","OpenLayers/Layer/TMS.js","OpenLayers/Layer/TileCache.js","OpenLayers/Layer/Zoomify.js","OpenLayers/Popup/Anchored.js","OpenLayers/Popup/AnchoredBubble.js","OpenLayers/Popup/Framed.js","OpenLayers/Popup/FramedCloud.js","OpenLayers/Feature.js","OpenLayers/Feature/Vector.js","OpenLayers/Feature/WFS.js","OpenLayers/Handler.js","OpenLayers/Handler/Click.js","OpenLayers/Handler/Hover.js","OpenLayers/Handler/Point.js","OpenLayers/Handler/Path.js","OpenLayers/Handler/Polygon.js","OpenLayers/Handler/Feature.js","OpenLayers/Handler/Drag.js","OpenLayers/Handler/RegularPolygon.js","OpenLayers/Handler/Box.js","OpenLayers/Handler/MouseWheel.js","OpenLayers/Handler/Keyboard.js","OpenLayers/Control.js","OpenLayers/Control/Attribution.js","OpenLayers/Control/Button.js","OpenLayers/Control/ZoomBox.js","OpenLayers/Control/ZoomToMaxExtent.js","OpenLayers/Control/DragPan.js","OpenLayers/Control/Navigation.js","OpenLayers/Control/MouseDefaults.js","OpenLayers/Control/MousePosition.js","OpenLayers/Control/OverviewMap.js","OpenLayers/Control/KeyboardDefaults.js","OpenLayers/Control/PanZoom.js","OpenLayers/Control/PanZoomBar.js","OpenLayers/Control/ArgParser.js","OpenLayers/Control/Permalink.js","OpenLayers/Control/Scale.js","OpenLayers/Control/ScaleLine.js","OpenLayers/Control/Snapping.js","OpenLayers/Control/Split.js","OpenLayers/Control/LayerSwitcher.js","OpenLayers/Control/DrawFeature.js","OpenLayers/Control/DragFeature.js","OpenLayers/Control/ModifyFeature.js","OpenLayers/Control/Panel.js","OpenLayers/Control/SelectFeature.js","OpenLayers/Control/NavigationHistory.js","OpenLayers/Control/Measure.js","OpenLayers/Control/WMSGetFeatureInfo.js","OpenLayers/Control/WMTSGetFeatureInfo.js","OpenLayers/Control/Graticule.js","OpenLayers/Control/TransformFeature.js","OpenLayers/Control/SLDSelect.js","OpenLayers/Geometry.js","OpenLayers/Geometry/Rectangle.js","OpenLayers/Geometry/Collection.js","OpenLayers/Geometry/Point.js","OpenLayers/Geometry/MultiPoint.js","OpenLayers/Geometry/Curve.js","OpenLayers/Geometry/LineString.js","OpenLayers/Geometry/LinearRing.js","OpenLayers/Geometry/Polygon.js","OpenLayers/Geometry/MultiLineString.js","OpenLayers/Geometry/MultiPolygon.js","OpenLayers/Geometry/Surface.js","OpenLayers/Renderer.js","OpenLayers/Renderer/Elements.js","OpenLayers/Renderer/SVG.js","OpenLayers/Renderer/Canvas.js","OpenLayers/Renderer/VML.js","OpenLayers/Layer/Vector.js","OpenLayers/Layer/Vector/RootContainer.js","OpenLayers/Strategy.js","OpenLayers/Strategy/Filter.js","OpenLayers/Strategy/Fixed.js","OpenLayers/Strategy/Cluster.js","OpenLayers/Strategy/Paging.js","OpenLayers/Strategy/BBOX.js","OpenLayers/Strategy/Save.js","OpenLayers/Strategy/Refresh.js","OpenLayers/Filter.js","OpenLayers/Filter/FeatureId.js","OpenLayers/Filter/Logical.js","OpenLayers/Filter/Comparison.js","OpenLayers/Filter/Spatial.js","OpenLayers/Protocol.js","OpenLayers/Protocol/HTTP.js","OpenLayers/Protocol/SQL.js","OpenLayers/Protocol/SQL/Gears.js","OpenLayers/Protocol/WFS.js","OpenLayers/Protocol/WFS/v1.js","OpenLayers/Protocol/WFS/v1_0_0.js","OpenLayers/Protocol/WFS/v1_1_0.js","OpenLayers/Protocol/SOS.js","OpenLayers/Protocol/SOS/v1_0_0.js","OpenLayers/Layer/PointTrack.js","OpenLayers/Layer/GML.js","OpenLayers/Style.js","OpenLayers/Style2.js","OpenLayers/StyleMap.js","OpenLayers/Rule.js","OpenLayers/Format.js","OpenLayers/Format/XML.js","OpenLayers/Format/Context.js","OpenLayers/Format/ArcXML.js","OpenLayers/Format/ArcXML/Features.js","OpenLayers/Format/GML.js","OpenLayers/Format/GML/Base.js","OpenLayers/Format/GML/v2.js","OpenLayers/Format/GML/v3.js","OpenLayers/Format/Atom.js","OpenLayers/Format/KML.js","OpenLayers/Format/GeoRSS.js","OpenLayers/Format/WFS.js","OpenLayers/Format/WFSCapabilities.js","OpenLayers/Format/WFSCapabilities/v1.js","OpenLayers/Format/WFSCapabilities/v1_0_0.js","OpenLayers/Format/WFSCapabilities/v1_1_0.js","OpenLayers/Format/WFSDescribeFeatureType.js","OpenLayers/Format/WMSDescribeLayer.js","OpenLayers/Format/WMSDescribeLayer/v1_1.js","OpenLayers/Format/WKT.js","OpenLayers/Format/OSM.js","OpenLayers/Format/GPX.js","OpenLayers/Format/Filter.js","OpenLayers/Format/Filter/v1.js","OpenLayers/Format/Filter/v1_0_0.js","OpenLayers/Format/Filter/v1_1_0.js","OpenLayers/Format/SLD.js","OpenLayers/Format/SLD/v1.js","OpenLayers/Format/SLD/v1_0_0.js","OpenLayers/Format/OWSCommon/v1.js","OpenLayers/Format/OWSCommon/v1_0_0.js","OpenLayers/Format/OWSCommon/v1_1_0.js","OpenLayers/Format/CSWGetDomain.js","OpenLayers/Format/CSWGetDomain/v2_0_2.js","OpenLayers/Format/CSWGetRecords.js","OpenLayers/Format/CSWGetRecords/v2_0_2.js","OpenLayers/Format/WFST.js","OpenLayers/Format/WFST/v1.js","OpenLayers/Format/WFST/v1_0_0.js","OpenLayers/Format/WFST/v1_1_0.js","OpenLayers/Format/Text.js","OpenLayers/Format/JSON.js","OpenLayers/Format/GeoJSON.js","OpenLayers/Format/WMC.js","OpenLayers/Format/WMC/v1.js","OpenLayers/Format/WMC/v1_0_0.js","OpenLayers/Format/WMC/v1_1_0.js","OpenLayers/Format/WMSCapabilities.js","OpenLayers/Format/WMSCapabilities/v1.js","OpenLayers/Format/WMSCapabilities/v1_1.js","OpenLayers/Format/WMSCapabilities/v1_1_0.js","OpenLayers/Format/WMSCapabilities/v1_1_1.js","OpenLayers/Format/WMSCapabilities/v1_3.js","OpenLayers/Format/WMSCapabilities/v1_3_0.js","OpenLayers/Format/WMSGetFeatureInfo.js","OpenLayers/Format/SOSCapabilities.js","OpenLayers/Format/SOSCapabilities/v1_0_0.js","OpenLayers/Format/SOSGetObservation.js","OpenLayers/Format/SOSGetFeatureOfInterest.js","OpenLayers/Format/OWSContext.js","OpenLayers/Format/OWSContext/v0_3_1.js","OpenLayers/Format/WMTSCapabilities.js","OpenLayers/Format/WMTSCapabilities/v1_0_0.js","OpenLayers/Layer/WFS.js","OpenLayers/Control/GetFeature.js","OpenLayers/Control/MouseToolbar.js","OpenLayers/Control/NavToolbar.js","OpenLayers/Control/PanPanel.js","OpenLayers/Control/Pan.js","OpenLayers/Control/ZoomIn.js","OpenLayers/Control/ZoomOut.js","OpenLayers/Control/ZoomPanel.js","OpenLayers/Control/EditingToolbar.js","OpenLayers/Symbolizer.js","OpenLayers/Symbolizer/Point.js","OpenLayers/Symbolizer/Line.js","OpenLayers/Symbolizer/Polygon.js","OpenLayers/Symbolizer/Text.js","OpenLayers/Symbolizer/Raster.js","OpenLayers/Lang.js","OpenLayers/Lang/en.js");var agent=navigator.userAgent;var docWrite=(agent.match("MSIE")||agent.match("Safari"));if(docWrite){var allScriptTags=new Array(jsfiles.length);}
59318 var host=OpenLayers._getScriptLocation()+"lib/";for(var i=0,len=jsfiles.length;i<len;i++){if(docWrite){allScriptTags[i]="<script src='"+host+jsfiles[i]+"'></script>";}else{var s=document.createElement("script");s.src=host+jsfiles[i];var h=document.getElementsByTagName("head").length?document.getElementsByTagName("head")[0]:document.body;h.appendChild(s);}}
59319 if(docWrite){document.write(allScriptTags.join(""));}}})();OpenLayers.VERSION_NUMBER="OpenLayers 2.10 -- $Revision: 10721 $";OpenLayers.String={startsWith:function(str,sub){return(str.indexOf(sub)==0);},contains:function(str,sub){return(str.indexOf(sub)!=-1);},trim:function(str){return str.replace(/^\s\s*/,'').replace(/\s\s*$/,'');},camelize:function(str){var oStringList=str.split('-');var camelizedString=oStringList[0];for(var i=1,len=oStringList.length;i<len;i++){var s=oStringList[i];camelizedString+=s.charAt(0).toUpperCase()+s.substring(1);}
59320 return camelizedString;},format:function(template,context,args){if(!context){context=window;}
59321 var replacer=function(str,match){var replacement;var subs=match.split(/\.+/);for(var i=0;i<subs.length;i++){if(i==0){replacement=context;}
59322 replacement=replacement[subs[i]];}
59323 if(typeof replacement=="function"){replacement=args?replacement.apply(null,args):replacement();}
59324 if(typeof replacement=='undefined'){return'undefined';}else{return replacement;}};return template.replace(OpenLayers.String.tokenRegEx,replacer);},tokenRegEx:/\$\{([\w.]+?)\}/g,numberRegEx:/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/,isNumeric:function(value){return OpenLayers.String.numberRegEx.test(value);},numericIf:function(value){return OpenLayers.String.isNumeric(value)?parseFloat(value):value;}};if(!String.prototype.startsWith){String.prototype.startsWith=function(sStart){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.startsWith'}));return OpenLayers.String.startsWith(this,sStart);};}
59325 if(!String.prototype.contains){String.prototype.contains=function(str){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.contains'}));return OpenLayers.String.contains(this,str);};}
59326 if(!String.prototype.trim){String.prototype.trim=function(){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.trim'}));return OpenLayers.String.trim(this);};}
59327 if(!String.prototype.camelize){String.prototype.camelize=function(){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.camelize'}));return OpenLayers.String.camelize(this);};}
59328 OpenLayers.Number={decimalSeparator:".",thousandsSeparator:",",limitSigDigs:function(num,sig){var fig=0;if(sig>0){fig=parseFloat(num.toPrecision(sig));}
59329 return fig;},format:function(num,dec,tsep,dsep){dec=(typeof dec!="undefined")?dec:0;tsep=(typeof tsep!="undefined")?tsep:OpenLayers.Number.thousandsSeparator;dsep=(typeof dsep!="undefined")?dsep:OpenLayers.Number.decimalSeparator;if(dec!=null){num=parseFloat(num.toFixed(dec));}
59330 var parts=num.toString().split(".");if(parts.length==1&&dec==null){dec=0;}
59331 var integer=parts[0];if(tsep){var thousands=/(-?[0-9]+)([0-9]{3})/;while(thousands.test(integer)){integer=integer.replace(thousands,"$1"+tsep+"$2");}}
59332 var str;if(dec==0){str=integer;}else{var rem=parts.length>1?parts[1]:"0";if(dec!=null){rem=rem+new Array(dec-rem.length+1).join("0");}
59333 str=integer+dsep+rem;}
59334 return str;}};if(!Number.prototype.limitSigDigs){Number.prototype.limitSigDigs=function(sig){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Number.limitSigDigs'}));return OpenLayers.Number.limitSigDigs(this,sig);};}
59335 OpenLayers.Function={bind:function(func,object){var args=Array.prototype.slice.apply(arguments,[2]);return function(){var newArgs=args.concat(Array.prototype.slice.apply(arguments,[0]));return func.apply(object,newArgs);};},bindAsEventListener:function(func,object){return function(event){return func.call(object,event||window.event);};},False:function(){return false;},True:function(){return true;}};if(!Function.prototype.bind){Function.prototype.bind=function(){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Function.bind'}));Array.prototype.unshift.apply(arguments,[this]);return OpenLayers.Function.bind.apply(null,arguments);};}
59336 if(!Function.prototype.bindAsEventListener){Function.prototype.bindAsEventListener=function(object){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Function.bindAsEventListener'}));return OpenLayers.Function.bindAsEventListener(this,object);};}
59337 OpenLayers.Array={filter:function(array,callback,caller){var selected=[];if(Array.prototype.filter){selected=array.filter(callback,caller);}else{var len=array.length;if(typeof callback!="function"){throw new TypeError();}
59338 for(var i=0;i<len;i++){if(i in array){var val=array[i];if(callback.call(caller,val,i,array)){selected.push(val);}}}}
59339 return selected;}};OpenLayers.Date={toISOString:(function(){if("toISOString"in Date.prototype){return function(date){return date.toISOString();}}else{function pad(num,len){var str=num+"";while(str.length<len){str="0"+str;}
59340 return str;}
59341 return function(date){var str;if(isNaN(date.getTime())){str="Invalid Date";}else{str=date.getUTCFullYear()+"-"+
59342 pad(date.getUTCMonth()+1,2)+"-"+
59343 pad(date.getUTCDate(),2)+"T"+
59344 pad(date.getUTCHours(),2)+":"+
59345 pad(date.getUTCMinutes(),2)+":"+
59346 pad(date.getUTCSeconds(),2)+"."+
59347 pad(date.getUTCMilliseconds(),3)+"Z";}
59348 return str;}}})(),parse:function(str){var date;var elapsed=Date.parse(str);if(!isNaN(elapsed)){date=new Date(elapsed);}else{var match=str.match(/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{1,2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|(?:[+-]\d{1,2}(?::(\d{2}))?)))?$/);var date;if(match&&(match[1]||match[7])){var year=parseInt(match[1],10)||0;var month=(parseInt(match[2],10)-1)||0;var day=parseInt(match[3],10)||1;date=new Date(Date.UTC(year,month,day));var type=match[7];if(type){var hours=parseInt(match[4],10);var minutes=parseInt(match[5],10);var secFrac=parseFloat(match[6]);var seconds=secFrac|0;var milliseconds=Math.round(1000*(secFrac-seconds));date.setUTCHours(hours,minutes,seconds,milliseconds);if(type!=="Z"){var hoursOffset=parseInt(type,10);var minutesOffset=parseInt(match[8])||0;var offset=-1000*(60*(hoursOffset*60)+minutesOffset*60);date=new Date(date.getTime()+offset);}}}else{date=new Date("invalid");}}
59349 return date;}};OpenLayers.Class=function(){var Class=function(){if(arguments&&arguments[0]!=OpenLayers.Class.isPrototype){this.initialize.apply(this,arguments);}};var extended={};var parent,initialize,Type;for(var i=0,len=arguments.length;i<len;++i){Type=arguments[i];if(typeof Type=="function"){if(i==0&&len>1){initialize=Type.prototype.initialize;Type.prototype.initialize=function(){};extended=new Type();if(initialize===undefined){delete Type.prototype.initialize;}else{Type.prototype.initialize=initialize;}}
59350 parent=Type.prototype;}else{parent=Type;}
59351 OpenLayers.Util.extend(extended,parent);}
59352 Class.prototype=extended;return Class;};OpenLayers.Class.isPrototype=function(){};OpenLayers.Class.create=function(){return function(){if(arguments&&arguments[0]!=OpenLayers.Class.isPrototype){this.initialize.apply(this,arguments);}};};OpenLayers.Class.inherit=function(){var superClass=arguments[0];var proto=new superClass(OpenLayers.Class.isPrototype);for(var i=1,len=arguments.length;i<len;i++){if(typeof arguments[i]=="function"){var mixin=arguments[i];arguments[i]=new mixin(OpenLayers.Class.isPrototype);}
59353 OpenLayers.Util.extend(proto,arguments[i]);}
59354 return proto;};OpenLayers.Util={};OpenLayers.Util.getElement=function(){var elements=[];for(var i=0,len=arguments.length;i<len;i++){var element=arguments[i];if(typeof element=='string'){element=document.getElementById(element);}
59355 if(arguments.length==1){return element;}
59356 elements.push(element);}
59357 return elements;};OpenLayers.Util.isElement=function(o){return!!(o&&o.nodeType===1);};if(typeof window.$==="undefined"){window.$=OpenLayers.Util.getElement;}
59358 OpenLayers.Util.extend=function(destination,source){destination=destination||{};if(source){for(var property in source){var value=source[property];if(value!==undefined){destination[property]=value;}}
59359 var sourceIsEvt=typeof window.Event=="function"&&source instanceof window.Event;if(!sourceIsEvt&&source.hasOwnProperty&&source.hasOwnProperty('toString')){destination.toString=source.toString;}}
59360 return destination;};OpenLayers.Util.removeItem=function(array,item){for(var i=array.length-1;i>=0;i--){if(array[i]==item){array.splice(i,1);}}
59361 return array;};OpenLayers.Util.clearArray=function(array){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'array = []'}));array.length=0;};OpenLayers.Util.indexOf=function(array,obj){if(typeof array.indexOf=="function"){return array.indexOf(obj);}else{for(var i=0,len=array.length;i<len;i++){if(array[i]==obj){return i;}}
59362 return-1;}};OpenLayers.Util.modifyDOMElement=function(element,id,px,sz,position,border,overflow,opacity){if(id){element.id=id;}
59363 if(px){element.style.left=px.x+"px";element.style.top=px.y+"px";}
59364 if(sz){element.style.width=sz.w+"px";element.style.height=sz.h+"px";}
59365 if(position){element.style.position=position;}
59366 if(border){element.style.border=border;}
59367 if(overflow){element.style.overflow=overflow;}
59368 if(parseFloat(opacity)>=0.0&&parseFloat(opacity)<1.0){element.style.filter='alpha(opacity='+(opacity*100)+')';element.style.opacity=opacity;}else if(parseFloat(opacity)==1.0){element.style.filter='';element.style.opacity='';}};OpenLayers.Util.createDiv=function(id,px,sz,imgURL,position,border,overflow,opacity){var dom=document.createElement('div');if(imgURL){dom.style.backgroundImage='url('+imgURL+')';}
59369 if(!id){id=OpenLayers.Util.createUniqueID("OpenLayersDiv");}
59370 if(!position){position="absolute";}
59371 OpenLayers.Util.modifyDOMElement(dom,id,px,sz,position,border,overflow,opacity);return dom;};OpenLayers.Util.createImage=function(id,px,sz,imgURL,position,border,opacity,delayDisplay){var image=document.createElement("img");if(!id){id=OpenLayers.Util.createUniqueID("OpenLayersDiv");}
59372 if(!position){position="relative";}
59373 OpenLayers.Util.modifyDOMElement(image,id,px,sz,position,border,null,opacity);if(delayDisplay){image.style.display="none";OpenLayers.Event.observe(image,"load",OpenLayers.Function.bind(OpenLayers.Util.onImageLoad,image));OpenLayers.Event.observe(image,"error",OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError,image));}
59374 image.style.alt=id;image.galleryImg="no";if(imgURL){image.src=imgURL;}
59375 return image;};OpenLayers.Util.setOpacity=function(element,opacity){OpenLayers.Util.modifyDOMElement(element,null,null,null,null,null,null,opacity);};OpenLayers.Util.onImageLoad=function(){if(!this.viewRequestID||(this.map&&this.viewRequestID==this.map.viewRequestID)){this.style.display="";}
59376 OpenLayers.Element.removeClass(this,"olImageLoadError");};OpenLayers.IMAGE_RELOAD_ATTEMPTS=0;OpenLayers.Util.onImageLoadError=function(){this._attempts=(this._attempts)?(this._attempts+1):1;if(this._attempts<=OpenLayers.IMAGE_RELOAD_ATTEMPTS){var urls=this.urls;if(urls&&urls instanceof Array&&urls.length>1){var src=this.src.toString();var current_url,k;for(k=0;current_url=urls[k];k++){if(src.indexOf(current_url)!=-1){break;}}
59377 var guess=Math.floor(urls.length*Math.random());var new_url=urls[guess];k=0;while(new_url==current_url&&k++<4){guess=Math.floor(urls.length*Math.random());new_url=urls[guess];}
59378 this.src=src.replace(current_url,new_url);}else{this.src=this.src;}}else{OpenLayers.Element.addClass(this,"olImageLoadError");}
59379 this.style.display="";};OpenLayers.Util.alphaHackNeeded=null;OpenLayers.Util.alphaHack=function(){if(OpenLayers.Util.alphaHackNeeded==null){var arVersion=navigator.appVersion.split("MSIE");var version=parseFloat(arVersion[1]);var filter=false;try{filter=!!(document.body.filters);}catch(e){}
59380 OpenLayers.Util.alphaHackNeeded=(filter&&(version>=5.5)&&(version<7));}
59381 return OpenLayers.Util.alphaHackNeeded;};OpenLayers.Util.modifyAlphaImageDiv=function(div,id,px,sz,imgURL,position,border,sizing,opacity){OpenLayers.Util.modifyDOMElement(div,id,px,sz,position,null,null,opacity);var img=div.childNodes[0];if(imgURL){img.src=imgURL;}
59382 OpenLayers.Util.modifyDOMElement(img,div.id+"_innerImage",null,sz,"relative",border);if(OpenLayers.Util.alphaHack()){if(div.style.display!="none"){div.style.display="inline-block";}
59383 if(sizing==null){sizing="scale";}
59384 div.style.filter="progid:DXImageTransform.Microsoft"+".AlphaImageLoader(src='"+img.src+"', "+"sizingMethod='"+sizing+"')";if(parseFloat(div.style.opacity)>=0.0&&parseFloat(div.style.opacity)<1.0){div.style.filter+=" alpha(opacity="+div.style.opacity*100+")";}
59385 img.style.filter="alpha(opacity=0)";}};OpenLayers.Util.createAlphaImageDiv=function(id,px,sz,imgURL,position,border,sizing,opacity,delayDisplay){var div=OpenLayers.Util.createDiv();var img=OpenLayers.Util.createImage(null,null,null,null,null,null,null,false);div.appendChild(img);if(delayDisplay){img.style.display="none";OpenLayers.Event.observe(img,"load",OpenLayers.Function.bind(OpenLayers.Util.onImageLoad,div));OpenLayers.Event.observe(img,"error",OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError,div));}
59386 OpenLayers.Util.modifyAlphaImageDiv(div,id,px,sz,imgURL,position,border,sizing,opacity);return div;};OpenLayers.Util.upperCaseObject=function(object){var uObject={};for(var key in object){uObject[key.toUpperCase()]=object[key];}
59387 return uObject;};OpenLayers.Util.applyDefaults=function(to,from){to=to||{};var fromIsEvt=typeof window.Event=="function"&&from instanceof window.Event;for(var key in from){if(to[key]===undefined||(!fromIsEvt&&from.hasOwnProperty&&from.hasOwnProperty(key)&&!to.hasOwnProperty(key))){to[key]=from[key];}}
59388 if(!fromIsEvt&&from&&from.hasOwnProperty&&from.hasOwnProperty('toString')&&!to.hasOwnProperty('toString')){to.toString=from.toString;}
59389 return to;};OpenLayers.Util.getParameterString=function(params){var paramsArray=[];for(var key in params){var value=params[key];if((value!=null)&&(typeof value!='function')){var encodedValue;if(typeof value=='object'&&value.constructor==Array){var encodedItemArray=[];var item;for(var itemIndex=0,len=value.length;itemIndex<len;itemIndex++){item=value[itemIndex];encodedItemArray.push(encodeURIComponent((item===null||item===undefined)?"":item));}
59390 encodedValue=encodedItemArray.join(",");}
59391 else{encodedValue=encodeURIComponent(value);}
59392 paramsArray.push(encodeURIComponent(key)+"="+encodedValue);}}
59393 return paramsArray.join("&");};OpenLayers.Util.urlAppend=function(url,paramStr){var newUrl=url;if(paramStr){var parts=(url+" ").split(/[?&]/);newUrl+=(parts.pop()===" "?paramStr:parts.length?"&"+paramStr:"?"+paramStr);}
59394 return newUrl;};OpenLayers.ImgPath='';OpenLayers.Util.getImagesLocation=function(){return OpenLayers.ImgPath||(OpenLayers._getScriptLocation()+"img/");};OpenLayers.Util.Try=function(){var returnValue=null;for(var i=0,len=arguments.length;i<len;i++){var lambda=arguments[i];try{returnValue=lambda();break;}catch(e){}}
59395 return returnValue;};OpenLayers.Util.getNodes=function(p,tagName){var nodes=OpenLayers.Util.Try(function(){return OpenLayers.Util._getNodes(p.documentElement.childNodes,tagName);},function(){return OpenLayers.Util._getNodes(p.childNodes,tagName);});return nodes;};OpenLayers.Util._getNodes=function(nodes,tagName){var retArray=[];for(var i=0,len=nodes.length;i<len;i++){if(nodes[i].nodeName==tagName){retArray.push(nodes[i]);}}
59396 return retArray;};OpenLayers.Util.getTagText=function(parent,item,index){var result=OpenLayers.Util.getNodes(parent,item);if(result&&(result.length>0))
59397 {if(!index){index=0;}
59398 if(result[index].childNodes.length>1){return result.childNodes[1].nodeValue;}
59399 else if(result[index].childNodes.length==1){return result[index].firstChild.nodeValue;}}else{return"";}};OpenLayers.Util.getXmlNodeValue=function(node){var val=null;OpenLayers.Util.Try(function(){val=node.text;if(!val){val=node.textContent;}
59400 if(!val){val=node.firstChild.nodeValue;}},function(){val=node.textContent;});return val;};OpenLayers.Util.mouseLeft=function(evt,div){var target=(evt.relatedTarget)?evt.relatedTarget:evt.toElement;while(target!=div&&target!=null){target=target.parentNode;}
59401 return(target!=div);};OpenLayers.Util.DEFAULT_PRECISION=14;OpenLayers.Util.toFloat=function(number,precision){if(precision==null){precision=OpenLayers.Util.DEFAULT_PRECISION;}
59402 var number;if(precision==0){number=parseFloat(number);}else{number=parseFloat(parseFloat(number).toPrecision(precision));}
59403 return number;};OpenLayers.Util.rad=function(x){return x*Math.PI/180;};OpenLayers.Util.deg=function(x){return x*180/Math.PI;};OpenLayers.Util.VincentyConstants={a:6378137,b:6356752.3142,f:1/298.257223563};OpenLayers.Util.distVincenty=function(p1,p2){var ct=OpenLayers.Util.VincentyConstants;var a=ct.a,b=ct.b,f=ct.f;var L=OpenLayers.Util.rad(p2.lon-p1.lon);var U1=Math.atan((1-f)*Math.tan(OpenLayers.Util.rad(p1.lat)));var U2=Math.atan((1-f)*Math.tan(OpenLayers.Util.rad(p2.lat)));var sinU1=Math.sin(U1),cosU1=Math.cos(U1);var sinU2=Math.sin(U2),cosU2=Math.cos(U2);var lambda=L,lambdaP=2*Math.PI;var iterLimit=20;while(Math.abs(lambda-lambdaP)>1e-12&&--iterLimit>0){var sinLambda=Math.sin(lambda),cosLambda=Math.cos(lambda);var sinSigma=Math.sqrt((cosU2*sinLambda)*(cosU2*sinLambda)+
59404 (cosU1*sinU2-sinU1*cosU2*cosLambda)*(cosU1*sinU2-sinU1*cosU2*cosLambda));if(sinSigma==0){return 0;}
59405 var cosSigma=sinU1*sinU2+cosU1*cosU2*cosLambda;var sigma=Math.atan2(sinSigma,cosSigma);var alpha=Math.asin(cosU1*cosU2*sinLambda/sinSigma);var cosSqAlpha=Math.cos(alpha)*Math.cos(alpha);var cos2SigmaM=cosSigma-2*sinU1*sinU2/cosSqAlpha;var C=f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));lambdaP=lambda;lambda=L+(1-C)*f*Math.sin(alpha)*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));}
59406 if(iterLimit==0){return NaN;}
59407 var uSq=cosSqAlpha*(a*a-b*b)/(b*b);var A=1+uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));var B=uSq/1024*(256+uSq*(-128+uSq*(74-47*uSq)));var deltaSigma=B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
59408 B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));var s=b*A*(sigma-deltaSigma);var d=s.toFixed(3)/1000;return d;};OpenLayers.Util.destinationVincenty=function(lonlat,brng,dist){var u=OpenLayers.Util;var ct=u.VincentyConstants;var a=ct.a,b=ct.b,f=ct.f;var lon1=lonlat.lon;var lat1=lonlat.lat;var s=dist;var alpha1=u.rad(brng);var sinAlpha1=Math.sin(alpha1);var cosAlpha1=Math.cos(alpha1);var tanU1=(1-f)*Math.tan(u.rad(lat1));var cosU1=1/Math.sqrt((1+tanU1*tanU1)),sinU1=tanU1*cosU1;var sigma1=Math.atan2(tanU1,cosAlpha1);var sinAlpha=cosU1*sinAlpha1;var cosSqAlpha=1-sinAlpha*sinAlpha;var uSq=cosSqAlpha*(a*a-b*b)/(b*b);var A=1+uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));var B=uSq/1024*(256+uSq*(-128+uSq*(74-47*uSq)));var sigma=s/(b*A),sigmaP=2*Math.PI;while(Math.abs(sigma-sigmaP)>1e-12){var cos2SigmaM=Math.cos(2*sigma1+sigma);var sinSigma=Math.sin(sigma);var cosSigma=Math.cos(sigma);var deltaSigma=B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
59409 B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));sigmaP=sigma;sigma=s/(b*A)+deltaSigma;}
59410 var tmp=sinU1*sinSigma-cosU1*cosSigma*cosAlpha1;var lat2=Math.atan2(sinU1*cosSigma+cosU1*sinSigma*cosAlpha1,(1-f)*Math.sqrt(sinAlpha*sinAlpha+tmp*tmp));var lambda=Math.atan2(sinSigma*sinAlpha1,cosU1*cosSigma-sinU1*sinSigma*cosAlpha1);var C=f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));var L=lambda-(1-C)*f*sinAlpha*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));var revAz=Math.atan2(sinAlpha,-tmp);return new OpenLayers.LonLat(lon1+u.deg(L),u.deg(lat2));};OpenLayers.Util.getParameters=function(url){url=url||window.location.href;var paramsString="";if(OpenLayers.String.contains(url,'?')){var start=url.indexOf('?')+1;var end=OpenLayers.String.contains(url,"#")?url.indexOf('#'):url.length;paramsString=url.substring(start,end);}
59411 var parameters={};var pairs=paramsString.split(/[&;]/);for(var i=0,len=pairs.length;i<len;++i){var keyValue=pairs[i].split('=');if(keyValue[0]){var key=decodeURIComponent(keyValue[0]);var value=keyValue[1]||'';value=decodeURIComponent(value.replace(/\+/g," ")).split(",");if(value.length==1){value=value[0];}
59412 parameters[key]=value;}}
59413 return parameters;};OpenLayers.Util.getArgs=function(url){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Util.getParameters'}));return OpenLayers.Util.getParameters(url);};OpenLayers.Util.lastSeqID=0;OpenLayers.Util.createUniqueID=function(prefix){if(prefix==null){prefix="id_";}
59414 OpenLayers.Util.lastSeqID+=1;return prefix+OpenLayers.Util.lastSeqID;};OpenLayers.INCHES_PER_UNIT={'inches':1.0,'ft':12.0,'mi':63360.0,'m':39.3701,'km':39370.1,'dd':4374754,'yd':36};OpenLayers.INCHES_PER_UNIT["in"]=OpenLayers.INCHES_PER_UNIT.inches;OpenLayers.INCHES_PER_UNIT["degrees"]=OpenLayers.INCHES_PER_UNIT.dd;OpenLayers.INCHES_PER_UNIT["nmi"]=1852*OpenLayers.INCHES_PER_UNIT.m;OpenLayers.METERS_PER_INCH=0.02540005080010160020;OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT,{"Inch":OpenLayers.INCHES_PER_UNIT.inches,"Meter":1.0/OpenLayers.METERS_PER_INCH,"Foot":0.30480060960121920243/OpenLayers.METERS_PER_INCH,"IFoot":0.30480000000000000000/OpenLayers.METERS_PER_INCH,"ClarkeFoot":0.3047972651151/OpenLayers.METERS_PER_INCH,"SearsFoot":0.30479947153867624624/OpenLayers.METERS_PER_INCH,"GoldCoastFoot":0.30479971018150881758/OpenLayers.METERS_PER_INCH,"IInch":0.02540000000000000000/OpenLayers.METERS_PER_INCH,"MicroInch":0.00002540000000000000/OpenLayers.METERS_PER_INCH,"Mil":0.00000002540000000000/OpenLayers.METERS_PER_INCH,"Centimeter":0.01000000000000000000/OpenLayers.METERS_PER_INCH,"Kilometer":1000.00000000000000000000/OpenLayers.METERS_PER_INCH,"Yard":0.91440182880365760731/OpenLayers.METERS_PER_INCH,"SearsYard":0.914398414616029/OpenLayers.METERS_PER_INCH,"IndianYard":0.91439853074444079983/OpenLayers.METERS_PER_INCH,"IndianYd37":0.91439523/OpenLayers.METERS_PER_INCH,"IndianYd62":0.9143988/OpenLayers.METERS_PER_INCH,"IndianYd75":0.9143985/OpenLayers.METERS_PER_INCH,"IndianFoot":0.30479951/OpenLayers.METERS_PER_INCH,"IndianFt37":0.30479841/OpenLayers.METERS_PER_INCH,"IndianFt62":0.3047996/OpenLayers.METERS_PER_INCH,"IndianFt75":0.3047995/OpenLayers.METERS_PER_INCH,"Mile":1609.34721869443738887477/OpenLayers.METERS_PER_INCH,"IYard":0.91440000000000000000/OpenLayers.METERS_PER_INCH,"IMile":1609.34400000000000000000/OpenLayers.METERS_PER_INCH,"NautM":1852.00000000000000000000/OpenLayers.METERS_PER_INCH,"Lat-66":110943.316488932731/OpenLayers.METERS_PER_INCH,"Lat-83":110946.25736872234125/OpenLayers.METERS_PER_INCH,"Decimeter":0.10000000000000000000/OpenLayers.METERS_PER_INCH,"Millimeter":0.00100000000000000000/OpenLayers.METERS_PER_INCH,"Dekameter":10.00000000000000000000/OpenLayers.METERS_PER_INCH,"Decameter":10.00000000000000000000/OpenLayers.METERS_PER_INCH,"Hectometer":100.00000000000000000000/OpenLayers.METERS_PER_INCH,"GermanMeter":1.0000135965/OpenLayers.METERS_PER_INCH,"CaGrid":0.999738/OpenLayers.METERS_PER_INCH,"ClarkeChain":20.1166194976/OpenLayers.METERS_PER_INCH,"GunterChain":20.11684023368047/OpenLayers.METERS_PER_INCH,"BenoitChain":20.116782494375872/OpenLayers.METERS_PER_INCH,"SearsChain":20.11676512155/OpenLayers.METERS_PER_INCH,"ClarkeLink":0.201166194976/OpenLayers.METERS_PER_INCH,"GunterLink":0.2011684023368047/OpenLayers.METERS_PER_INCH,"BenoitLink":0.20116782494375872/OpenLayers.METERS_PER_INCH,"SearsLink":0.2011676512155/OpenLayers.METERS_PER_INCH,"Rod":5.02921005842012/OpenLayers.METERS_PER_INCH,"IntnlChain":20.1168/OpenLayers.METERS_PER_INCH,"IntnlLink":0.201168/OpenLayers.METERS_PER_INCH,"Perch":5.02921005842012/OpenLayers.METERS_PER_INCH,"Pole":5.02921005842012/OpenLayers.METERS_PER_INCH,"Furlong":201.1684023368046/OpenLayers.METERS_PER_INCH,"Rood":3.778266898/OpenLayers.METERS_PER_INCH,"CapeFoot":0.3047972615/OpenLayers.METERS_PER_INCH,"Brealey":375.00000000000000000000/OpenLayers.METERS_PER_INCH,"ModAmFt":0.304812252984505969011938/OpenLayers.METERS_PER_INCH,"Fathom":1.8288/OpenLayers.METERS_PER_INCH,"NautM-UK":1853.184/OpenLayers.METERS_PER_INCH,"50kilometers":50000.0/OpenLayers.METERS_PER_INCH,"150kilometers":150000.0/OpenLayers.METERS_PER_INCH});OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT,{"mm":OpenLayers.INCHES_PER_UNIT["Meter"]/1000.0,"cm":OpenLayers.INCHES_PER_UNIT["Meter"]/100.0,"dm":OpenLayers.INCHES_PER_UNIT["Meter"]*100.0,"km":OpenLayers.INCHES_PER_UNIT["Meter"]*1000.0,"kmi":OpenLayers.INCHES_PER_UNIT["nmi"],"fath":OpenLayers.INCHES_PER_UNIT["Fathom"],"ch":OpenLayers.INCHES_PER_UNIT["IntnlChain"],"link":OpenLayers.INCHES_PER_UNIT["IntnlLink"],"us-in":OpenLayers.INCHES_PER_UNIT["inches"],"us-ft":OpenLayers.INCHES_PER_UNIT["Foot"],"us-yd":OpenLayers.INCHES_PER_UNIT["Yard"],"us-ch":OpenLayers.INCHES_PER_UNIT["GunterChain"],"us-mi":OpenLayers.INCHES_PER_UNIT["Mile"],"ind-yd":OpenLayers.INCHES_PER_UNIT["IndianYd37"],"ind-ft":OpenLayers.INCHES_PER_UNIT["IndianFt37"],"ind-ch":20.11669506/OpenLayers.METERS_PER_INCH});OpenLayers.DOTS_PER_INCH=72;OpenLayers.Util.normalizeScale=function(scale){var normScale=(scale>1.0)?(1.0/scale):scale;return normScale;};OpenLayers.Util.getResolutionFromScale=function(scale,units){var resolution;if(scale){if(units==null){units="degrees";}
59415 var normScale=OpenLayers.Util.normalizeScale(scale);resolution=1/(normScale*OpenLayers.INCHES_PER_UNIT[units]*OpenLayers.DOTS_PER_INCH);}
59416 return resolution;};OpenLayers.Util.getScaleFromResolution=function(resolution,units){if(units==null){units="degrees";}
59417 var scale=resolution*OpenLayers.INCHES_PER_UNIT[units]*OpenLayers.DOTS_PER_INCH;return scale;};OpenLayers.Util.safeStopPropagation=function(evt){OpenLayers.Event.stop(evt,true);};OpenLayers.Util.pagePosition=function(forElement){var valueT=0,valueL=0;var element=forElement;var child=forElement;while(element){if(element==document.body){if(OpenLayers.Element.getStyle(child,'position')=='absolute'){break;}}
59418 valueT+=element.offsetTop||0;valueL+=element.offsetLeft||0;child=element;try{element=element.offsetParent;}catch(e){OpenLayers.Console.error(OpenLayers.i18n("pagePositionFailed",{'elemId':element.id}));break;}}
59419 element=forElement;while(element){valueT-=element.scrollTop||0;valueL-=element.scrollLeft||0;element=element.parentNode;}
59420 return[valueL,valueT];};OpenLayers.Util.isEquivalentUrl=function(url1,url2,options){options=options||{};OpenLayers.Util.applyDefaults(options,{ignoreCase:true,ignorePort80:true,ignoreHash:true});var urlObj1=OpenLayers.Util.createUrlObject(url1,options);var urlObj2=OpenLayers.Util.createUrlObject(url2,options);for(var key in urlObj1){if(key!=="args"){if(urlObj1[key]!=urlObj2[key]){return false;}}}
59421 for(var key in urlObj1.args){if(urlObj1.args[key]!=urlObj2.args[key]){return false;}
59422 delete urlObj2.args[key];}
59423 for(var key in urlObj2.args){return false;}
59424 return true;};OpenLayers.Util.createUrlObject=function(url,options){options=options||{};if(!(/^\w+:\/\//).test(url)){var loc=window.location;var port=loc.port?":"+loc.port:"";var fullUrl=loc.protocol+"//"+loc.host.split(":").shift()+port;if(url.indexOf("/")===0){url=fullUrl+url;}else{var parts=loc.pathname.split("/");parts.pop();url=fullUrl+parts.join("/")+"/"+url;}}
59425 if(options.ignoreCase){url=url.toLowerCase();}
59426 var a=document.createElement('a');a.href=url;var urlObject={};urlObject.host=a.host.split(":").shift();urlObject.protocol=a.protocol;if(options.ignorePort80){urlObject.port=(a.port=="80"||a.port=="0")?"":a.port;}else{urlObject.port=(a.port==""||a.port=="0")?"80":a.port;}
59427 urlObject.hash=(options.ignoreHash||a.hash==="#")?"":a.hash;var queryString=a.search;if(!queryString){var qMark=url.indexOf("?");queryString=(qMark!=-1)?url.substr(qMark):"";}
59428 urlObject.args=OpenLayers.Util.getParameters(queryString);urlObject.pathname=(a.pathname.charAt(0)=="/")?a.pathname:"/"+a.pathname;return urlObject;};OpenLayers.Util.removeTail=function(url){var head=null;var qMark=url.indexOf("?");var hashMark=url.indexOf("#");if(qMark==-1){head=(hashMark!=-1)?url.substr(0,hashMark):url;}else{head=(hashMark!=-1)?url.substr(0,Math.min(qMark,hashMark)):url.substr(0,qMark);}
59429 return head;};OpenLayers.Util.getBrowserName=function(){var browserName="";var ua=navigator.userAgent.toLowerCase();if(ua.indexOf("opera")!=-1){browserName="opera";}else if(ua.indexOf("msie")!=-1){browserName="msie";}else if(ua.indexOf("safari")!=-1){browserName="safari";}else if(ua.indexOf("mozilla")!=-1){if(ua.indexOf("firefox")!=-1){browserName="firefox";}else{browserName="mozilla";}}
59430 return browserName;};OpenLayers.Util.getRenderedDimensions=function(contentHTML,size,options){var w,h;var container=document.createElement("div");container.style.visibility="hidden";var containerElement=(options&&options.containerElement)?options.containerElement:document.body;if(size){if(size.w){w=size.w;container.style.width=w+"px";}else if(size.h){h=size.h;container.style.height=h+"px";}}
59431 if(options&&options.displayClass){container.className=options.displayClass;}
59432 var content=document.createElement("div");content.innerHTML=contentHTML;content.style.overflow="visible";if(content.childNodes){for(var i=0,l=content.childNodes.length;i<l;i++){if(!content.childNodes[i].style)continue;content.childNodes[i].style.overflow="visible";}}
59433 container.appendChild(content);containerElement.appendChild(container);var parentHasPositionAbsolute=false;var parent=container.parentNode;while(parent&&parent.tagName.toLowerCase()!="body"){var parentPosition=OpenLayers.Element.getStyle(parent,"position");if(parentPosition=="absolute"){parentHasPositionAbsolute=true;break;}else if(parentPosition&&parentPosition!="static"){break;}
59434 parent=parent.parentNode;}
59435 if(!parentHasPositionAbsolute){container.style.position="absolute";}
59436 if(!w){w=parseInt(content.scrollWidth);container.style.width=w+"px";}
59437 if(!h){h=parseInt(content.scrollHeight);}
59438 container.removeChild(content);containerElement.removeChild(container);return new OpenLayers.Size(w,h);};OpenLayers.Util.getScrollbarWidth=function(){var scrollbarWidth=OpenLayers.Util._scrollbarWidth;if(scrollbarWidth==null){var scr=null;var inn=null;var wNoScroll=0;var wScroll=0;scr=document.createElement('div');scr.style.position='absolute';scr.style.top='-1000px';scr.style.left='-1000px';scr.style.width='100px';scr.style.height='50px';scr.style.overflow='hidden';inn=document.createElement('div');inn.style.width='100%';inn.style.height='200px';scr.appendChild(inn);document.body.appendChild(scr);wNoScroll=inn.offsetWidth;scr.style.overflow='scroll';wScroll=inn.offsetWidth;document.body.removeChild(document.body.lastChild);OpenLayers.Util._scrollbarWidth=(wNoScroll-wScroll);scrollbarWidth=OpenLayers.Util._scrollbarWidth;}
59439 return scrollbarWidth;};OpenLayers.Util.getFormattedLonLat=function(coordinate,axis,dmsOption){if(!dmsOption){dmsOption='dms';}
59440 var abscoordinate=Math.abs(coordinate)
59441 var coordinatedegrees=Math.floor(abscoordinate);var coordinateminutes=(abscoordinate-coordinatedegrees)/(1/60);var tempcoordinateminutes=coordinateminutes;coordinateminutes=Math.floor(coordinateminutes);var coordinateseconds=(tempcoordinateminutes-coordinateminutes)/(1/60);coordinateseconds=Math.round(coordinateseconds*10);coordinateseconds/=10;if(coordinatedegrees<10){coordinatedegrees="0"+coordinatedegrees;}
59442 var str=coordinatedegrees+"\u00B0";if(dmsOption.indexOf('dm')>=0){if(coordinateminutes<10){coordinateminutes="0"+coordinateminutes;}
59443 str+=coordinateminutes+"'";if(dmsOption.indexOf('dms')>=0){if(coordinateseconds<10){coordinateseconds="0"+coordinateseconds;}
59444 str+=coordinateseconds+'"';}}
59445 if(axis=="lon"){str+=coordinate<0?OpenLayers.i18n("W"):OpenLayers.i18n("E");}else{str+=coordinate<0?OpenLayers.i18n("S"):OpenLayers.i18n("N");}
59446 return str;};OpenLayers.Rico=new Object();OpenLayers.Rico.Corner={round:function(e,options){e=OpenLayers.Util.getElement(e);this._setOptions(options);var color=this.options.color;if(this.options.color=="fromElement"){color=this._background(e);}
59447 var bgColor=this.options.bgColor;if(this.options.bgColor=="fromParent"){bgColor=this._background(e.offsetParent);}
59448 this._roundCornersImpl(e,color,bgColor);},changeColor:function(theDiv,newColor){theDiv.style.backgroundColor=newColor;var spanElements=theDiv.parentNode.getElementsByTagName("span");for(var currIdx=0;currIdx<spanElements.length;currIdx++){spanElements[currIdx].style.backgroundColor=newColor;}},changeOpacity:function(theDiv,newOpacity){var mozillaOpacity=newOpacity;var ieOpacity='alpha(opacity='+newOpacity*100+')';theDiv.style.opacity=mozillaOpacity;theDiv.style.filter=ieOpacity;var spanElements=theDiv.parentNode.getElementsByTagName("span");for(var currIdx=0;currIdx<spanElements.length;currIdx++){spanElements[currIdx].style.opacity=mozillaOpacity;spanElements[currIdx].style.filter=ieOpacity;}},reRound:function(theDiv,options){var topRico=theDiv.parentNode.childNodes[0];var bottomRico=theDiv.parentNode.childNodes[2];theDiv.parentNode.removeChild(topRico);theDiv.parentNode.removeChild(bottomRico);this.round(theDiv.parentNode,options);},_roundCornersImpl:function(e,color,bgColor){if(this.options.border){this._renderBorder(e,bgColor);}
59449 if(this._isTopRounded()){this._roundTopCorners(e,color,bgColor);}
59450 if(this._isBottomRounded()){this._roundBottomCorners(e,color,bgColor);}},_renderBorder:function(el,bgColor){var borderValue="1px solid "+this._borderColor(bgColor);var borderL="border-left: "+borderValue;var borderR="border-right: "+borderValue;var style="style='"+borderL+";"+borderR+"'";el.innerHTML="<div "+style+">"+el.innerHTML+"</div>";},_roundTopCorners:function(el,color,bgColor){var corner=this._createCorner(bgColor);for(var i=0;i<this.options.numSlices;i++){corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));}
59451 el.style.paddingTop=0;el.insertBefore(corner,el.firstChild);},_roundBottomCorners:function(el,color,bgColor){var corner=this._createCorner(bgColor);for(var i=(this.options.numSlices-1);i>=0;i--){corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));}
59452 el.style.paddingBottom=0;el.appendChild(corner);},_createCorner:function(bgColor){var corner=document.createElement("div");corner.style.backgroundColor=(this._isTransparent()?"transparent":bgColor);return corner;},_createCornerSlice:function(color,bgColor,n,position){var slice=document.createElement("span");var inStyle=slice.style;inStyle.backgroundColor=color;inStyle.display="block";inStyle.height="1px";inStyle.overflow="hidden";inStyle.fontSize="1px";var borderColor=this._borderColor(color,bgColor);if(this.options.border&&n==0){inStyle.borderTopStyle="solid";inStyle.borderTopWidth="1px";inStyle.borderLeftWidth="0px";inStyle.borderRightWidth="0px";inStyle.borderBottomWidth="0px";inStyle.height="0px";inStyle.borderColor=borderColor;}
59453 else if(borderColor){inStyle.borderColor=borderColor;inStyle.borderStyle="solid";inStyle.borderWidth="0px 1px";}
59454 if(!this.options.compact&&(n==(this.options.numSlices-1))){inStyle.height="2px";}
59455 this._setMargin(slice,n,position);this._setBorder(slice,n,position);return slice;},_setOptions:function(options){this.options={corners:"all",color:"fromElement",bgColor:"fromParent",blend:true,border:false,compact:false};OpenLayers.Util.extend(this.options,options||{});this.options.numSlices=this.options.compact?2:4;if(this._isTransparent()){this.options.blend=false;}},_whichSideTop:function(){if(this._hasString(this.options.corners,"all","top")){return"";}
59456 if(this.options.corners.indexOf("tl")>=0&&this.options.corners.indexOf("tr")>=0){return"";}
59457 if(this.options.corners.indexOf("tl")>=0){return"left";}else if(this.options.corners.indexOf("tr")>=0){return"right";}
59458 return"";},_whichSideBottom:function(){if(this._hasString(this.options.corners,"all","bottom")){return"";}
59459 if(this.options.corners.indexOf("bl")>=0&&this.options.corners.indexOf("br")>=0){return"";}
59460 if(this.options.corners.indexOf("bl")>=0){return"left";}else if(this.options.corners.indexOf("br")>=0){return"right";}
59461 return"";},_borderColor:function(color,bgColor){if(color=="transparent"){return bgColor;}else if(this.options.border){return this.options.border;}else if(this.options.blend){return this._blend(bgColor,color);}else{return"";}},_setMargin:function(el,n,corners){var marginSize=this._marginSize(n);var whichSide=corners=="top"?this._whichSideTop():this._whichSideBottom();if(whichSide=="left"){el.style.marginLeft=marginSize+"px";el.style.marginRight="0px";}
59462 else if(whichSide=="right"){el.style.marginRight=marginSize+"px";el.style.marginLeft="0px";}
59463 else{el.style.marginLeft=marginSize+"px";el.style.marginRight=marginSize+"px";}},_setBorder:function(el,n,corners){var borderSize=this._borderSize(n);var whichSide=corners=="top"?this._whichSideTop():this._whichSideBottom();if(whichSide=="left"){el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth="0px";}
59464 else if(whichSide=="right"){el.style.borderRightWidth=borderSize+"px";el.style.borderLeftWidth="0px";}
59465 else{el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth=borderSize+"px";}
59466 if(this.options.border!=false){el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth=borderSize+"px";}},_marginSize:function(n){if(this._isTransparent()){return 0;}
59467 var marginSizes=[5,3,2,1];var blendedMarginSizes=[3,2,1,0];var compactMarginSizes=[2,1];var smBlendedMarginSizes=[1,0];if(this.options.compact&&this.options.blend){return smBlendedMarginSizes[n];}else if(this.options.compact){return compactMarginSizes[n];}else if(this.options.blend){return blendedMarginSizes[n];}else{return marginSizes[n];}},_borderSize:function(n){var transparentBorderSizes=[5,3,2,1];var blendedBorderSizes=[2,1,1,1];var compactBorderSizes=[1,0];var actualBorderSizes=[0,2,0,0];if(this.options.compact&&(this.options.blend||this._isTransparent())){return 1;}else if(this.options.compact){return compactBorderSizes[n];}else if(this.options.blend){return blendedBorderSizes[n];}else if(this.options.border){return actualBorderSizes[n];}else if(this._isTransparent()){return transparentBorderSizes[n];}
59468 return 0;},_hasString:function(str){for(var i=1;i<arguments.length;i++)if(str.indexOf(arguments[i])>=0){return true;}return false;},_blend:function(c1,c2){var cc1=OpenLayers.Rico.Color.createFromHex(c1);cc1.blend(OpenLayers.Rico.Color.createFromHex(c2));return cc1;},_background:function(el){try{return OpenLayers.Rico.Color.createColorFromBackground(el).asHex();}catch(err){return"#ffffff";}},_isTransparent:function(){return this.options.color=="transparent";},_isTopRounded:function(){return this._hasString(this.options.corners,"all","top","tl","tr");},_isBottomRounded:function(){return this._hasString(this.options.corners,"all","bottom","bl","br");},_hasSingleTextChild:function(el){return el.childNodes.length==1&&el.childNodes[0].nodeType==3;}};(function(){if(window.google&&google.gears){return;}
59469 var factory=null;if(typeof GearsFactory!='undefined'){factory=new GearsFactory();}else{try{factory=new ActiveXObject('Gears.Factory');if(factory.getBuildInfo().indexOf('ie_mobile')!=-1){factory.privateSetGlobalObject(this);}}catch(e){if((typeof navigator.mimeTypes!='undefined')&&navigator.mimeTypes["application/x-googlegears"]){factory=document.createElement("object");factory.style.display="none";factory.width=0;factory.height=0;factory.type="application/x-googlegears";document.documentElement.appendChild(factory);}}}
59470 if(!factory){return;}
59471 if(!window.google){google={};}
59472 if(!google.gears){google.gears={factory:factory};}})();OpenLayers.Element={visible:function(element){return OpenLayers.Util.getElement(element).style.display!='none';},toggle:function(){for(var i=0,len=arguments.length;i<len;i++){var element=OpenLayers.Util.getElement(arguments[i]);var display=OpenLayers.Element.visible(element)?'hide':'show';OpenLayers.Element[display](element);}},hide:function(){for(var i=0,len=arguments.length;i<len;i++){var element=OpenLayers.Util.getElement(arguments[i]);if(element){element.style.display='none';}}},show:function(){for(var i=0,len=arguments.length;i<len;i++){var element=OpenLayers.Util.getElement(arguments[i]);if(element){element.style.display='';}}},remove:function(element){element=OpenLayers.Util.getElement(element);element.parentNode.removeChild(element);},getHeight:function(element){element=OpenLayers.Util.getElement(element);return element.offsetHeight;},getDimensions:function(element){element=OpenLayers.Util.getElement(element);if(OpenLayers.Element.getStyle(element,'display')!='none'){return{width:element.offsetWidth,height:element.offsetHeight};}
59473 var els=element.style;var originalVisibility=els.visibility;var originalPosition=els.position;var originalDisplay=els.display;els.visibility='hidden';els.position='absolute';els.display='';var originalWidth=element.clientWidth;var originalHeight=element.clientHeight;els.display=originalDisplay;els.position=originalPosition;els.visibility=originalVisibility;return{width:originalWidth,height:originalHeight};},hasClass:function(element,name){var names=element.className;return(!!names&&new RegExp("(^|\\s)"+name+"(\\s|$)").test(names));},addClass:function(element,name){if(!OpenLayers.Element.hasClass(element,name)){element.className+=(element.className?" ":"")+name;}
59474 return element;},removeClass:function(element,name){var names=element.className;if(names){element.className=OpenLayers.String.trim(names.replace(new RegExp("(^|\\s+)"+name+"(\\s+|$)")," "));}
59475 return element;},toggleClass:function(element,name){if(OpenLayers.Element.hasClass(element,name)){OpenLayers.Element.removeClass(element,name);}else{OpenLayers.Element.addClass(element,name);}
59476 return element;},getStyle:function(element,style){element=OpenLayers.Util.getElement(element);var value=null;if(element&&element.style){value=element.style[OpenLayers.String.camelize(style)];if(!value){if(document.defaultView&&document.defaultView.getComputedStyle){var css=document.defaultView.getComputedStyle(element,null);value=css?css.getPropertyValue(style):null;}else if(element.currentStyle){value=element.currentStyle[OpenLayers.String.camelize(style)];}}
59477 var positions=['left','top','right','bottom'];if(window.opera&&(OpenLayers.Util.indexOf(positions,style)!=-1)&&(OpenLayers.Element.getStyle(element,'position')=='static')){value='auto';}}
59478 return value=='auto'?null:value;}};OpenLayers.Size=OpenLayers.Class({w:0.0,h:0.0,initialize:function(w,h){this.w=parseFloat(w);this.h=parseFloat(h);},toString:function(){return("w="+this.w+",h="+this.h);},clone:function(){return new OpenLayers.Size(this.w,this.h);},equals:function(sz){var equals=false;if(sz!=null){equals=((this.w==sz.w&&this.h==sz.h)||(isNaN(this.w)&&isNaN(this.h)&&isNaN(sz.w)&&isNaN(sz.h)));}
59479 return equals;},CLASS_NAME:"OpenLayers.Size"});OpenLayers.Console={log:function(){},debug:function(){},info:function(){},warn:function(){},error:function(){},userError:function(error){alert(error);},assert:function(){},dir:function(){},dirxml:function(){},trace:function(){},group:function(){},groupEnd:function(){},time:function(){},timeEnd:function(){},profile:function(){},profileEnd:function(){},count:function(){},CLASS_NAME:"OpenLayers.Console"};(function(){var scripts=document.getElementsByTagName("script");for(var i=0,len=scripts.length;i<len;++i){if(scripts[i].src.indexOf("firebug.js")!=-1){if(console){OpenLayers.Util.extend(OpenLayers.Console,console);break;}}}})();OpenLayers.Icon=OpenLayers.Class({url:null,size:null,offset:null,calculateOffset:null,imageDiv:null,px:null,initialize:function(url,size,offset,calculateOffset){this.url=url;this.size=(size)?size:new OpenLayers.Size(20,20);this.offset=offset?offset:new OpenLayers.Pixel(-(this.size.w/2),-(this.size.h/2));this.calculateOffset=calculateOffset;var id=OpenLayers.Util.createUniqueID("OL_Icon_");this.imageDiv=OpenLayers.Util.createAlphaImageDiv(id);},destroy:function(){this.erase();OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);this.imageDiv.innerHTML="";this.imageDiv=null;},clone:function(){return new OpenLayers.Icon(this.url,this.size,this.offset,this.calculateOffset);},setSize:function(size){if(size!=null){this.size=size;}
59480 this.draw();},setUrl:function(url){if(url!=null){this.url=url;}
59481 this.draw();},draw:function(px){OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,null,this.size,this.url,"absolute");this.moveTo(px);return this.imageDiv;},erase:function(){if(this.imageDiv!=null&&this.imageDiv.parentNode!=null){OpenLayers.Element.remove(this.imageDiv);}},setOpacity:function(opacity){OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,null,null,null,null,null,null,opacity);},moveTo:function(px){if(px!=null){this.px=px;}
59482 if(this.imageDiv!=null){if(this.px==null){this.display(false);}else{if(this.calculateOffset){this.offset=this.calculateOffset(this.size);}
59483 var offsetPx=this.px.offset(this.offset);OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,offsetPx);}}},display:function(display){this.imageDiv.style.display=(display)?"":"none";},isDrawn:function(){var isDrawn=(this.imageDiv&&this.imageDiv.parentNode&&(this.imageDiv.parentNode.nodeType!=11));return isDrawn;},CLASS_NAME:"OpenLayers.Icon"});OpenLayers.Popup=OpenLayers.Class({events:null,id:"",lonlat:null,div:null,contentSize:null,size:null,contentHTML:null,backgroundColor:"",opacity:"",border:"",contentDiv:null,groupDiv:null,closeDiv:null,autoSize:false,minSize:null,maxSize:null,displayClass:"olPopup",contentDisplayClass:"olPopupContent",padding:0,disableFirefoxOverflowHack:false,fixPadding:function(){if(typeof this.padding=="number"){this.padding=new OpenLayers.Bounds(this.padding,this.padding,this.padding,this.padding);}},panMapIfOutOfView:false,keepInMap:false,closeOnMove:false,map:null,initialize:function(id,lonlat,contentSize,contentHTML,closeBox,closeBoxCallback){if(id==null){id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");}
59484 this.id=id;this.lonlat=lonlat;this.contentSize=(contentSize!=null)?contentSize:new OpenLayers.Size(OpenLayers.Popup.WIDTH,OpenLayers.Popup.HEIGHT);if(contentHTML!=null){this.contentHTML=contentHTML;}
59485 this.backgroundColor=OpenLayers.Popup.COLOR;this.opacity=OpenLayers.Popup.OPACITY;this.border=OpenLayers.Popup.BORDER;this.div=OpenLayers.Util.createDiv(this.id,null,null,null,null,null,"hidden");this.div.className=this.displayClass;var groupDivId=this.id+"_GroupDiv";this.groupDiv=OpenLayers.Util.createDiv(groupDivId,null,null,null,"relative",null,"hidden");var id=this.div.id+"_contentDiv";this.contentDiv=OpenLayers.Util.createDiv(id,null,this.contentSize.clone(),null,"relative");this.contentDiv.className=this.contentDisplayClass;this.groupDiv.appendChild(this.contentDiv);this.div.appendChild(this.groupDiv);if(closeBox){this.addCloseBox(closeBoxCallback);}
59486 this.registerEvents();},destroy:function(){this.id=null;this.lonlat=null;this.size=null;this.contentHTML=null;this.backgroundColor=null;this.opacity=null;this.border=null;if(this.closeOnMove&&this.map){this.map.events.unregister("movestart",this,this.hide);}
59487 this.events.destroy();this.events=null;if(this.closeDiv){OpenLayers.Event.stopObservingElement(this.closeDiv);this.groupDiv.removeChild(this.closeDiv);}
59488 this.closeDiv=null;this.div.removeChild(this.groupDiv);this.groupDiv=null;if(this.map!=null){this.map.removePopup(this);}
59489 this.map=null;this.div=null;this.autoSize=null;this.minSize=null;this.maxSize=null;this.padding=null;this.panMapIfOutOfView=null;},draw:function(px){if(px==null){if((this.lonlat!=null)&&(this.map!=null)){px=this.map.getLayerPxFromLonLat(this.lonlat);}}
59490 if(this.closeOnMove){this.map.events.register("movestart",this,this.hide);}
59491 if(!this.disableFirefoxOverflowHack&&OpenLayers.Util.getBrowserName()=='firefox'){this.map.events.register("movestart",this,function(){var style=document.defaultView.getComputedStyle(this.contentDiv,null);var currentOverflow=style.getPropertyValue("overflow");if(currentOverflow!="hidden"){this.contentDiv._oldOverflow=currentOverflow;this.contentDiv.style.overflow="hidden";}});this.map.events.register("moveend",this,function(){var oldOverflow=this.contentDiv._oldOverflow;if(oldOverflow){this.contentDiv.style.overflow=oldOverflow;this.contentDiv._oldOverflow=null;}});}
59492 this.moveTo(px);if(!this.autoSize&&!this.size){this.setSize(this.contentSize);}
59493 this.setBackgroundColor();this.setOpacity();this.setBorder();this.setContentHTML();if(this.panMapIfOutOfView){this.panIntoView();}
59494 return this.div;},updatePosition:function(){if((this.lonlat)&&(this.map)){var px=this.map.getLayerPxFromLonLat(this.lonlat);if(px){this.moveTo(px);}}},moveTo:function(px){if((px!=null)&&(this.div!=null)){this.div.style.left=px.x+"px";this.div.style.top=px.y+"px";}},visible:function(){return OpenLayers.Element.visible(this.div);},toggle:function(){if(this.visible()){this.hide();}else{this.show();}},show:function(){OpenLayers.Element.show(this.div);if(this.panMapIfOutOfView){this.panIntoView();}},hide:function(){OpenLayers.Element.hide(this.div);},setSize:function(contentSize){this.size=contentSize.clone();var contentDivPadding=this.getContentDivPadding();var wPadding=contentDivPadding.left+contentDivPadding.right;var hPadding=contentDivPadding.top+contentDivPadding.bottom;this.fixPadding();wPadding+=this.padding.left+this.padding.right;hPadding+=this.padding.top+this.padding.bottom;if(this.closeDiv){var closeDivWidth=parseInt(this.closeDiv.style.width);wPadding+=closeDivWidth+contentDivPadding.right;}
59495 this.size.w+=wPadding;this.size.h+=hPadding;if(OpenLayers.Util.getBrowserName()=="msie"){this.contentSize.w+=contentDivPadding.left+contentDivPadding.right;this.contentSize.h+=contentDivPadding.bottom+contentDivPadding.top;}
59496 if(this.div!=null){this.div.style.width=this.size.w+"px";this.div.style.height=this.size.h+"px";}
59497 if(this.contentDiv!=null){this.contentDiv.style.width=contentSize.w+"px";this.contentDiv.style.height=contentSize.h+"px";}},updateSize:function(){var preparedHTML="<div class='"+this.contentDisplayClass+"'>"+
59498 this.contentDiv.innerHTML+"</div>";var containerElement=(this.map)?this.map.layerContainerDiv:document.body;var realSize=OpenLayers.Util.getRenderedDimensions(preparedHTML,null,{displayClass:this.displayClass,containerElement:containerElement});var safeSize=this.getSafeContentSize(realSize);var newSize=null;if(safeSize.equals(realSize)){newSize=realSize;}else{var fixedSize=new OpenLayers.Size();fixedSize.w=(safeSize.w<realSize.w)?safeSize.w:null;fixedSize.h=(safeSize.h<realSize.h)?safeSize.h:null;if(fixedSize.w&&fixedSize.h){newSize=safeSize;}else{var clippedSize=OpenLayers.Util.getRenderedDimensions(preparedHTML,fixedSize,{displayClass:this.contentDisplayClass,containerElement:containerElement});var currentOverflow=OpenLayers.Element.getStyle(this.contentDiv,"overflow");if((currentOverflow!="hidden")&&(clippedSize.equals(safeSize))){var scrollBar=OpenLayers.Util.getScrollbarWidth();if(fixedSize.w){clippedSize.h+=scrollBar;}else{clippedSize.w+=scrollBar;}}
59499 newSize=this.getSafeContentSize(clippedSize);}}
59500 this.setSize(newSize);},setBackgroundColor:function(color){if(color!=undefined){this.backgroundColor=color;}
59501 if(this.div!=null){this.div.style.backgroundColor=this.backgroundColor;}},setOpacity:function(opacity){if(opacity!=undefined){this.opacity=opacity;}
59502 if(this.div!=null){this.div.style.opacity=this.opacity;this.div.style.filter='alpha(opacity='+this.opacity*100+')';}},setBorder:function(border){if(border!=undefined){this.border=border;}
59503 if(this.div!=null){this.div.style.border=this.border;}},setContentHTML:function(contentHTML){if(contentHTML!=null){this.contentHTML=contentHTML;}
59504 if((this.contentDiv!=null)&&(this.contentHTML!=null)&&(this.contentHTML!=this.contentDiv.innerHTML)){this.contentDiv.innerHTML=this.contentHTML;if(this.autoSize){this.registerImageListeners();this.updateSize();}}},registerImageListeners:function(){var onImgLoad=function(){this.popup.updateSize();if(this.popup.visible()&&this.popup.panMapIfOutOfView){this.popup.panIntoView();}
59505 OpenLayers.Event.stopObserving(this.img,"load",this.img._onImageLoad);};var images=this.contentDiv.getElementsByTagName("img");for(var i=0,len=images.length;i<len;i++){var img=images[i];if(img.width==0||img.height==0){var context={'popup':this,'img':img};img._onImgLoad=OpenLayers.Function.bind(onImgLoad,context);OpenLayers.Event.observe(img,'load',img._onImgLoad);}}},getSafeContentSize:function(size){var safeContentSize=size.clone();var contentDivPadding=this.getContentDivPadding();var wPadding=contentDivPadding.left+contentDivPadding.right;var hPadding=contentDivPadding.top+contentDivPadding.bottom;this.fixPadding();wPadding+=this.padding.left+this.padding.right;hPadding+=this.padding.top+this.padding.bottom;if(this.closeDiv){var closeDivWidth=parseInt(this.closeDiv.style.width);wPadding+=closeDivWidth+contentDivPadding.right;}
59506 if(this.minSize){safeContentSize.w=Math.max(safeContentSize.w,(this.minSize.w-wPadding));safeContentSize.h=Math.max(safeContentSize.h,(this.minSize.h-hPadding));}
59507 if(this.maxSize){safeContentSize.w=Math.min(safeContentSize.w,(this.maxSize.w-wPadding));safeContentSize.h=Math.min(safeContentSize.h,(this.maxSize.h-hPadding));}
59508 if(this.map&&this.map.size){var extraX=0,extraY=0;if(this.keepInMap&&!this.panMapIfOutOfView){var px=this.map.getPixelFromLonLat(this.lonlat);switch(this.relativePosition){case"tr":extraX=px.x;extraY=this.map.size.h-px.y;break;case"tl":extraX=this.map.size.w-px.x;extraY=this.map.size.h-px.y;break;case"bl":extraX=this.map.size.w-px.x;extraY=px.y;break;case"br":extraX=px.x;extraY=px.y;break;default:extraX=px.x;extraY=this.map.size.h-px.y;break;}}
59509 var maxY=this.map.size.h-
59510 this.map.paddingForPopups.top-
59511 this.map.paddingForPopups.bottom-
59512 hPadding-extraY;var maxX=this.map.size.w-
59513 this.map.paddingForPopups.left-
59514 this.map.paddingForPopups.right-
59515 wPadding-extraX;safeContentSize.w=Math.min(safeContentSize.w,maxX);safeContentSize.h=Math.min(safeContentSize.h,maxY);}
59516 return safeContentSize;},getContentDivPadding:function(){var contentDivPadding=this._contentDivPadding;if(!contentDivPadding){if(this.div.parentNode==null){this.div.style.display="none";document.body.appendChild(this.div);}
59517 contentDivPadding=new OpenLayers.Bounds(OpenLayers.Element.getStyle(this.contentDiv,"padding-left"),OpenLayers.Element.getStyle(this.contentDiv,"padding-bottom"),OpenLayers.Element.getStyle(this.contentDiv,"padding-right"),OpenLayers.Element.getStyle(this.contentDiv,"padding-top"));this._contentDivPadding=contentDivPadding;if(this.div.parentNode==document.body){document.body.removeChild(this.div);this.div.style.display="";}}
59518 return contentDivPadding;},addCloseBox:function(callback){this.closeDiv=OpenLayers.Util.createDiv(this.id+"_close",null,new OpenLayers.Size(17,17));this.closeDiv.className="olPopupCloseBox";var contentDivPadding=this.getContentDivPadding();this.closeDiv.style.right=contentDivPadding.right+"px";this.closeDiv.style.top=contentDivPadding.top+"px";this.groupDiv.appendChild(this.closeDiv);var closePopup=callback||function(e){this.hide();OpenLayers.Event.stop(e);};OpenLayers.Event.observe(this.closeDiv,"click",OpenLayers.Function.bindAsEventListener(closePopup,this));},panIntoView:function(){var mapSize=this.map.getSize();var origTL=this.map.getViewPortPxFromLayerPx(new OpenLayers.Pixel(parseInt(this.div.style.left),parseInt(this.div.style.top)));var newTL=origTL.clone();if(origTL.x<this.map.paddingForPopups.left){newTL.x=this.map.paddingForPopups.left;}else
59519 if((origTL.x+this.size.w)>(mapSize.w-this.map.paddingForPopups.right)){newTL.x=mapSize.w-this.map.paddingForPopups.right-this.size.w;}
59520 if(origTL.y<this.map.paddingForPopups.top){newTL.y=this.map.paddingForPopups.top;}else
59521 if((origTL.y+this.size.h)>(mapSize.h-this.map.paddingForPopups.bottom)){newTL.y=mapSize.h-this.map.paddingForPopups.bottom-this.size.h;}
59522 var dx=origTL.x-newTL.x;var dy=origTL.y-newTL.y;this.map.pan(dx,dy);},registerEvents:function(){this.events=new OpenLayers.Events(this,this.div,null,true);this.events.on({"mousedown":this.onmousedown,"mousemove":this.onmousemove,"mouseup":this.onmouseup,"click":this.onclick,"mouseout":this.onmouseout,"dblclick":this.ondblclick,scope:this});},onmousedown:function(evt){this.mousedown=true;OpenLayers.Event.stop(evt,true);},onmousemove:function(evt){if(this.mousedown){OpenLayers.Event.stop(evt,true);}},onmouseup:function(evt){if(this.mousedown){this.mousedown=false;OpenLayers.Event.stop(evt,true);}},onclick:function(evt){OpenLayers.Event.stop(evt,true);},onmouseout:function(evt){this.mousedown=false;},ondblclick:function(evt){OpenLayers.Event.stop(evt,true);},CLASS_NAME:"OpenLayers.Popup"});OpenLayers.Popup.WIDTH=200;OpenLayers.Popup.HEIGHT=200;OpenLayers.Popup.COLOR="white";OpenLayers.Popup.OPACITY=1;OpenLayers.Popup.BORDER="0px";OpenLayers.Protocol=OpenLayers.Class({format:null,options:null,autoDestroy:true,defaultFilter:null,initialize:function(options){options=options||{};OpenLayers.Util.extend(this,options);this.options=options;},mergeWithDefaultFilter:function(filter){var merged;if(filter&&this.defaultFilter){merged=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND,filters:[this.defaultFilter,filter]});}else{merged=filter||this.defaultFilter||undefined;}
59523 return merged;},destroy:function(){this.options=null;this.format=null;},read:function(options){options=options||{};options.filter=this.mergeWithDefaultFilter(options.filter);},create:function(){},update:function(){},"delete":function(){},commit:function(){},abort:function(response){},createCallback:function(method,response,options){return OpenLayers.Function.bind(function(){method.apply(this,[response,options]);},this);},CLASS_NAME:"OpenLayers.Protocol"});OpenLayers.Protocol.Response=OpenLayers.Class({code:null,requestType:null,last:true,features:null,reqFeatures:null,priv:null,initialize:function(options){OpenLayers.Util.extend(this,options);},success:function(){return this.code>0;},CLASS_NAME:"OpenLayers.Protocol.Response"});OpenLayers.Protocol.Response.SUCCESS=1;OpenLayers.Protocol.Response.FAILURE=0;OpenLayers.Renderer=OpenLayers.Class({container:null,root:null,extent:null,locked:false,size:null,resolution:null,map:null,initialize:function(containerID,options){this.container=OpenLayers.Util.getElement(containerID);},destroy:function(){this.container=null;this.extent=null;this.size=null;this.resolution=null;this.map=null;},supported:function(){return false;},setExtent:function(extent,resolutionChanged){this.extent=extent.clone();if(resolutionChanged){this.resolution=null;}},setSize:function(size){this.size=size.clone();this.resolution=null;},getResolution:function(){this.resolution=this.resolution||this.map.getResolution();return this.resolution;},drawFeature:function(feature,style){if(style==null){style=feature.style;}
59524 if(feature.geometry){var bounds=feature.geometry.getBounds();if(bounds){if(!bounds.intersectsBounds(this.extent)){style={display:"none"};}
59525 var rendered=this.drawGeometry(feature.geometry,style,feature.id);if(style.display!="none"&&style.label&&rendered!==false){var location=feature.geometry.getCentroid();if(style.labelXOffset||style.labelYOffset){xOffset=isNaN(style.labelXOffset)?0:style.labelXOffset;yOffset=isNaN(style.labelYOffset)?0:style.labelYOffset;var res=this.getResolution();location.move(xOffset*res,yOffset*res);}
59526 this.drawText(feature.id,style,location);}else{this.removeText(feature.id);}
59527 return rendered;}}},drawGeometry:function(geometry,style,featureId){},drawText:function(featureId,style,location){},removeText:function(featureId){},clear:function(){},getFeatureIdFromEvent:function(evt){},eraseFeatures:function(features){if(!(features instanceof Array)){features=[features];}
59528 for(var i=0,len=features.length;i<len;++i){var feature=features[i];this.eraseGeometry(feature.geometry,feature.id);this.removeText(feature.id);}},eraseGeometry:function(geometry,featureId){},moveRoot:function(renderer){},getRenderLayerId:function(){return this.container.id;},applyDefaultSymbolizer:function(symbolizer){var result=OpenLayers.Util.extend({},OpenLayers.Renderer.defaultSymbolizer);if(symbolizer.stroke===false){delete result.strokeWidth;delete result.strokeColor;}
59529 if(symbolizer.fill===false){delete result.fillColor;}
59530 OpenLayers.Util.extend(result,symbolizer);return result;},CLASS_NAME:"OpenLayers.Renderer"});OpenLayers.Renderer.defaultSymbolizer={fillColor:"#000000",strokeColor:"#000000",strokeWidth:2,fillOpacity:1,strokeOpacity:1,pointRadius:0};OpenLayers.Strategy=OpenLayers.Class({layer:null,options:null,active:null,autoActivate:true,autoDestroy:true,initialize:function(options){OpenLayers.Util.extend(this,options);this.options=options;this.active=false;},destroy:function(){this.deactivate();this.layer=null;this.options=null;},setLayer:function(layer){this.layer=layer;},activate:function(){if(!this.active){this.active=true;return true;}
59531 return false;},deactivate:function(){if(this.active){this.active=false;return true;}
59532 return false;},CLASS_NAME:"OpenLayers.Strategy"});OpenLayers.Symbolizer=OpenLayers.Class({zIndex:0,initialize:function(config){OpenLayers.Util.extend(this,config);},clone:function(){var Type=eval(this.CLASS_NAME);return new Type(OpenLayers.Util.extend({},this));},CLASS_NAME:"OpenLayers.Symbolizer"});OpenLayers.Rico.Color=OpenLayers.Class({initialize:function(red,green,blue){this.rgb={r:red,g:green,b:blue};},setRed:function(r){this.rgb.r=r;},setGreen:function(g){this.rgb.g=g;},setBlue:function(b){this.rgb.b=b;},setHue:function(h){var hsb=this.asHSB();hsb.h=h;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,hsb.b);},setSaturation:function(s){var hsb=this.asHSB();hsb.s=s;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,hsb.b);},setBrightness:function(b){var hsb=this.asHSB();hsb.b=b;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,hsb.b);},darken:function(percent){var hsb=this.asHSB();this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,Math.max(hsb.b-percent,0));},brighten:function(percent){var hsb=this.asHSB();this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,Math.min(hsb.b+percent,1));},blend:function(other){this.rgb.r=Math.floor((this.rgb.r+other.rgb.r)/2);this.rgb.g=Math.floor((this.rgb.g+other.rgb.g)/2);this.rgb.b=Math.floor((this.rgb.b+other.rgb.b)/2);},isBright:function(){var hsb=this.asHSB();return this.asHSB().b>0.5;},isDark:function(){return!this.isBright();},asRGB:function(){return"rgb("+this.rgb.r+","+this.rgb.g+","+this.rgb.b+")";},asHex:function(){return"#"+this.rgb.r.toColorPart()+this.rgb.g.toColorPart()+this.rgb.b.toColorPart();},asHSB:function(){return OpenLayers.Rico.Color.RGBtoHSB(this.rgb.r,this.rgb.g,this.rgb.b);},toString:function(){return this.asHex();}});OpenLayers.Rico.Color.createFromHex=function(hexCode){if(hexCode.length==4){var shortHexCode=hexCode;var hexCode='#';for(var i=1;i<4;i++){hexCode+=(shortHexCode.charAt(i)+
59533 shortHexCode.charAt(i));}}
59534 if(hexCode.indexOf('#')==0){hexCode=hexCode.substring(1);}
59535 var red=hexCode.substring(0,2);var green=hexCode.substring(2,4);var blue=hexCode.substring(4,6);return new OpenLayers.Rico.Color(parseInt(red,16),parseInt(green,16),parseInt(blue,16));};OpenLayers.Rico.Color.createColorFromBackground=function(elem){var actualColor=RicoUtil.getElementsComputedStyle(OpenLayers.Util.getElement(elem),"backgroundColor","background-color");if(actualColor=="transparent"&&elem.parentNode){return OpenLayers.Rico.Color.createColorFromBackground(elem.parentNode);}
59536 if(actualColor==null){return new OpenLayers.Rico.Color(255,255,255);}
59537 if(actualColor.indexOf("rgb(")==0){var colors=actualColor.substring(4,actualColor.length-1);var colorArray=colors.split(",");return new OpenLayers.Rico.Color(parseInt(colorArray[0]),parseInt(colorArray[1]),parseInt(colorArray[2]));}
59538 else if(actualColor.indexOf("#")==0){return OpenLayers.Rico.Color.createFromHex(actualColor);}
59539 else{return new OpenLayers.Rico.Color(255,255,255);}};OpenLayers.Rico.Color.HSBtoRGB=function(hue,saturation,brightness){var red=0;var green=0;var blue=0;if(saturation==0){red=parseInt(brightness*255.0+0.5);green=red;blue=red;}
59540 else{var h=(hue-Math.floor(hue))*6.0;var f=h-Math.floor(h);var p=brightness*(1.0-saturation);var q=brightness*(1.0-saturation*f);var t=brightness*(1.0-(saturation*(1.0-f)));switch(parseInt(h)){case 0:red=(brightness*255.0+0.5);green=(t*255.0+0.5);blue=(p*255.0+0.5);break;case 1:red=(q*255.0+0.5);green=(brightness*255.0+0.5);blue=(p*255.0+0.5);break;case 2:red=(p*255.0+0.5);green=(brightness*255.0+0.5);blue=(t*255.0+0.5);break;case 3:red=(p*255.0+0.5);green=(q*255.0+0.5);blue=(brightness*255.0+0.5);break;case 4:red=(t*255.0+0.5);green=(p*255.0+0.5);blue=(brightness*255.0+0.5);break;case 5:red=(brightness*255.0+0.5);green=(p*255.0+0.5);blue=(q*255.0+0.5);break;}}
59541 return{r:parseInt(red),g:parseInt(green),b:parseInt(blue)};};OpenLayers.Rico.Color.RGBtoHSB=function(r,g,b){var hue;var saturation;var brightness;var cmax=(r>g)?r:g;if(b>cmax){cmax=b;}
59542 var cmin=(r<g)?r:g;if(b<cmin){cmin=b;}
59543 brightness=cmax/255.0;if(cmax!=0){saturation=(cmax-cmin)/cmax;}else{saturation=0;}
59544 if(saturation==0){hue=0;}else{var redc=(cmax-r)/(cmax-cmin);var greenc=(cmax-g)/(cmax-cmin);var bluec=(cmax-b)/(cmax-cmin);if(r==cmax){hue=bluec-greenc;}else if(g==cmax){hue=2.0+redc-bluec;}else{hue=4.0+greenc-redc;}
59545 hue=hue/6.0;if(hue<0){hue=hue+1.0;}}
59546 return{h:hue,s:saturation,b:brightness};};OpenLayers.Bounds=OpenLayers.Class({left:null,bottom:null,right:null,top:null,centerLonLat:null,initialize:function(left,bottom,right,top){if(left!=null){this.left=OpenLayers.Util.toFloat(left);}
59547 if(bottom!=null){this.bottom=OpenLayers.Util.toFloat(bottom);}
59548 if(right!=null){this.right=OpenLayers.Util.toFloat(right);}
59549 if(top!=null){this.top=OpenLayers.Util.toFloat(top);}},clone:function(){return new OpenLayers.Bounds(this.left,this.bottom,this.right,this.top);},equals:function(bounds){var equals=false;if(bounds!=null){equals=((this.left==bounds.left)&&(this.right==bounds.right)&&(this.top==bounds.top)&&(this.bottom==bounds.bottom));}
59550 return equals;},toString:function(){return("left-bottom=("+this.left+","+this.bottom+")"
59551 +" right-top=("+this.right+","+this.top+")");},toArray:function(reverseAxisOrder){if(reverseAxisOrder===true){return[this.bottom,this.left,this.top,this.right];}else{return[this.left,this.bottom,this.right,this.top];}},toBBOX:function(decimal,reverseAxisOrder){if(decimal==null){decimal=6;}
59552 var mult=Math.pow(10,decimal);var xmin=Math.round(this.left*mult)/mult;var ymin=Math.round(this.bottom*mult)/mult;var xmax=Math.round(this.right*mult)/mult;var ymax=Math.round(this.top*mult)/mult;if(reverseAxisOrder===true){return ymin+","+xmin+","+ymax+","+xmax;}else{return xmin+","+ymin+","+xmax+","+ymax;}},toGeometry:function(){return new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([new OpenLayers.Geometry.Point(this.left,this.bottom),new OpenLayers.Geometry.Point(this.right,this.bottom),new OpenLayers.Geometry.Point(this.right,this.top),new OpenLayers.Geometry.Point(this.left,this.top)])]);},getWidth:function(){return(this.right-this.left);},getHeight:function(){return(this.top-this.bottom);},getSize:function(){return new OpenLayers.Size(this.getWidth(),this.getHeight());},getCenterPixel:function(){return new OpenLayers.Pixel((this.left+this.right)/2,(this.bottom+this.top)/2);},getCenterLonLat:function(){if(!this.centerLonLat){this.centerLonLat=new OpenLayers.LonLat((this.left+this.right)/2,(this.bottom+this.top)/2);}
59553 return this.centerLonLat;},scale:function(ratio,origin){if(origin==null){origin=this.getCenterLonLat();}
59554 var origx,origy;if(origin.CLASS_NAME=="OpenLayers.LonLat"){origx=origin.lon;origy=origin.lat;}else{origx=origin.x;origy=origin.y;}
59555 var left=(this.left-origx)*ratio+origx;var bottom=(this.bottom-origy)*ratio+origy;var right=(this.right-origx)*ratio+origx;var top=(this.top-origy)*ratio+origy;return new OpenLayers.Bounds(left,bottom,right,top);},add:function(x,y){if((x==null)||(y==null)){var msg=OpenLayers.i18n("boundsAddError");OpenLayers.Console.error(msg);return null;}
59556 return new OpenLayers.Bounds(this.left+x,this.bottom+y,this.right+x,this.top+y);},extend:function(object){var bounds=null;if(object){switch(object.CLASS_NAME){case"OpenLayers.LonLat":bounds=new OpenLayers.Bounds(object.lon,object.lat,object.lon,object.lat);break;case"OpenLayers.Geometry.Point":bounds=new OpenLayers.Bounds(object.x,object.y,object.x,object.y);break;case"OpenLayers.Bounds":bounds=object;break;}
59557 if(bounds){this.centerLonLat=null;if((this.left==null)||(bounds.left<this.left)){this.left=bounds.left;}
59558 if((this.bottom==null)||(bounds.bottom<this.bottom)){this.bottom=bounds.bottom;}
59559 if((this.right==null)||(bounds.right>this.right)){this.right=bounds.right;}
59560 if((this.top==null)||(bounds.top>this.top)){this.top=bounds.top;}}}},containsLonLat:function(ll,inclusive){return this.contains(ll.lon,ll.lat,inclusive);},containsPixel:function(px,inclusive){return this.contains(px.x,px.y,inclusive);},contains:function(x,y,inclusive){if(inclusive==null){inclusive=true;}
59561 if(x==null||y==null){return false;}
59562 x=OpenLayers.Util.toFloat(x);y=OpenLayers.Util.toFloat(y);var contains=false;if(inclusive){contains=((x>=this.left)&&(x<=this.right)&&(y>=this.bottom)&&(y<=this.top));}else{contains=((x>this.left)&&(x<this.right)&&(y>this.bottom)&&(y<this.top));}
59563 return contains;},intersectsBounds:function(bounds,inclusive){if(inclusive==null){inclusive=true;}
59564 var intersects=false;var mightTouch=(this.left==bounds.right||this.right==bounds.left||this.top==bounds.bottom||this.bottom==bounds.top);if(inclusive||!mightTouch){var inBottom=(((bounds.bottom>=this.bottom)&&(bounds.bottom<=this.top))||((this.bottom>=bounds.bottom)&&(this.bottom<=bounds.top)));var inTop=(((bounds.top>=this.bottom)&&(bounds.top<=this.top))||((this.top>bounds.bottom)&&(this.top<bounds.top)));var inLeft=(((bounds.left>=this.left)&&(bounds.left<=this.right))||((this.left>=bounds.left)&&(this.left<=bounds.right)));var inRight=(((bounds.right>=this.left)&&(bounds.right<=this.right))||((this.right>=bounds.left)&&(this.right<=bounds.right)));intersects=((inBottom||inTop)&&(inLeft||inRight));}
59565 return intersects;},containsBounds:function(bounds,partial,inclusive){if(partial==null){partial=false;}
59566 if(inclusive==null){inclusive=true;}
59567 var bottomLeft=this.contains(bounds.left,bounds.bottom,inclusive);var bottomRight=this.contains(bounds.right,bounds.bottom,inclusive);var topLeft=this.contains(bounds.left,bounds.top,inclusive);var topRight=this.contains(bounds.right,bounds.top,inclusive);return(partial)?(bottomLeft||bottomRight||topLeft||topRight):(bottomLeft&&bottomRight&&topLeft&&topRight);},determineQuadrant:function(lonlat){var quadrant="";var center=this.getCenterLonLat();quadrant+=(lonlat.lat<center.lat)?"b":"t";quadrant+=(lonlat.lon<center.lon)?"l":"r";return quadrant;},transform:function(source,dest){this.centerLonLat=null;var ll=OpenLayers.Projection.transform({'x':this.left,'y':this.bottom},source,dest);var lr=OpenLayers.Projection.transform({'x':this.right,'y':this.bottom},source,dest);var ul=OpenLayers.Projection.transform({'x':this.left,'y':this.top},source,dest);var ur=OpenLayers.Projection.transform({'x':this.right,'y':this.top},source,dest);this.left=Math.min(ll.x,ul.x);this.bottom=Math.min(ll.y,lr.y);this.right=Math.max(lr.x,ur.x);this.top=Math.max(ul.y,ur.y);return this;},wrapDateLine:function(maxExtent,options){options=options||{};var leftTolerance=options.leftTolerance||0;var rightTolerance=options.rightTolerance||0;var newBounds=this.clone();if(maxExtent){while(newBounds.left<maxExtent.left&&(newBounds.right-rightTolerance)<=maxExtent.left){newBounds=newBounds.add(maxExtent.getWidth(),0);}
59568 while((newBounds.left+leftTolerance)>=maxExtent.right&&newBounds.right>maxExtent.right){newBounds=newBounds.add(-maxExtent.getWidth(),0);}}
59569 return newBounds;},CLASS_NAME:"OpenLayers.Bounds"});OpenLayers.Bounds.fromString=function(str){var bounds=str.split(",");return OpenLayers.Bounds.fromArray(bounds);};OpenLayers.Bounds.fromArray=function(bbox){return new OpenLayers.Bounds(parseFloat(bbox[0]),parseFloat(bbox[1]),parseFloat(bbox[2]),parseFloat(bbox[3]));};OpenLayers.Bounds.fromSize=function(size){return new OpenLayers.Bounds(0,size.h,size.w,0);};OpenLayers.Bounds.oppositeQuadrant=function(quadrant){var opp="";opp+=(quadrant.charAt(0)=='t')?'b':'t';opp+=(quadrant.charAt(1)=='l')?'r':'l';return opp;};OpenLayers.LonLat=OpenLayers.Class({lon:0.0,lat:0.0,initialize:function(lon,lat){this.lon=OpenLayers.Util.toFloat(lon);this.lat=OpenLayers.Util.toFloat(lat);},toString:function(){return("lon="+this.lon+",lat="+this.lat);},toShortString:function(){return(this.lon+", "+this.lat);},clone:function(){return new OpenLayers.LonLat(this.lon,this.lat);},add:function(lon,lat){if((lon==null)||(lat==null)){var msg=OpenLayers.i18n("lonlatAddError");OpenLayers.Console.error(msg);return null;}
59570 return new OpenLayers.LonLat(this.lon+OpenLayers.Util.toFloat(lon),this.lat+OpenLayers.Util.toFloat(lat));},equals:function(ll){var equals=false;if(ll!=null){equals=((this.lon==ll.lon&&this.lat==ll.lat)||(isNaN(this.lon)&&isNaN(this.lat)&&isNaN(ll.lon)&&isNaN(ll.lat)));}
59571 return equals;},transform:function(source,dest){var point=OpenLayers.Projection.transform({'x':this.lon,'y':this.lat},source,dest);this.lon=point.x;this.lat=point.y;return this;},wrapDateLine:function(maxExtent){var newLonLat=this.clone();if(maxExtent){while(newLonLat.lon<maxExtent.left){newLonLat.lon+=maxExtent.getWidth();}
59572 while(newLonLat.lon>maxExtent.right){newLonLat.lon-=maxExtent.getWidth();}}
59573 return newLonLat;},CLASS_NAME:"OpenLayers.LonLat"});OpenLayers.LonLat.fromString=function(str){var pair=str.split(",");return new OpenLayers.LonLat(pair[0],pair[1]);};OpenLayers.Pixel=OpenLayers.Class({x:0.0,y:0.0,initialize:function(x,y){this.x=parseFloat(x);this.y=parseFloat(y);},toString:function(){return("x="+this.x+",y="+this.y);},clone:function(){return new OpenLayers.Pixel(this.x,this.y);},equals:function(px){var equals=false;if(px!=null){equals=((this.x==px.x&&this.y==px.y)||(isNaN(this.x)&&isNaN(this.y)&&isNaN(px.x)&&isNaN(px.y)));}
59574 return equals;},add:function(x,y){if((x==null)||(y==null)){var msg=OpenLayers.i18n("pixelAddError");OpenLayers.Console.error(msg);return null;}
59575 return new OpenLayers.Pixel(this.x+x,this.y+y);},offset:function(px){var newPx=this.clone();if(px){newPx=this.add(px.x,px.y);}
59576 return newPx;},CLASS_NAME:"OpenLayers.Pixel"});OpenLayers.Control=OpenLayers.Class({id:null,map:null,div:null,type:null,allowSelection:false,displayClass:"",title:"",autoActivate:false,active:null,handler:null,eventListeners:null,events:null,EVENT_TYPES:["activate","deactivate"],initialize:function(options){this.displayClass=this.CLASS_NAME.replace("OpenLayers.","ol").replace(/\./g,"");OpenLayers.Util.extend(this,options);this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);if(this.eventListeners instanceof Object){this.events.on(this.eventListeners);}
59577 if(this.id==null){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");}},destroy:function(){if(this.events){if(this.eventListeners){this.events.un(this.eventListeners);}
59578 this.events.destroy();this.events=null;}
59579 this.eventListeners=null;if(this.handler){this.handler.destroy();this.handler=null;}
59580 if(this.handlers){for(var key in this.handlers){if(this.handlers.hasOwnProperty(key)&&typeof this.handlers[key].destroy=="function"){this.handlers[key].destroy();}}
59581 this.handlers=null;}
59582 if(this.map){this.map.removeControl(this);this.map=null;}},setMap:function(map){this.map=map;if(this.handler){this.handler.setMap(map);}},draw:function(px){if(this.div==null){this.div=OpenLayers.Util.createDiv(this.id);this.div.className=this.displayClass;if(!this.allowSelection){this.div.className+=" olControlNoSelect";this.div.setAttribute("unselectable","on",0);this.div.onselectstart=OpenLayers.Function.False;}
59583 if(this.title!=""){this.div.title=this.title;}}
59584 if(px!=null){this.position=px.clone();}
59585 this.moveTo(this.position);return this.div;},moveTo:function(px){if((px!=null)&&(this.div!=null)){this.div.style.left=px.x+"px";this.div.style.top=px.y+"px";}},activate:function(){if(this.active){return false;}
59586 if(this.handler){this.handler.activate();}
59587 this.active=true;if(this.map){OpenLayers.Element.addClass(this.map.viewPortDiv,this.displayClass.replace(/ /g,"")+"Active");}
59588 this.events.triggerEvent("activate");return true;},deactivate:function(){if(this.active){if(this.handler){this.handler.deactivate();}
59589 this.active=false;if(this.map){OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass.replace(/ /g,"")+"Active");}
59590 this.events.triggerEvent("deactivate");return true;}
59591 return false;},CLASS_NAME:"OpenLayers.Control"});OpenLayers.Control.TYPE_BUTTON=1;OpenLayers.Control.TYPE_TOGGLE=2;OpenLayers.Control.TYPE_TOOL=3;OpenLayers.Lang={code:null,defaultCode:"en",getCode:function(){if(!OpenLayers.Lang.code){OpenLayers.Lang.setCode();}
59592 return OpenLayers.Lang.code;},setCode:function(code){var lang;if(!code){code=(OpenLayers.Util.getBrowserName()=="msie")?navigator.userLanguage:navigator.language;}
59593 var parts=code.split('-');parts[0]=parts[0].toLowerCase();if(typeof OpenLayers.Lang[parts[0]]=="object"){lang=parts[0];}
59594 if(parts[1]){var testLang=parts[0]+'-'+parts[1].toUpperCase();if(typeof OpenLayers.Lang[testLang]=="object"){lang=testLang;}}
59595 if(!lang){OpenLayers.Console.warn('Failed to find OpenLayers.Lang.'+parts.join("-")+' dictionary, falling back to default language');lang=OpenLayers.Lang.defaultCode;}
59596 OpenLayers.Lang.code=lang;},translate:function(key,context){var dictionary=OpenLayers.Lang[OpenLayers.Lang.getCode()];var message=dictionary[key];if(!message){message=key;}
59597 if(context){message=OpenLayers.String.format(message,context);}
59598 return message;}};OpenLayers.i18n=OpenLayers.Lang.translate;OpenLayers.Popup.Anchored=OpenLayers.Class(OpenLayers.Popup,{relativePosition:null,keepInMap:true,anchor:null,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){var newArguments=[id,lonlat,contentSize,contentHTML,closeBox,closeBoxCallback];OpenLayers.Popup.prototype.initialize.apply(this,newArguments);this.anchor=(anchor!=null)?anchor:{size:new OpenLayers.Size(0,0),offset:new OpenLayers.Pixel(0,0)};},destroy:function(){this.anchor=null;this.relativePosition=null;OpenLayers.Popup.prototype.destroy.apply(this,arguments);},show:function(){this.updatePosition();OpenLayers.Popup.prototype.show.apply(this,arguments);},moveTo:function(px){var oldRelativePosition=this.relativePosition;this.relativePosition=this.calculateRelativePosition(px);var newPx=this.calculateNewPx(px);var newArguments=new Array(newPx);OpenLayers.Popup.prototype.moveTo.apply(this,newArguments);if(this.relativePosition!=oldRelativePosition){this.updateRelativePosition();}},setSize:function(contentSize){OpenLayers.Popup.prototype.setSize.apply(this,arguments);if((this.lonlat)&&(this.map)){var px=this.map.getLayerPxFromLonLat(this.lonlat);this.moveTo(px);}},calculateRelativePosition:function(px){var lonlat=this.map.getLonLatFromLayerPx(px);var extent=this.map.getExtent();var quadrant=extent.determineQuadrant(lonlat);return OpenLayers.Bounds.oppositeQuadrant(quadrant);},updateRelativePosition:function(){},calculateNewPx:function(px){var newPx=px.offset(this.anchor.offset);var size=this.size||this.contentSize;var top=(this.relativePosition.charAt(0)=='t');newPx.y+=(top)?-(size.h+this.anchor.size.h):this.anchor.size.h;var left=(this.relativePosition.charAt(1)=='l');newPx.x+=(left)?-(size.w+this.anchor.size.w):this.anchor.size.w;return newPx;},CLASS_NAME:"OpenLayers.Popup.Anchored"});OpenLayers.Protocol.SOS=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Protocol.SOS.DEFAULTS);var cls=OpenLayers.Protocol.SOS["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported SOS version: "+options.version;}
59599 return new cls(options);};OpenLayers.Protocol.SOS.DEFAULTS={"version":"1.0.0"};OpenLayers.Protocol.SQL=OpenLayers.Class(OpenLayers.Protocol,{databaseName:'ol',tableName:"ol_vector_features",postReadFiltering:true,initialize:function(options){OpenLayers.Protocol.prototype.initialize.apply(this,[options]);},destroy:function(){OpenLayers.Protocol.prototype.destroy.apply(this);},supported:function(){return false;},evaluateFilter:function(feature,filter){return filter&&this.postReadFiltering?filter.evaluate(feature):true;},CLASS_NAME:"OpenLayers.Protocol.SQL"});OpenLayers.Protocol.WFS=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Protocol.WFS.DEFAULTS);var cls=OpenLayers.Protocol.WFS["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported WFS version: "+options.version;}
59600 return new cls(options);};OpenLayers.Protocol.WFS.fromWMSLayer=function(layer,options){var typeName,featurePrefix;var param=layer.params["LAYERS"];var parts=(param instanceof Array?param[0]:param).split(":");if(parts.length>1){featurePrefix=parts[0];}
59601 typeName=parts.pop();var protocolOptions={url:layer.url,featureType:typeName,featurePrefix:featurePrefix,srsName:layer.projection&&layer.projection.getCode()||layer.map&&layer.map.getProjectionObject().getCode(),version:"1.1.0"};return new OpenLayers.Protocol.WFS(OpenLayers.Util.applyDefaults(options,protocolOptions));};OpenLayers.Protocol.WFS.DEFAULTS={"version":"1.0.0"};OpenLayers.Renderer.Canvas=OpenLayers.Class(OpenLayers.Renderer,{canvas:null,features:null,initialize:function(containerID){OpenLayers.Renderer.prototype.initialize.apply(this,arguments);this.root=document.createElement("canvas");this.container.appendChild(this.root);this.canvas=this.root.getContext("2d");this.features={};},eraseGeometry:function(geometry,featureId){this.eraseFeatures(this.features[featureId][0]);},supported:function(){var canvas=document.createElement("canvas");return!!canvas.getContext;},setExtent:function(extent){this.extent=extent.clone();this.resolution=null;this.redraw();},setSize:function(size){this.size=size.clone();this.root.style.width=size.w+"px";this.root.style.height=size.h+"px";this.root.width=size.w;this.root.height=size.h;this.resolution=null;},drawFeature:function(feature,style){style=style||feature.style;style=this.applyDefaultSymbolizer(style);this.features[feature.id]=[feature,style];this.redraw();},drawGeometry:function(geometry,style){var className=geometry.CLASS_NAME;if((className=="OpenLayers.Geometry.Collection")||(className=="OpenLayers.Geometry.MultiPoint")||(className=="OpenLayers.Geometry.MultiLineString")||(className=="OpenLayers.Geometry.MultiPolygon")){for(var i=0;i<geometry.components.length;i++){this.drawGeometry(geometry.components[i],style);}
59602 return;}
59603 switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":this.drawPoint(geometry,style);break;case"OpenLayers.Geometry.LineString":this.drawLineString(geometry,style);break;case"OpenLayers.Geometry.LinearRing":this.drawLinearRing(geometry,style);break;case"OpenLayers.Geometry.Polygon":this.drawPolygon(geometry,style);break;default:break;}},drawExternalGraphic:function(pt,style){var img=new Image();if(style.graphicTitle){img.title=style.graphicTitle;}
59604 var width=style.graphicWidth||style.graphicHeight;var height=style.graphicHeight||style.graphicWidth;width=width?width:style.pointRadius*2;height=height?height:style.pointRadius*2;var xOffset=(style.graphicXOffset!=undefined)?style.graphicXOffset:-(0.5*width);var yOffset=(style.graphicYOffset!=undefined)?style.graphicYOffset:-(0.5*height);var context={img:img,x:(pt[0]+xOffset),y:(pt[1]+yOffset),width:width,height:height,opacity:style.graphicOpacity||style.fillOpacity,canvas:this.canvas};img.onload=OpenLayers.Function.bind(function(){this.canvas.globalAlpha=this.opacity;this.canvas.drawImage(this.img,this.x,this.y,this.width,this.height);},context);img.src=style.externalGraphic;},setCanvasStyle:function(type,style){if(type=="fill"){this.canvas.globalAlpha=style['fillOpacity'];this.canvas.fillStyle=style['fillColor'];}else if(type=="stroke"){this.canvas.globalAlpha=style['strokeOpacity'];this.canvas.strokeStyle=style['strokeColor'];this.canvas.lineWidth=style['strokeWidth'];}else{this.canvas.globalAlpha=0;this.canvas.lineWidth=1;}},drawPoint:function(geometry,style){if(style.graphic!==false){var pt=this.getLocalXY(geometry);if(style.externalGraphic){this.drawExternalGraphic(pt,style);}else{if(style.fill!==false){this.setCanvasStyle("fill",style);this.canvas.beginPath();this.canvas.arc(pt[0],pt[1],style.pointRadius,0,Math.PI*2,true);this.canvas.fill();}
59605 if(style.stroke!==false){this.setCanvasStyle("stroke",style);this.canvas.beginPath();this.canvas.arc(pt[0],pt[1],style.pointRadius,0,Math.PI*2,true);this.canvas.stroke();this.setCanvasStyle("reset");}}}},drawLineString:function(geometry,style){if(style.stroke!==false){this.setCanvasStyle("stroke",style);this.canvas.beginPath();var start=this.getLocalXY(geometry.components[0]);this.canvas.moveTo(start[0],start[1]);for(var i=1;i<geometry.components.length;i++){var pt=this.getLocalXY(geometry.components[i]);this.canvas.lineTo(pt[0],pt[1]);}
59606 this.canvas.stroke();}
59607 this.setCanvasStyle("reset");},drawLinearRing:function(geometry,style){if(style.fill!==false){this.setCanvasStyle("fill",style);this.canvas.beginPath();var start=this.getLocalXY(geometry.components[0]);this.canvas.moveTo(start[0],start[1]);for(var i=1;i<geometry.components.length-1;i++){var pt=this.getLocalXY(geometry.components[i]);this.canvas.lineTo(pt[0],pt[1]);}
59608 this.canvas.fill();}
59609 if(style.stroke!==false){this.setCanvasStyle("stroke",style);this.canvas.beginPath();var start=this.getLocalXY(geometry.components[0]);this.canvas.moveTo(start[0],start[1]);for(var i=1;i<geometry.components.length;i++){var pt=this.getLocalXY(geometry.components[i]);this.canvas.lineTo(pt[0],pt[1]);}
59610 this.canvas.stroke();}
59611 this.setCanvasStyle("reset");},drawPolygon:function(geometry,style){this.drawLinearRing(geometry.components[0],style);for(var i=1;i<geometry.components.length;i++){this.drawLinearRing(geometry.components[i],{fillOpacity:0,strokeWidth:0,strokeOpacity:0,strokeColor:'#000000',fillColor:'#000000'});}},drawText:function(location,style){style=OpenLayers.Util.extend({fontColor:"#000000",labelAlign:"cm"},style);var pt=this.getLocalXY(location);this.setCanvasStyle("reset");this.canvas.fillStyle=style.fontColor;this.canvas.globalAlpha=style.fontOpacity||1.0;var fontStyle=style.fontWeight+" "+style.fontSize+" "+style.fontFamily;if(this.canvas.fillText){var labelAlign=OpenLayers.Renderer.Canvas.LABEL_ALIGN[style.labelAlign[0]]||"center";this.canvas.font=fontStyle;this.canvas.textAlign=labelAlign;this.canvas.fillText(style.label,pt[0],pt[1]);}else if(this.canvas.mozDrawText){this.canvas.mozTextStyle=fontStyle;var len=this.canvas.mozMeasureText(style.label);switch(style.labelAlign[0]){case"l":break;case"r":pt[0]-=len;break;case"c":default:pt[0]-=len/2;}
59612 this.canvas.translate(pt[0],pt[1]);this.canvas.mozDrawText(style.label);this.canvas.translate(-1*pt[0],-1*pt[1]);}
59613 this.setCanvasStyle("reset");},getLocalXY:function(point){var resolution=this.getResolution();var extent=this.extent;var x=(point.x/resolution+(-extent.left/resolution));var y=((extent.top/resolution)-point.y/resolution);return[x,y];},clear:function(){this.canvas.clearRect(0,0,this.root.width,this.root.height);this.features={};},getFeatureIdFromEvent:function(evt){var loc=this.map.getLonLatFromPixel(evt.xy);var resolution=this.getResolution();var bounds=new OpenLayers.Bounds(loc.lon-resolution*5,loc.lat-resolution*5,loc.lon+resolution*5,loc.lat+resolution*5);var geom=bounds.toGeometry();for(var feat in this.features){if(!this.features.hasOwnProperty(feat)){continue;}
59614 if(this.features[feat][0].geometry.intersects(geom)){return feat;}}
59615 return null;},eraseFeatures:function(features){if(!(features instanceof Array)){features=[features];}
59616 for(var i=0;i<features.length;++i){delete this.features[features[i].id];}
59617 this.redraw();},redraw:function(){if(!this.locked){this.canvas.clearRect(0,0,this.root.width,this.root.height);var labelMap=[];var feature,style;for(var id in this.features){if(!this.features.hasOwnProperty(id)){continue;}
59618 feature=this.features[id][0];style=this.features[id][1];if(!feature.geometry){continue;}
59619 this.drawGeometry(feature.geometry,style);if(style.label){labelMap.push([feature,style]);}}
59620 var item;for(var i=0,len=labelMap.length;i<len;++i){item=labelMap[i];this.drawText(item[0].geometry.getCentroid(),item[1]);}}},CLASS_NAME:"OpenLayers.Renderer.Canvas"});OpenLayers.Renderer.Canvas.LABEL_ALIGN={"l":"left","r":"right"};OpenLayers.ElementsIndexer=OpenLayers.Class({maxZIndex:null,order:null,indices:null,compare:null,initialize:function(yOrdering){this.compare=yOrdering?OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_Y_ORDER:OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_DRAWING_ORDER;this.order=[];this.indices={};this.maxZIndex=0;},insert:function(newNode){if(this.exists(newNode)){this.remove(newNode);}
59621 var nodeId=newNode.id;this.determineZIndex(newNode);var leftIndex=-1;var rightIndex=this.order.length;var middle;while(rightIndex-leftIndex>1){middle=parseInt((leftIndex+rightIndex)/2);var placement=this.compare(this,newNode,OpenLayers.Util.getElement(this.order[middle]));if(placement>0){leftIndex=middle;}else{rightIndex=middle;}}
59622 this.order.splice(rightIndex,0,nodeId);this.indices[nodeId]=this.getZIndex(newNode);return this.getNextElement(rightIndex);},remove:function(node){var nodeId=node.id;var arrayIndex=OpenLayers.Util.indexOf(this.order,nodeId);if(arrayIndex>=0){this.order.splice(arrayIndex,1);delete this.indices[nodeId];if(this.order.length>0){var lastId=this.order[this.order.length-1];this.maxZIndex=this.indices[lastId];}else{this.maxZIndex=0;}}},clear:function(){this.order=[];this.indices={};this.maxZIndex=0;},exists:function(node){return(this.indices[node.id]!=null);},getZIndex:function(node){return node._style.graphicZIndex;},determineZIndex:function(node){var zIndex=node._style.graphicZIndex;if(zIndex==null){zIndex=this.maxZIndex;node._style.graphicZIndex=zIndex;}else if(zIndex>this.maxZIndex){this.maxZIndex=zIndex;}},getNextElement:function(index){var nextIndex=index+1;if(nextIndex<this.order.length){var nextElement=OpenLayers.Util.getElement(this.order[nextIndex]);if(nextElement==undefined){nextElement=this.getNextElement(nextIndex);}
59623 return nextElement;}else{return null;}},CLASS_NAME:"OpenLayers.ElementsIndexer"});OpenLayers.ElementsIndexer.IndexingMethods={Z_ORDER:function(indexer,newNode,nextNode){var newZIndex=indexer.getZIndex(newNode);var returnVal=0;if(nextNode){var nextZIndex=indexer.getZIndex(nextNode);returnVal=newZIndex-nextZIndex;}
59624 return returnVal;},Z_ORDER_DRAWING_ORDER:function(indexer,newNode,nextNode){var returnVal=OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(indexer,newNode,nextNode);if(nextNode&&returnVal==0){returnVal=1;}
59625 return returnVal;},Z_ORDER_Y_ORDER:function(indexer,newNode,nextNode){var returnVal=OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(indexer,newNode,nextNode);if(nextNode&&returnVal===0){var result=nextNode._boundsBottom-newNode._boundsBottom;returnVal=(result===0)?1:result;}
59626 return returnVal;}};OpenLayers.Renderer.Elements=OpenLayers.Class(OpenLayers.Renderer,{rendererRoot:null,root:null,vectorRoot:null,textRoot:null,xmlns:null,indexer:null,BACKGROUND_ID_SUFFIX:"_background",LABEL_ID_SUFFIX:"_label",initialize:function(containerID,options){OpenLayers.Renderer.prototype.initialize.apply(this,arguments);this.rendererRoot=this.createRenderRoot();this.root=this.createRoot("_root");this.vectorRoot=this.createRoot("_vroot");this.textRoot=this.createRoot("_troot");this.root.appendChild(this.vectorRoot);this.root.appendChild(this.textRoot);this.rendererRoot.appendChild(this.root);this.container.appendChild(this.rendererRoot);if(options&&(options.zIndexing||options.yOrdering)){this.indexer=new OpenLayers.ElementsIndexer(options.yOrdering);}},destroy:function(){this.clear();this.rendererRoot=null;this.root=null;this.xmlns=null;OpenLayers.Renderer.prototype.destroy.apply(this,arguments);},clear:function(){var child;var root=this.vectorRoot;if(root){while(child=root.firstChild){root.removeChild(child);}}
59627 root=this.textRoot;if(root){while(child=root.firstChild){root.removeChild(child);}}
59628 if(this.indexer){this.indexer.clear();}},getNodeType:function(geometry,style){},drawGeometry:function(geometry,style,featureId){var className=geometry.CLASS_NAME;var rendered=true;if((className=="OpenLayers.Geometry.Collection")||(className=="OpenLayers.Geometry.MultiPoint")||(className=="OpenLayers.Geometry.MultiLineString")||(className=="OpenLayers.Geometry.MultiPolygon")){for(var i=0,len=geometry.components.length;i<len;i++){rendered=this.drawGeometry(geometry.components[i],style,featureId)&&rendered;}
59629 return rendered;};rendered=false;if(style.display!="none"){if(style.backgroundGraphic){this.redrawBackgroundNode(geometry.id,geometry,style,featureId);}
59630 rendered=this.redrawNode(geometry.id,geometry,style,featureId);}
59631 if(rendered==false){var node=document.getElementById(geometry.id);if(node){if(node._style.backgroundGraphic){node.parentNode.removeChild(document.getElementById(geometry.id+this.BACKGROUND_ID_SUFFIX));}
59632 node.parentNode.removeChild(node);}}
59633 return rendered;},redrawNode:function(id,geometry,style,featureId){style=this.applyDefaultSymbolizer(style);var node=this.nodeFactory(id,this.getNodeType(geometry,style));node._featureId=featureId;node._boundsBottom=geometry.getBounds().bottom;node._geometryClass=geometry.CLASS_NAME;node._style=style;var drawResult=this.drawGeometryNode(node,geometry,style);if(drawResult===false){return false;}
59634 node=drawResult.node;if(this.indexer){var insert=this.indexer.insert(node);if(insert){this.vectorRoot.insertBefore(node,insert);}else{this.vectorRoot.appendChild(node);}}else{if(node.parentNode!==this.vectorRoot){this.vectorRoot.appendChild(node);}}
59635 this.postDraw(node);return drawResult.complete;},redrawBackgroundNode:function(id,geometry,style,featureId){var backgroundStyle=OpenLayers.Util.extend({},style);backgroundStyle.externalGraphic=backgroundStyle.backgroundGraphic;backgroundStyle.graphicXOffset=backgroundStyle.backgroundXOffset;backgroundStyle.graphicYOffset=backgroundStyle.backgroundYOffset;backgroundStyle.graphicZIndex=backgroundStyle.backgroundGraphicZIndex;backgroundStyle.graphicWidth=backgroundStyle.backgroundWidth||backgroundStyle.graphicWidth;backgroundStyle.graphicHeight=backgroundStyle.backgroundHeight||backgroundStyle.graphicHeight;backgroundStyle.backgroundGraphic=null;backgroundStyle.backgroundXOffset=null;backgroundStyle.backgroundYOffset=null;backgroundStyle.backgroundGraphicZIndex=null;return this.redrawNode(id+this.BACKGROUND_ID_SUFFIX,geometry,backgroundStyle,null);},drawGeometryNode:function(node,geometry,style){style=style||node._style;var options={'isFilled':style.fill===undefined?true:style.fill,'isStroked':style.stroke===undefined?!!style.strokeWidth:style.stroke};var drawn;switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":if(style.graphic===false){options.isFilled=false;options.isStroked=false;}
59636 drawn=this.drawPoint(node,geometry);break;case"OpenLayers.Geometry.LineString":options.isFilled=false;drawn=this.drawLineString(node,geometry);break;case"OpenLayers.Geometry.LinearRing":drawn=this.drawLinearRing(node,geometry);break;case"OpenLayers.Geometry.Polygon":drawn=this.drawPolygon(node,geometry);break;case"OpenLayers.Geometry.Surface":drawn=this.drawSurface(node,geometry);break;case"OpenLayers.Geometry.Rectangle":drawn=this.drawRectangle(node,geometry);break;default:break;}
59637 node._options=options;if(drawn!=false){return{node:this.setStyle(node,style,options,geometry),complete:drawn};}else{return false;}},postDraw:function(node){},drawPoint:function(node,geometry){},drawLineString:function(node,geometry){},drawLinearRing:function(node,geometry){},drawPolygon:function(node,geometry){},drawRectangle:function(node,geometry){},drawCircle:function(node,geometry){},drawSurface:function(node,geometry){},removeText:function(featureId){var label=document.getElementById(featureId+this.LABEL_ID_SUFFIX);if(label){this.textRoot.removeChild(label);}},getFeatureIdFromEvent:function(evt){var target=evt.target;var useElement=target&&target.correspondingUseElement;var node=useElement?useElement:(target||evt.srcElement);var featureId=node._featureId;return featureId;},eraseGeometry:function(geometry,featureId){if((geometry.CLASS_NAME=="OpenLayers.Geometry.MultiPoint")||(geometry.CLASS_NAME=="OpenLayers.Geometry.MultiLineString")||(geometry.CLASS_NAME=="OpenLayers.Geometry.MultiPolygon")||(geometry.CLASS_NAME=="OpenLayers.Geometry.Collection")){for(var i=0,len=geometry.components.length;i<len;i++){this.eraseGeometry(geometry.components[i],featureId);}}else{var element=OpenLayers.Util.getElement(geometry.id);if(element&&element.parentNode){if(element.geometry){element.geometry.destroy();element.geometry=null;}
59638 element.parentNode.removeChild(element);if(this.indexer){this.indexer.remove(element);}
59639 if(element._style.backgroundGraphic){var backgroundId=geometry.id+this.BACKGROUND_ID_SUFFIX;var bElem=OpenLayers.Util.getElement(backgroundId);if(bElem&&bElem.parentNode){bElem.parentNode.removeChild(bElem);}}}}},nodeFactory:function(id,type){var node=OpenLayers.Util.getElement(id);if(node){if(!this.nodeTypeCompare(node,type)){node.parentNode.removeChild(node);node=this.nodeFactory(id,type);}}else{node=this.createNode(type,id);}
59640 return node;},nodeTypeCompare:function(node,type){},createNode:function(type,id){},moveRoot:function(renderer){var root=this.root;if(renderer.root.parentNode==this.rendererRoot){root=renderer.root;}
59641 root.parentNode.removeChild(root);renderer.rendererRoot.appendChild(root);},getRenderLayerId:function(){return this.root.parentNode.parentNode.id;},isComplexSymbol:function(graphicName){return(graphicName!="circle")&&!!graphicName;},CLASS_NAME:"OpenLayers.Renderer.Elements"});OpenLayers.Renderer.symbol={"star":[350,75,379,161,469,161,397,215,423,301,350,250,277,301,303,215,231,161,321,161,350,75],"cross":[4,0,6,0,6,4,10,4,10,6,6,6,6,10,4,10,4,6,0,6,0,4,4,4,4,0],"x":[0,0,25,0,50,35,75,0,100,0,65,50,100,100,75,100,50,65,25,100,0,100,35,50,0,0],"square":[0,0,0,1,1,1,1,0,0,0],"triangle":[0,10,10,10,5,0,0,10]};OpenLayers.Strategy.Cluster=OpenLayers.Class(OpenLayers.Strategy,{distance:20,threshold:null,features:null,clusters:null,clustering:false,resolution:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){this.layer.events.on({"beforefeaturesadded":this.cacheFeatures,"moveend":this.cluster,scope:this});}
59642 return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.clearCache();this.layer.events.un({"beforefeaturesadded":this.cacheFeatures,"moveend":this.cluster,scope:this});}
59643 return deactivated;},cacheFeatures:function(event){var propagate=true;if(!this.clustering){this.clearCache();this.features=event.features;this.cluster();propagate=false;}
59644 return propagate;},clearCache:function(){this.features=null;},cluster:function(event){if((!event||event.zoomChanged)&&this.features){var resolution=this.layer.map.getResolution();if(resolution!=this.resolution||!this.clustersExist()){this.resolution=resolution;var clusters=[];var feature,clustered,cluster;for(var i=0;i<this.features.length;++i){feature=this.features[i];if(feature.geometry){clustered=false;for(var j=clusters.length-1;j>=0;--j){cluster=clusters[j];if(this.shouldCluster(cluster,feature)){this.addToCluster(cluster,feature);clustered=true;break;}}
59645 if(!clustered){clusters.push(this.createCluster(this.features[i]));}}}
59646 this.layer.removeAllFeatures();if(clusters.length>0){if(this.threshold>1){var clone=clusters.slice();clusters=[];var candidate;for(var i=0,len=clone.length;i<len;++i){candidate=clone[i];if(candidate.attributes.count<this.threshold){Array.prototype.push.apply(clusters,candidate.cluster);}else{clusters.push(candidate);}}}
59647 this.clustering=true;this.layer.addFeatures(clusters);this.clustering=false;}
59648 this.clusters=clusters;}}},clustersExist:function(){var exist=false;if(this.clusters&&this.clusters.length>0&&this.clusters.length==this.layer.features.length){exist=true;for(var i=0;i<this.clusters.length;++i){if(this.clusters[i]!=this.layer.features[i]){exist=false;break;}}}
59649 return exist;},shouldCluster:function(cluster,feature){var cc=cluster.geometry.getBounds().getCenterLonLat();var fc=feature.geometry.getBounds().getCenterLonLat();var distance=(Math.sqrt(Math.pow((cc.lon-fc.lon),2)+Math.pow((cc.lat-fc.lat),2))/this.resolution);return(distance<=this.distance);},addToCluster:function(cluster,feature){cluster.cluster.push(feature);cluster.attributes.count+=1;},createCluster:function(feature){var center=feature.geometry.getBounds().getCenterLonLat();var cluster=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(center.lon,center.lat),{count:1});cluster.cluster=[feature];return cluster;},CLASS_NAME:"OpenLayers.Strategy.Cluster"});OpenLayers.Strategy.Fixed=OpenLayers.Class(OpenLayers.Strategy,{preload:false,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},destroy:function(){OpenLayers.Strategy.prototype.destroy.apply(this,arguments);},activate:function(){if(OpenLayers.Strategy.prototype.activate.apply(this,arguments)){this.layer.events.on({"refresh":this.load,scope:this});if(this.layer.visibility==true||this.preload){this.load();}else{this.layer.events.on({"visibilitychanged":this.load,scope:this});}
59650 return true;}
59651 return false;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.layer.events.un({"refresh":this.load,"visibilitychanged":this.load,scope:this});}
59652 return deactivated;},load:function(options){this.layer.events.triggerEvent("loadstart");this.layer.protocol.read(OpenLayers.Util.applyDefaults({callback:this.merge,filter:this.layer.filter,scope:this},options));this.layer.events.un({"visibilitychanged":this.load,scope:this});},merge:function(resp){this.layer.destroyFeatures();var features=resp.features;if(features&&features.length>0){var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var geom;for(var i=0,len=features.length;i<len;++i){geom=features[i].geometry;if(geom){geom.transform(remote,local);}}}
59653 this.layer.addFeatures(features);}
59654 this.layer.events.triggerEvent("loadend");},CLASS_NAME:"OpenLayers.Strategy.Fixed"});OpenLayers.Strategy.Paging=OpenLayers.Class(OpenLayers.Strategy,{features:null,length:10,num:null,paging:false,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){this.layer.events.on({"beforefeaturesadded":this.cacheFeatures,scope:this});}
59655 return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.clearCache();this.layer.events.un({"beforefeaturesadded":this.cacheFeatures,scope:this});}
59656 return deactivated;},cacheFeatures:function(event){if(!this.paging){this.clearCache();this.features=event.features;this.pageNext(event);}},clearCache:function(){if(this.features){for(var i=0;i<this.features.length;++i){this.features[i].destroy();}}
59657 this.features=null;this.num=null;},pageCount:function(){var numFeatures=this.features?this.features.length:0;return Math.ceil(numFeatures/this.length);},pageNum:function(){return this.num;},pageLength:function(newLength){if(newLength&&newLength>0){this.length=newLength;}
59658 return this.length;},pageNext:function(event){var changed=false;if(this.features){if(this.num===null){this.num=-1;}
59659 var start=(this.num+1)*this.length;changed=this.page(start,event);}
59660 return changed;},pagePrevious:function(){var changed=false;if(this.features){if(this.num===null){this.num=this.pageCount();}
59661 var start=(this.num-1)*this.length;changed=this.page(start);}
59662 return changed;},page:function(start,event){var changed=false;if(this.features){if(start>=0&&start<this.features.length){var num=Math.floor(start/this.length);if(num!=this.num){this.paging=true;var features=this.features.slice(start,start+this.length);this.layer.removeFeatures(this.layer.features);this.num=num;if(event&&event.features){event.features=features;}else{this.layer.addFeatures(features);}
59663 this.paging=false;changed=true;}}}
59664 return changed;},CLASS_NAME:"OpenLayers.Strategy.Paging"});OpenLayers.Strategy.Refresh=OpenLayers.Class(OpenLayers.Strategy,{force:false,interval:0,timer:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){if(this.layer.visibility===true){this.start();}
59665 this.layer.events.on({"visibilitychanged":this.reset,scope:this});}
59666 return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.stop();}
59667 return deactivated;},reset:function(){if(this.layer.visibility===true){this.start();}else{this.stop();}},start:function(){if(this.interval&&typeof this.interval==="number"&&this.interval>0){this.timer=window.setInterval(OpenLayers.Function.bind(this.refresh,this),this.interval);}},refresh:function(){if(this.layer&&this.layer.refresh&&typeof this.layer.refresh=="function"){this.layer.refresh({force:this.force});}},stop:function(){if(this.timer!==null){window.clearInterval(this.timer);this.timer=null;}},CLASS_NAME:"OpenLayers.Strategy.Refresh"});OpenLayers.Strategy.Save=OpenLayers.Class(OpenLayers.Strategy,{EVENT_TYPES:["start","success","fail"],events:null,auto:false,timer:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){if(this.auto){if(typeof this.auto==="number"){this.timer=window.setInterval(OpenLayers.Function.bind(this.save,this),this.auto*1000);}else{this.layer.events.on({"featureadded":this.triggerSave,"afterfeaturemodified":this.triggerSave,scope:this});}}}
59668 return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){if(this.auto){if(typeof this.auto==="number"){window.clearInterval(this.timer);}else{this.layer.events.un({"featureadded":this.triggerSave,"afterfeaturemodified":this.triggerSave,scope:this});}}}
59669 return deactivated;},triggerSave:function(event){var feature=event.feature;if(feature.state===OpenLayers.State.INSERT||feature.state===OpenLayers.State.UPDATE||feature.state===OpenLayers.State.DELETE){this.save([event.feature]);}},save:function(features){if(!features){features=this.layer.features;}
59670 this.events.triggerEvent("start",{features:features});var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var len=features.length;var clones=new Array(len);var orig,clone;for(var i=0;i<len;++i){orig=features[i];clone=orig.clone();clone.fid=orig.fid;clone.state=orig.state;if(orig.url){clone.url=orig.url;}
59671 clone._original=orig;clone.geometry.transform(local,remote);clones[i]=clone;}
59672 features=clones;}
59673 this.layer.protocol.commit(features,{callback:this.onCommit,scope:this});},onCommit:function(response){var evt={"response":response};if(response.success()){var features=response.reqFeatures;var state,feature;var destroys=[];var insertIds=response.insertIds||[];var j=0;for(var i=0,len=features.length;i<len;++i){feature=features[i];feature=feature._original||feature;state=feature.state;if(state){if(state==OpenLayers.State.DELETE){destroys.push(feature);}else if(state==OpenLayers.State.INSERT){feature.fid=insertIds[j];++j;}
59674 feature.state=null;}}
59675 if(destroys.length>0){this.layer.destroyFeatures(destroys);}
59676 this.events.triggerEvent("success",evt);}else{this.events.triggerEvent("fail",evt);}},CLASS_NAME:"OpenLayers.Strategy.Save"});OpenLayers.Symbolizer.Line=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Line"});OpenLayers.Symbolizer.Point=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,fillColor:null,fillOpacity:null,pointRadius:null,externalGraphic:null,graphicWidth:null,graphicHeight:null,graphicOpacity:null,graphicXOffset:null,graphicYOffset:null,rotation:null,graphicName:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Point"});OpenLayers.Symbolizer.Polygon=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,fillColor:null,fillOpacity:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Polygon"});OpenLayers.Symbolizer.Raster=OpenLayers.Class(OpenLayers.Symbolizer,{initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Raster"});OpenLayers.Symbolizer.Text=OpenLayers.Class(OpenLayers.Symbolizer,{label:null,fontFamily:null,fontSize:null,fontWeight:null,fontStyle:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Text"});OpenLayers.Tween=OpenLayers.Class({INTERVAL:10,easing:null,begin:null,finish:null,duration:null,callbacks:null,time:null,interval:null,playing:false,initialize:function(easing){this.easing=(easing)?easing:OpenLayers.Easing.Expo.easeOut;},start:function(begin,finish,duration,options){this.playing=true;this.begin=begin;this.finish=finish;this.duration=duration;this.callbacks=options.callbacks;this.time=0;if(this.interval){window.clearInterval(this.interval);this.interval=null;}
59677 if(this.callbacks&&this.callbacks.start){this.callbacks.start.call(this,this.begin);}
59678 this.interval=window.setInterval(OpenLayers.Function.bind(this.play,this),this.INTERVAL);},stop:function(){if(!this.playing){return;}
59679 if(this.callbacks&&this.callbacks.done){this.callbacks.done.call(this,this.finish);}
59680 window.clearInterval(this.interval);this.interval=null;this.playing=false;},play:function(){var value={};for(var i in this.begin){var b=this.begin[i];var f=this.finish[i];if(b==null||f==null||isNaN(b)||isNaN(f)){OpenLayers.Console.error('invalid value for Tween');}
59681 var c=f-b;value[i]=this.easing.apply(this,[this.time,b,c,this.duration]);}
59682 this.time++;if(this.callbacks&&this.callbacks.eachStep){this.callbacks.eachStep.call(this,value);}
59683 if(this.time>this.duration){this.stop();}},CLASS_NAME:"OpenLayers.Tween"});OpenLayers.Easing={CLASS_NAME:"OpenLayers.Easing"};OpenLayers.Easing.Linear={easeIn:function(t,b,c,d){return c*t/d+b;},easeOut:function(t,b,c,d){return c*t/d+b;},easeInOut:function(t,b,c,d){return c*t/d+b;},CLASS_NAME:"OpenLayers.Easing.Linear"};OpenLayers.Easing.Expo={easeIn:function(t,b,c,d){return(t==0)?b:c*Math.pow(2,10*(t/d-1))+b;},easeOut:function(t,b,c,d){return(t==d)?b+c:c*(-Math.pow(2,-10*t/d)+1)+b;},easeInOut:function(t,b,c,d){if(t==0)return b;if(t==d)return b+c;if((t/=d/2)<1)return c/2*Math.pow(2,10*(t-1))+b;return c/2*(-Math.pow(2,-10*--t)+2)+b;},CLASS_NAME:"OpenLayers.Easing.Expo"};OpenLayers.Easing.Quad={easeIn:function(t,b,c,d){return c*(t/=d)*t+b;},easeOut:function(t,b,c,d){return-c*(t/=d)*(t-2)+b;},easeInOut:function(t,b,c,d){if((t/=d/2)<1)return c/2*t*t+b;return-c/2*((--t)*(t-2)-1)+b;},CLASS_NAME:"OpenLayers.Easing.Quad"};OpenLayers.Control.ArgParser=OpenLayers.Class(OpenLayers.Control,{center:null,zoom:null,layers:null,displayProjection:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},setMap:function(map){OpenLayers.Control.prototype.setMap.apply(this,arguments);for(var i=0,len=this.map.controls.length;i<len;i++){var control=this.map.controls[i];if((control!=this)&&(control.CLASS_NAME=="OpenLayers.Control.ArgParser")){if(control.displayProjection!=this.displayProjection){this.displayProjection=control.displayProjection;}
59684 break;}}
59685 if(i==this.map.controls.length){var args=OpenLayers.Util.getParameters();if(args.layers){this.layers=args.layers;this.map.events.register('addlayer',this,this.configureLayers);this.configureLayers();}
59686 if(args.lat&&args.lon){this.center=new OpenLayers.LonLat(parseFloat(args.lon),parseFloat(args.lat));if(args.zoom){this.zoom=parseInt(args.zoom);}
59687 this.map.events.register('changebaselayer',this,this.setCenter);this.setCenter();}}},setCenter:function(){if(this.map.baseLayer){this.map.events.unregister('changebaselayer',this,this.setCenter);if(this.displayProjection){this.center.transform(this.displayProjection,this.map.getProjectionObject());}
59688 this.map.setCenter(this.center,this.zoom);}},configureLayers:function(){if(this.layers.length==this.map.layers.length){this.map.events.unregister('addlayer',this,this.configureLayers);for(var i=0,len=this.layers.length;i<len;i++){var layer=this.map.layers[i];var c=this.layers.charAt(i);if(c=="B"){this.map.setBaseLayer(layer);}else if((c=="T")||(c=="F")){layer.setVisibility(c=="T");}}}},CLASS_NAME:"OpenLayers.Control.ArgParser"});OpenLayers.Control.Attribution=OpenLayers.Class(OpenLayers.Control,{separator:", ",initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){this.map.events.un({"removelayer":this.updateAttribution,"addlayer":this.updateAttribution,"changelayer":this.updateAttribution,"changebaselayer":this.updateAttribution,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.map.events.on({'changebaselayer':this.updateAttribution,'changelayer':this.updateAttribution,'addlayer':this.updateAttribution,'removelayer':this.updateAttribution,scope:this});this.updateAttribution();return this.div;},updateAttribution:function(){var attributions=[];if(this.map&&this.map.layers){for(var i=0,len=this.map.layers.length;i<len;i++){var layer=this.map.layers[i];if(layer.attribution&&layer.getVisibility()){if(OpenLayers.Util.indexOf(attributions,layer.attribution)===-1){attributions.push(layer.attribution);}}}
59689 this.div.innerHTML=attributions.join(this.separator);}},CLASS_NAME:"OpenLayers.Control.Attribution"});OpenLayers.Control.Button=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){},CLASS_NAME:"OpenLayers.Control.Button"});OpenLayers.Control.Graticule=OpenLayers.Class(OpenLayers.Control,{autoActivate:true,intervals:[45,30,20,10,5,2,1,0.5,0.2,0.1,0.05,0.01,0.005,0.002,0.001],displayInLayerSwitcher:true,visible:true,numPoints:50,targetSize:200,layerName:null,labelled:true,labelFormat:'dm',lineSymbolizer:{strokeColor:"#333",strokeWidth:1,strokeOpacity:0.5},labelSymbolizer:{},gratLayer:null,initialize:function(options){options=options||{};options.layerName=options.layerName||OpenLayers.i18n("graticule");OpenLayers.Control.prototype.initialize.apply(this,[options]);this.labelSymbolizer.stroke=false;this.labelSymbolizer.fill=false;this.labelSymbolizer.label="${label}";this.labelSymbolizer.labelAlign="${labelAlign}";this.labelSymbolizer.labelXOffset="${xOffset}";this.labelSymbolizer.labelYOffset="${yOffset}";},destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments);if(this.gratLayer){this.gratLayer.destroy();this.gratLayer=null;}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.gratLayer){var gratStyle=new OpenLayers.Style({},{rules:[new OpenLayers.Rule({'symbolizer':{"Point":this.labelSymbolizer,"Line":this.lineSymbolizer}})]});this.gratLayer=new OpenLayers.Layer.Vector(this.layerName,{styleMap:new OpenLayers.StyleMap({'default':gratStyle}),visibility:this.visible,displayInLayerSwitcher:this.displayInLayerSwitcher});}
59690 return this.div;},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){this.map.addLayer(this.gratLayer);this.map.events.register('moveend',this,this.update);this.update();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.map.events.unregister('moveend',this,this.update);this.map.removeLayer(this.gratLayer);return true;}else{return false;}},update:function(){var mapBounds=this.map.getExtent();if(!mapBounds){return;}
59691 this.gratLayer.destroyFeatures();var llProj=new OpenLayers.Projection("EPSG:4326");var mapProj=this.map.getProjectionObject();var mapRes=this.map.getResolution();if(mapProj.proj&&mapProj.proj.projName=="longlat"){this.numPoints=1;}
59692 var mapCenter=this.map.getCenter();var mapCenterLL=new OpenLayers.Pixel(mapCenter.lon,mapCenter.lat);OpenLayers.Projection.transform(mapCenterLL,mapProj,llProj);var testSq=this.targetSize*mapRes;testSq*=testSq;var llInterval;for(var i=0;i<this.intervals.length;++i){llInterval=this.intervals[i];var delta=llInterval/2;var p1=mapCenterLL.offset(new OpenLayers.Pixel(-delta,-delta));var p2=mapCenterLL.offset(new OpenLayers.Pixel(delta,delta));OpenLayers.Projection.transform(p1,llProj,mapProj);OpenLayers.Projection.transform(p2,llProj,mapProj);var distSq=(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);if(distSq<=testSq){break;}}
59693 mapCenterLL.x=Math.floor(mapCenterLL.x/llInterval)*llInterval;mapCenterLL.y=Math.floor(mapCenterLL.y/llInterval)*llInterval;var iter=0;var centerLonPoints=[mapCenterLL.clone()];var newPoint=mapCenterLL.clone();var mapXY;do{newPoint=newPoint.offset(new OpenLayers.Pixel(0,llInterval));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLonPoints.unshift(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);newPoint=mapCenterLL.clone();do{newPoint=newPoint.offset(new OpenLayers.Pixel(0,-llInterval));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLonPoints.push(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);iter=0;var centerLatPoints=[mapCenterLL.clone()];newPoint=mapCenterLL.clone();do{newPoint=newPoint.offset(new OpenLayers.Pixel(-llInterval,0));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLatPoints.unshift(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);newPoint=mapCenterLL.clone();do{newPoint=newPoint.offset(new OpenLayers.Pixel(llInterval,0));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLatPoints.push(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);var lines=[];for(var i=0;i<centerLatPoints.length;++i){var lon=centerLatPoints[i].x;var pointList=[];var labelPoint=null;var latEnd=Math.min(centerLonPoints[0].y,90);var latStart=Math.max(centerLonPoints[centerLonPoints.length-1].y,-90);var latDelta=(latEnd-latStart)/this.numPoints;var lat=latStart;for(var j=0;j<=this.numPoints;++j){var gridPoint=new OpenLayers.Geometry.Point(lon,lat);gridPoint.transform(llProj,mapProj);pointList.push(gridPoint);lat+=latDelta;if(gridPoint.y>=mapBounds.bottom&&!labelPoint){labelPoint=gridPoint;}}
59694 if(this.labelled){var labelPos=new OpenLayers.Geometry.Point(labelPoint.x,mapBounds.bottom);var labelAttrs={value:lon,label:this.labelled?OpenLayers.Util.getFormattedLonLat(lon,"lon",this.labelFormat):"",labelAlign:"cb",xOffset:0,yOffset:2};this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(labelPos,labelAttrs));}
59695 var geom=new OpenLayers.Geometry.LineString(pointList);lines.push(new OpenLayers.Feature.Vector(geom));}
59696 for(var j=0;j<centerLonPoints.length;++j){lat=centerLonPoints[j].y;if(lat<-90||lat>90){continue;}
59697 var pointList=[];var lonStart=centerLatPoints[0].x;var lonEnd=centerLatPoints[centerLatPoints.length-1].x;var lonDelta=(lonEnd-lonStart)/this.numPoints;var lon=lonStart;var labelPoint=null;for(var i=0;i<=this.numPoints;++i){var gridPoint=new OpenLayers.Geometry.Point(lon,lat);gridPoint.transform(llProj,mapProj);pointList.push(gridPoint);lon+=lonDelta;if(gridPoint.x<mapBounds.right){labelPoint=gridPoint;}}
59698 if(this.labelled){var labelPos=new OpenLayers.Geometry.Point(mapBounds.right,labelPoint.y);var labelAttrs={value:lat,label:this.labelled?OpenLayers.Util.getFormattedLonLat(lat,"lat",this.labelFormat):"",labelAlign:"rb",xOffset:-2,yOffset:2};this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(labelPos,labelAttrs));}
59699 var geom=new OpenLayers.Geometry.LineString(pointList);lines.push(new OpenLayers.Feature.Vector(geom));}
59700 this.gratLayer.addFeatures(lines);},CLASS_NAME:"OpenLayers.Control.Graticule"});OpenLayers.Control.LayerSwitcher=OpenLayers.Class(OpenLayers.Control,{roundedCorner:true,roundedCornerColor:"darkblue",layerStates:null,layersDiv:null,baseLayersDiv:null,baseLayers:null,dataLbl:null,dataLayersDiv:null,dataLayers:null,minimizeDiv:null,maximizeDiv:null,ascending:true,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);this.layerStates=[];},destroy:function(){OpenLayers.Event.stopObservingElement(this.div);OpenLayers.Event.stopObservingElement(this.minimizeDiv);OpenLayers.Event.stopObservingElement(this.maximizeDiv);this.clearLayersArray("base");this.clearLayersArray("data");this.map.events.un({"addlayer":this.redraw,"changelayer":this.redraw,"removelayer":this.redraw,"changebaselayer":this.redraw,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Control.prototype.setMap.apply(this,arguments);this.map.events.on({"addlayer":this.redraw,"changelayer":this.redraw,"removelayer":this.redraw,"changebaselayer":this.redraw,scope:this});},draw:function(){OpenLayers.Control.prototype.draw.apply(this);this.loadContents();if(!this.outsideViewport){this.minimizeControl();}
59701 this.redraw();return this.div;},clearLayersArray:function(layersType){var layers=this[layersType+"Layers"];if(layers){for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];OpenLayers.Event.stopObservingElement(layer.inputElem);OpenLayers.Event.stopObservingElement(layer.labelSpan);}}
59702 this[layersType+"LayersDiv"].innerHTML="";this[layersType+"Layers"]=[];},checkRedraw:function(){var redraw=false;if(!this.layerStates.length||(this.map.layers.length!=this.layerStates.length)){redraw=true;}else{for(var i=0,len=this.layerStates.length;i<len;i++){var layerState=this.layerStates[i];var layer=this.map.layers[i];if((layerState.name!=layer.name)||(layerState.inRange!=layer.inRange)||(layerState.id!=layer.id)||(layerState.visibility!=layer.visibility)){redraw=true;break;}}}
59703 return redraw;},redraw:function(){if(!this.checkRedraw()){return this.div;}
59704 this.clearLayersArray("base");this.clearLayersArray("data");var containsOverlays=false;var containsBaseLayers=false;var len=this.map.layers.length;this.layerStates=new Array(len);for(var i=0;i<len;i++){var layer=this.map.layers[i];this.layerStates[i]={'name':layer.name,'visibility':layer.visibility,'inRange':layer.inRange,'id':layer.id};}
59705 var layers=this.map.layers.slice();if(!this.ascending){layers.reverse();}
59706 for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];var baseLayer=layer.isBaseLayer;if(layer.displayInLayerSwitcher){if(baseLayer){containsBaseLayers=true;}else{containsOverlays=true;}
59707 var checked=(baseLayer)?(layer==this.map.baseLayer):layer.getVisibility();var inputElem=document.createElement("input");inputElem.id=this.id+"_input_"+layer.name;inputElem.name=(baseLayer)?this.id+"_baseLayers":layer.name;inputElem.type=(baseLayer)?"radio":"checkbox";inputElem.value=layer.name;inputElem.checked=checked;inputElem.defaultChecked=checked;if(!baseLayer&&!layer.inRange){inputElem.disabled=true;}
59708 var context={'inputElem':inputElem,'layer':layer,'layerSwitcher':this};OpenLayers.Event.observe(inputElem,"mouseup",OpenLayers.Function.bindAsEventListener(this.onInputClick,context));var labelSpan=document.createElement("span");OpenLayers.Element.addClass(labelSpan,"labelSpan")
59709 if(!baseLayer&&!layer.inRange){labelSpan.style.color="gray";}
59710 labelSpan.innerHTML=layer.name;labelSpan.style.verticalAlign=(baseLayer)?"bottom":"baseline";OpenLayers.Event.observe(labelSpan,"click",OpenLayers.Function.bindAsEventListener(this.onInputClick,context));var br=document.createElement("br");var groupArray=(baseLayer)?this.baseLayers:this.dataLayers;groupArray.push({'layer':layer,'inputElem':inputElem,'labelSpan':labelSpan});var groupDiv=(baseLayer)?this.baseLayersDiv:this.dataLayersDiv;groupDiv.appendChild(inputElem);groupDiv.appendChild(labelSpan);groupDiv.appendChild(br);}}
59711 this.dataLbl.style.display=(containsOverlays)?"":"none";this.baseLbl.style.display=(containsBaseLayers)?"":"none";return this.div;},onInputClick:function(e){if(!this.inputElem.disabled){if(this.inputElem.type=="radio"){this.inputElem.checked=true;this.layer.map.setBaseLayer(this.layer);}else{this.inputElem.checked=!this.inputElem.checked;this.layerSwitcher.updateMap();}}
59712 OpenLayers.Event.stop(e);},onLayerClick:function(e){this.updateMap();},updateMap:function(){for(var i=0,len=this.baseLayers.length;i<len;i++){var layerEntry=this.baseLayers[i];if(layerEntry.inputElem.checked){this.map.setBaseLayer(layerEntry.layer,false);}}
59713 for(var i=0,len=this.dataLayers.length;i<len;i++){var layerEntry=this.dataLayers[i];layerEntry.layer.setVisibility(layerEntry.inputElem.checked);}},maximizeControl:function(e){this.div.style.width="";this.div.style.height="";this.showControls(false);if(e!=null){OpenLayers.Event.stop(e);}},minimizeControl:function(e){this.div.style.width="0px";this.div.style.height="0px";this.showControls(true);if(e!=null){OpenLayers.Event.stop(e);}},showControls:function(minimize){this.maximizeDiv.style.display=minimize?"":"none";this.minimizeDiv.style.display=minimize?"none":"";this.layersDiv.style.display=minimize?"none":"";},loadContents:function(){OpenLayers.Event.observe(this.div,"mouseup",OpenLayers.Function.bindAsEventListener(this.mouseUp,this));OpenLayers.Event.observe(this.div,"click",this.ignoreEvent);OpenLayers.Event.observe(this.div,"mousedown",OpenLayers.Function.bindAsEventListener(this.mouseDown,this));OpenLayers.Event.observe(this.div,"dblclick",this.ignoreEvent);this.layersDiv=document.createElement("div");this.layersDiv.id=this.id+"_layersDiv";OpenLayers.Element.addClass(this.layersDiv,"layersDiv");this.baseLbl=document.createElement("div");this.baseLbl.innerHTML=OpenLayers.i18n("baseLayer");OpenLayers.Element.addClass(this.baseLbl,"baseLbl");this.baseLayersDiv=document.createElement("div");OpenLayers.Element.addClass(this.baseLayersDiv,"baseLayersDiv");this.dataLbl=document.createElement("div");this.dataLbl.innerHTML=OpenLayers.i18n("overlays");OpenLayers.Element.addClass(this.dataLbl,"dataLbl");this.dataLayersDiv=document.createElement("div");OpenLayers.Element.addClass(this.dataLayersDiv,"dataLayersDiv");if(this.ascending){this.layersDiv.appendChild(this.baseLbl);this.layersDiv.appendChild(this.baseLayersDiv);this.layersDiv.appendChild(this.dataLbl);this.layersDiv.appendChild(this.dataLayersDiv);}else{this.layersDiv.appendChild(this.dataLbl);this.layersDiv.appendChild(this.dataLayersDiv);this.layersDiv.appendChild(this.baseLbl);this.layersDiv.appendChild(this.baseLayersDiv);}
59714 this.div.appendChild(this.layersDiv);if(this.roundedCorner){OpenLayers.Rico.Corner.round(this.div,{corners:"tl bl",bgColor:"transparent",color:this.roundedCornerColor,blend:false});OpenLayers.Rico.Corner.changeOpacity(this.layersDiv,0.75);}
59715 var imgLocation=OpenLayers.Util.getImagesLocation();var sz=new OpenLayers.Size(18,18);var img=imgLocation+'layer-switcher-maximize.png';this.maximizeDiv=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MaximizeDiv",null,sz,img,"absolute");OpenLayers.Element.addClass(this.maximizeDiv,"maximizeDiv");this.maximizeDiv.style.display="none";OpenLayers.Event.observe(this.maximizeDiv,"click",OpenLayers.Function.bindAsEventListener(this.maximizeControl,this));this.div.appendChild(this.maximizeDiv);var img=imgLocation+'layer-switcher-minimize.png';var sz=new OpenLayers.Size(18,18);this.minimizeDiv=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MinimizeDiv",null,sz,img,"absolute");OpenLayers.Element.addClass(this.minimizeDiv,"minimizeDiv");this.minimizeDiv.style.display="none";OpenLayers.Event.observe(this.minimizeDiv,"click",OpenLayers.Function.bindAsEventListener(this.minimizeControl,this));this.div.appendChild(this.minimizeDiv);},ignoreEvent:function(evt){OpenLayers.Event.stop(evt);},mouseDown:function(evt){this.isMouseDown=true;this.ignoreEvent(evt);},mouseUp:function(evt){if(this.isMouseDown){this.isMouseDown=false;this.ignoreEvent(evt);}},CLASS_NAME:"OpenLayers.Control.LayerSwitcher"});OpenLayers.Control.MouseDefaults=OpenLayers.Class(OpenLayers.Control,{performedDrag:false,wheelObserver:null,initialize:function(){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){if(this.handler){this.handler.destroy();}
59716 this.handler=null;this.map.events.un({"click":this.defaultClick,"dblclick":this.defaultDblClick,"mousedown":this.defaultMouseDown,"mouseup":this.defaultMouseUp,"mousemove":this.defaultMouseMove,"mouseout":this.defaultMouseOut,scope:this});OpenLayers.Event.stopObserving(window,"DOMMouseScroll",this.wheelObserver);OpenLayers.Event.stopObserving(window,"mousewheel",this.wheelObserver);OpenLayers.Event.stopObserving(document,"mousewheel",this.wheelObserver);this.wheelObserver=null;OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){this.map.events.on({"click":this.defaultClick,"dblclick":this.defaultDblClick,"mousedown":this.defaultMouseDown,"mouseup":this.defaultMouseUp,"mousemove":this.defaultMouseMove,"mouseout":this.defaultMouseOut,scope:this});this.registerWheelEvents();},registerWheelEvents:function(){this.wheelObserver=OpenLayers.Function.bindAsEventListener(this.onWheelEvent,this);OpenLayers.Event.observe(window,"DOMMouseScroll",this.wheelObserver);OpenLayers.Event.observe(window,"mousewheel",this.wheelObserver);OpenLayers.Event.observe(document,"mousewheel",this.wheelObserver);},defaultClick:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59717 var notAfterDrag=!this.performedDrag;this.performedDrag=false;return notAfterDrag;},defaultDblClick:function(evt){var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom+1);OpenLayers.Event.stop(evt);return false;},defaultMouseDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59718 this.mouseDragStart=evt.xy.clone();this.performedDrag=false;if(evt.shiftKey){this.map.div.style.cursor="crosshair";this.zoomBox=OpenLayers.Util.createDiv('zoomBox',this.mouseDragStart,null,null,"absolute","2px solid red");this.zoomBox.style.backgroundColor="white";this.zoomBox.style.filter="alpha(opacity=50)";this.zoomBox.style.opacity="0.50";this.zoomBox.style.fontSize="1px";this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.viewPortDiv.appendChild(this.zoomBox);}
59719 document.onselectstart=OpenLayers.Function.False;OpenLayers.Event.stop(evt);},defaultMouseMove:function(evt){this.mousePosition=evt.xy.clone();if(this.mouseDragStart!=null){if(this.zoomBox){var deltaX=Math.abs(this.mouseDragStart.x-evt.xy.x);var deltaY=Math.abs(this.mouseDragStart.y-evt.xy.y);this.zoomBox.style.width=Math.max(1,deltaX)+"px";this.zoomBox.style.height=Math.max(1,deltaY)+"px";if(evt.xy.x<this.mouseDragStart.x){this.zoomBox.style.left=evt.xy.x+"px";}
59720 if(evt.xy.y<this.mouseDragStart.y){this.zoomBox.style.top=evt.xy.y+"px";}}else{var deltaX=this.mouseDragStart.x-evt.xy.x;var deltaY=this.mouseDragStart.y-evt.xy.y;var size=this.map.getSize();var newXY=new OpenLayers.Pixel(size.w/2+deltaX,size.h/2+deltaY);var newCenter=this.map.getLonLatFromViewPortPx(newXY);this.map.setCenter(newCenter,null,true);this.mouseDragStart=evt.xy.clone();this.map.div.style.cursor="move";}
59721 this.performedDrag=true;}},defaultMouseUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59722 if(this.zoomBox){this.zoomBoxEnd(evt);}else{if(this.performedDrag){this.map.setCenter(this.map.center);}}
59723 document.onselectstart=null;this.mouseDragStart=null;this.map.div.style.cursor="";},defaultMouseOut:function(evt){if(this.mouseDragStart!=null&&OpenLayers.Util.mouseLeft(evt,this.map.div)){if(this.zoomBox){this.removeZoomBox();}
59724 this.mouseDragStart=null;}},defaultWheelUp:function(evt){if(this.map.getZoom()<=this.map.getNumZoomLevels()){this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),this.map.getZoom()+1);}},defaultWheelDown:function(evt){if(this.map.getZoom()>0){this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),this.map.getZoom()-1);}},zoomBoxEnd:function(evt){if(this.mouseDragStart!=null){if(Math.abs(this.mouseDragStart.x-evt.xy.x)>5||Math.abs(this.mouseDragStart.y-evt.xy.y)>5){var start=this.map.getLonLatFromViewPortPx(this.mouseDragStart);var end=this.map.getLonLatFromViewPortPx(evt.xy);var top=Math.max(start.lat,end.lat);var bottom=Math.min(start.lat,end.lat);var left=Math.min(start.lon,end.lon);var right=Math.max(start.lon,end.lon);var bounds=new OpenLayers.Bounds(left,bottom,right,top);this.map.zoomToExtent(bounds);}else{var end=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(new OpenLayers.LonLat((end.lon),(end.lat)),this.map.getZoom()+1);}
59725 this.removeZoomBox();}},removeZoomBox:function(){this.map.viewPortDiv.removeChild(this.zoomBox);this.zoomBox=null;},onWheelEvent:function(e){var inMap=false;var elem=OpenLayers.Event.element(e);while(elem!=null){if(this.map&&elem==this.map.div){inMap=true;break;}
59726 elem=elem.parentNode;}
59727 if(inMap){var delta=0;if(!e){e=window.event;}
59728 if(e.wheelDelta){delta=e.wheelDelta/120;if(window.opera&&window.opera.version()<9.2){delta=-delta;}}else if(e.detail){delta=-e.detail/3;}
59729 if(delta){e.xy=this.mousePosition;if(delta<0){this.defaultWheelDown(e);}else{this.defaultWheelUp(e);}}
59730 OpenLayers.Event.stop(e);}},CLASS_NAME:"OpenLayers.Control.MouseDefaults"});OpenLayers.Control.MousePosition=OpenLayers.Class(OpenLayers.Control,{autoActivate:true,element:null,prefix:'',separator:', ',suffix:'',numDigits:5,granularity:10,emptyString:null,lastXy:null,displayProjection:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments);},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){this.map.events.register('mousemove',this,this.redraw);this.map.events.register('mouseout',this,this.reset);this.redraw();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.map.events.unregister('mousemove',this,this.redraw);this.map.events.unregister('mouseout',this,this.reset);this.element.innerHTML="";return true;}else{return false;}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.element){this.div.left="";this.div.top="";this.element=this.div;}
59731 return this.div;},redraw:function(evt){var lonLat;if(evt==null){this.reset();return;}else{if(this.lastXy==null||Math.abs(evt.xy.x-this.lastXy.x)>this.granularity||Math.abs(evt.xy.y-this.lastXy.y)>this.granularity)
59732 {this.lastXy=evt.xy;return;}
59733 lonLat=this.map.getLonLatFromPixel(evt.xy);if(!lonLat){return;}
59734 if(this.displayProjection){lonLat.transform(this.map.getProjectionObject(),this.displayProjection);}
59735 this.lastXy=evt.xy;}
59736 var newHtml=this.formatOutput(lonLat);if(newHtml!=this.element.innerHTML){this.element.innerHTML=newHtml;}},reset:function(evt){if(this.emptyString!=null){this.element.innerHTML=this.emptyString;}},formatOutput:function(lonLat){var digits=parseInt(this.numDigits);var newHtml=this.prefix+
59737 lonLat.lon.toFixed(digits)+
59738 this.separator+
59739 lonLat.lat.toFixed(digits)+
59740 this.suffix;return newHtml;},CLASS_NAME:"OpenLayers.Control.MousePosition"});OpenLayers.Control.Pan=OpenLayers.Class(OpenLayers.Control,{slideFactor:50,direction:null,type:OpenLayers.Control.TYPE_BUTTON,initialize:function(direction,options){this.direction=direction;this.CLASS_NAME+=this.direction;OpenLayers.Control.prototype.initialize.apply(this,[options]);},trigger:function(){switch(this.direction){case OpenLayers.Control.Pan.NORTH:this.map.pan(0,-this.slideFactor);break;case OpenLayers.Control.Pan.SOUTH:this.map.pan(0,this.slideFactor);break;case OpenLayers.Control.Pan.WEST:this.map.pan(-this.slideFactor,0);break;case OpenLayers.Control.Pan.EAST:this.map.pan(this.slideFactor,0);break;}},CLASS_NAME:"OpenLayers.Control.Pan"});OpenLayers.Control.Pan.NORTH="North";OpenLayers.Control.Pan.SOUTH="South";OpenLayers.Control.Pan.EAST="East";OpenLayers.Control.Pan.WEST="West";OpenLayers.Control.PanZoom=OpenLayers.Class(OpenLayers.Control,{slideFactor:50,slideRatio:null,buttons:null,position:null,initialize:function(options){this.position=new OpenLayers.Pixel(OpenLayers.Control.PanZoom.X,OpenLayers.Control.PanZoom.Y);OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this,arguments);this.removeButtons();this.buttons=null;this.position=null;},draw:function(px){OpenLayers.Control.prototype.draw.apply(this,arguments);px=this.position;this.buttons=[];var sz=new OpenLayers.Size(18,18);var centered=new OpenLayers.Pixel(px.x+sz.w/2,px.y);this._addButton("panup","north-mini.png",centered,sz);px.y=centered.y+sz.h;this._addButton("panleft","west-mini.png",px,sz);this._addButton("panright","east-mini.png",px.add(sz.w,0),sz);this._addButton("pandown","south-mini.png",centered.add(0,sz.h*2),sz);this._addButton("zoomin","zoom-plus-mini.png",centered.add(0,sz.h*3+5),sz);this._addButton("zoomworld","zoom-world-mini.png",centered.add(0,sz.h*4+5),sz);this._addButton("zoomout","zoom-minus-mini.png",centered.add(0,sz.h*5+5),sz);return this.div;},_addButton:function(id,img,xy,sz){var imgLocation=OpenLayers.Util.getImagesLocation()+img;var btn=OpenLayers.Util.createAlphaImageDiv(this.id+"_"+id,xy,sz,imgLocation,"absolute");this.div.appendChild(btn);OpenLayers.Event.observe(btn,"mousedown",OpenLayers.Function.bindAsEventListener(this.buttonDown,btn));OpenLayers.Event.observe(btn,"dblclick",OpenLayers.Function.bindAsEventListener(this.doubleClick,btn));OpenLayers.Event.observe(btn,"click",OpenLayers.Function.bindAsEventListener(this.doubleClick,btn));btn.action=id;btn.map=this.map;if(!this.slideRatio){var slideFactorPixels=this.slideFactor;var getSlideFactor=function(){return slideFactorPixels;};}else{var slideRatio=this.slideRatio;var getSlideFactor=function(dim){return this.map.getSize()[dim]*slideRatio;};}
59741 btn.getSlideFactor=getSlideFactor;this.buttons.push(btn);return btn;},_removeButton:function(btn){OpenLayers.Event.stopObservingElement(btn);btn.map=null;btn.getSlideFactor=null;this.div.removeChild(btn);OpenLayers.Util.removeItem(this.buttons,btn);},removeButtons:function(){for(var i=this.buttons.length-1;i>=0;--i){this._removeButton(this.buttons[i]);}},doubleClick:function(evt){OpenLayers.Event.stop(evt);return false;},buttonDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59742 switch(this.action){case"panup":this.map.pan(0,-this.getSlideFactor("h"));break;case"pandown":this.map.pan(0,this.getSlideFactor("h"));break;case"panleft":this.map.pan(-this.getSlideFactor("w"),0);break;case"panright":this.map.pan(this.getSlideFactor("w"),0);break;case"zoomin":this.map.zoomIn();break;case"zoomout":this.map.zoomOut();break;case"zoomworld":this.map.zoomToMaxExtent();break;}
59743 OpenLayers.Event.stop(evt);},CLASS_NAME:"OpenLayers.Control.PanZoom"});OpenLayers.Control.PanZoom.X=4;OpenLayers.Control.PanZoom.Y=4;OpenLayers.Control.Panel=OpenLayers.Class(OpenLayers.Control,{controls:null,autoActivate:true,defaultControl:null,saveState:false,activeState:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.controls=[];this.activeState={};},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this,arguments);for(var i=this.controls.length-1;i>=0;i--){if(this.controls[i].events){this.controls[i].events.un({"activate":this.redraw,"deactivate":this.redraw,scope:this});}
59744 OpenLayers.Event.stopObservingElement(this.controls[i].panel_div);this.controls[i].panel_div=null;}
59745 this.activeState=null;},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){var control;for(var i=0,len=this.controls.length;i<len;i++){control=this.controls[i];if(control===this.defaultControl||(this.saveState&&this.activeState[control.id])){control.activate();}}
59746 if(this.saveState===true){this.defaultControl=null;}
59747 this.redraw();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){var control;for(var i=0,len=this.controls.length;i<len;i++){control=this.controls[i];this.activeState[control.id]=control.deactivate();}
59748 return true;}else{return false;}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.addControlsToMap(this.controls);return this.div;},redraw:function(){if(this.div.children.length>0){for(var l=this.div.children.length,i=l-1;i>=0;i--){this.div.removeChild(this.div.children[i]);}}
59749 this.div.innerHTML="";if(this.active){for(var i=0,len=this.controls.length;i<len;i++){var element=this.controls[i].panel_div;if(this.controls[i].active){element.className=this.controls[i].displayClass+"ItemActive";}else{element.className=this.controls[i].displayClass+"ItemInactive";}
59750 this.div.appendChild(element);}}},activateControl:function(control){if(!this.active){return false;}
59751 if(control.type==OpenLayers.Control.TYPE_BUTTON){control.trigger();this.redraw();return;}
59752 if(control.type==OpenLayers.Control.TYPE_TOGGLE){if(control.active){control.deactivate();}else{control.activate();}
59753 this.redraw();return;}
59754 var c;for(var i=0,len=this.controls.length;i<len;i++){c=this.controls[i];if(c!=control&&(c.type===OpenLayers.Control.TYPE_TOOL||c.type==null)){c.deactivate();}}
59755 control.activate();},addControls:function(controls){if(!(controls instanceof Array)){controls=[controls];}
59756 this.controls=this.controls.concat(controls);for(var i=0,len=controls.length;i<len;i++){var element=document.createElement("div");controls[i].panel_div=element;if(controls[i].title!=""){controls[i].panel_div.title=controls[i].title;}
59757 OpenLayers.Event.observe(controls[i].panel_div,"click",OpenLayers.Function.bind(this.onClick,this,controls[i]));OpenLayers.Event.observe(controls[i].panel_div,"dblclick",OpenLayers.Function.bind(this.onDoubleClick,this,controls[i]));OpenLayers.Event.observe(controls[i].panel_div,"mousedown",OpenLayers.Function.bindAsEventListener(OpenLayers.Event.stop));}
59758 if(this.map){this.addControlsToMap(controls);this.redraw();}},addControlsToMap:function(controls){var control;for(var i=0,len=controls.length;i<len;i++){control=controls[i];if(control.autoActivate===true){control.autoActivate=false;this.map.addControl(control);control.autoActivate=true;}else{this.map.addControl(control);control.deactivate();}
59759 control.events.on({"activate":this.redraw,"deactivate":this.redraw,scope:this});}},onClick:function(ctrl,evt){OpenLayers.Event.stop(evt?evt:window.event);this.activateControl(ctrl);},onDoubleClick:function(ctrl,evt){OpenLayers.Event.stop(evt?evt:window.event);},getControlsBy:function(property,match){var test=(typeof match.test=="function");var found=OpenLayers.Array.filter(this.controls,function(item){return item[property]==match||(test&&match.test(item[property]));});return found;},getControlsByName:function(match){return this.getControlsBy("name",match);},getControlsByClass:function(match){return this.getControlsBy("CLASS_NAME",match);},CLASS_NAME:"OpenLayers.Control.Panel"});OpenLayers.Control.Scale=OpenLayers.Class(OpenLayers.Control,{element:null,geodesic:false,initialize:function(element,options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.element=OpenLayers.Util.getElement(element);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.element){this.element=document.createElement("div");this.div.appendChild(this.element);}
59760 this.map.events.register('moveend',this,this.updateScale);this.updateScale();return this.div;},updateScale:function(){var scale;if(this.geodesic===true){var units=this.map.getUnits();if(!units){return;}
59761 var inches=OpenLayers.INCHES_PER_UNIT;scale=(this.map.getGeodesicPixelSize().w||0.000001)*inches["km"]*OpenLayers.DOTS_PER_INCH;}else{scale=this.map.getScale();}
59762 if(!scale){return;}
59763 if(scale>=9500&&scale<=950000){scale=Math.round(scale/1000)+"K";}else if(scale>=950000){scale=Math.round(scale/1000000)+"M";}else{scale=Math.round(scale);}
59764 this.element.innerHTML=OpenLayers.i18n("scale",{'scaleDenom':scale});},CLASS_NAME:"OpenLayers.Control.Scale"});OpenLayers.Control.ScaleLine=OpenLayers.Class(OpenLayers.Control,{maxWidth:100,topOutUnits:"km",topInUnits:"m",bottomOutUnits:"mi",bottomInUnits:"ft",eTop:null,eBottom:null,geodesic:false,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.eTop){this.eTop=document.createElement("div");this.eTop.className=this.displayClass+"Top";var theLen=this.topInUnits.length;this.div.appendChild(this.eTop);if((this.topOutUnits=="")||(this.topInUnits=="")){this.eTop.style.visibility="hidden";}else{this.eTop.style.visibility="visible";}
59765 this.eBottom=document.createElement("div");this.eBottom.className=this.displayClass+"Bottom";this.div.appendChild(this.eBottom);if((this.bottomOutUnits=="")||(this.bottomInUnits=="")){this.eBottom.style.visibility="hidden";}else{this.eBottom.style.visibility="visible";}}
59766 this.map.events.register('moveend',this,this.update);this.update();return this.div;},getBarLen:function(maxLen){var digits=parseInt(Math.log(maxLen)/Math.log(10));var pow10=Math.pow(10,digits);var firstChar=parseInt(maxLen/pow10);var barLen;if(firstChar>5){barLen=5;}else if(firstChar>2){barLen=2;}else{barLen=1;}
59767 return barLen*pow10;},update:function(){var res=this.map.getResolution();if(!res){return;}
59768 var curMapUnits=this.map.getUnits();var inches=OpenLayers.INCHES_PER_UNIT;var maxSizeData=this.maxWidth*res*inches[curMapUnits];var geodesicRatio=1;if(this.geodesic===true){var maxSizeGeodesic=(this.map.getGeodesicPixelSize().w||0.000001)*this.maxWidth;var maxSizeKilometers=maxSizeData/inches["km"];geodesicRatio=maxSizeGeodesic/maxSizeKilometers;maxSizeData*=geodesicRatio;}
59769 var topUnits;var bottomUnits;if(maxSizeData>100000){topUnits=this.topOutUnits;bottomUnits=this.bottomOutUnits;}else{topUnits=this.topInUnits;bottomUnits=this.bottomInUnits;}
59770 var topMax=maxSizeData/inches[topUnits];var bottomMax=maxSizeData/inches[bottomUnits];var topRounded=this.getBarLen(topMax);var bottomRounded=this.getBarLen(bottomMax);topMax=topRounded/inches[curMapUnits]*inches[topUnits];bottomMax=bottomRounded/inches[curMapUnits]*inches[bottomUnits];var topPx=topMax/res/geodesicRatio;var bottomPx=bottomMax/res/geodesicRatio;if(this.eBottom.style.visibility=="visible"){this.eBottom.style.width=Math.round(bottomPx)+"px";this.eBottom.innerHTML=bottomRounded+" "+bottomUnits;}
59771 if(this.eTop.style.visibility=="visible"){this.eTop.style.width=Math.round(topPx)+"px";this.eTop.innerHTML=topRounded+" "+topUnits;}},CLASS_NAME:"OpenLayers.Control.ScaleLine"});OpenLayers.Control.ZoomIn=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){this.map.zoomIn();},CLASS_NAME:"OpenLayers.Control.ZoomIn"});OpenLayers.Control.ZoomOut=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){this.map.zoomOut();},CLASS_NAME:"OpenLayers.Control.ZoomOut"});OpenLayers.Control.ZoomToMaxExtent=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){if(this.map){this.map.zoomToMaxExtent();}},CLASS_NAME:"OpenLayers.Control.ZoomToMaxExtent"});OpenLayers.Event={observers:false,KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,element:function(event){return event.target||event.srcElement;},isLeftClick:function(event){return(((event.which)&&(event.which==1))||((event.button)&&(event.button==1)));},isRightClick:function(event){return(((event.which)&&(event.which==3))||((event.button)&&(event.button==2)));},stop:function(event,allowDefault){if(!allowDefault){if(event.preventDefault){event.preventDefault();}else{event.returnValue=false;}}
59772 if(event.stopPropagation){event.stopPropagation();}else{event.cancelBubble=true;}},findElement:function(event,tagName){var element=OpenLayers.Event.element(event);while(element.parentNode&&(!element.tagName||(element.tagName.toUpperCase()!=tagName.toUpperCase()))){element=element.parentNode;}
59773 return element;},observe:function(elementParam,name,observer,useCapture){var element=OpenLayers.Util.getElement(elementParam);useCapture=useCapture||false;if(name=='keypress'&&(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||element.attachEvent)){name='keydown';}
59774 if(!this.observers){this.observers={};}
59775 if(!element._eventCacheID){var idPrefix="eventCacheID_";if(element.id){idPrefix=element.id+"_"+idPrefix;}
59776 element._eventCacheID=OpenLayers.Util.createUniqueID(idPrefix);}
59777 var cacheID=element._eventCacheID;if(!this.observers[cacheID]){this.observers[cacheID]=[];}
59778 this.observers[cacheID].push({'element':element,'name':name,'observer':observer,'useCapture':useCapture});if(element.addEventListener){element.addEventListener(name,observer,useCapture);}else if(element.attachEvent){element.attachEvent('on'+name,observer);}},stopObservingElement:function(elementParam){var element=OpenLayers.Util.getElement(elementParam);var cacheID=element._eventCacheID;this._removeElementObservers(OpenLayers.Event.observers[cacheID]);},_removeElementObservers:function(elementObservers){if(elementObservers){for(var i=elementObservers.length-1;i>=0;i--){var entry=elementObservers[i];var args=new Array(entry.element,entry.name,entry.observer,entry.useCapture);var removed=OpenLayers.Event.stopObserving.apply(this,args);}}},stopObserving:function(elementParam,name,observer,useCapture){useCapture=useCapture||false;var element=OpenLayers.Util.getElement(elementParam);var cacheID=element._eventCacheID;if(name=='keypress'){if(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||element.detachEvent){name='keydown';}}
59779 var foundEntry=false;var elementObservers=OpenLayers.Event.observers[cacheID];if(elementObservers){var i=0;while(!foundEntry&&i<elementObservers.length){var cacheEntry=elementObservers[i];if((cacheEntry.name==name)&&(cacheEntry.observer==observer)&&(cacheEntry.useCapture==useCapture)){elementObservers.splice(i,1);if(elementObservers.length==0){delete OpenLayers.Event.observers[cacheID];}
59780 foundEntry=true;break;}
59781 i++;}}
59782 if(foundEntry){if(element.removeEventListener){element.removeEventListener(name,observer,useCapture);}else if(element&&element.detachEvent){element.detachEvent('on'+name,observer);}}
59783 return foundEntry;},unloadCache:function(){if(OpenLayers.Event&&OpenLayers.Event.observers){for(var cacheID in OpenLayers.Event.observers){var elementObservers=OpenLayers.Event.observers[cacheID];OpenLayers.Event._removeElementObservers.apply(this,[elementObservers]);}
59784 OpenLayers.Event.observers=false;}},CLASS_NAME:"OpenLayers.Event"};OpenLayers.Event.observe(window,'unload',OpenLayers.Event.unloadCache,false);if(window.Event){OpenLayers.Util.applyDefaults(window.Event,OpenLayers.Event);}else{var Event=OpenLayers.Event;}
59785 OpenLayers.Events=OpenLayers.Class({BROWSER_EVENTS:["mouseover","mouseout","mousedown","mouseup","mousemove","click","dblclick","rightclick","dblrightclick","resize","focus","blur"],listeners:null,object:null,element:null,eventTypes:null,eventHandler:null,fallThrough:null,includeXY:false,clearMouseListener:null,initialize:function(object,element,eventTypes,fallThrough,options){OpenLayers.Util.extend(this,options);this.object=object;this.fallThrough=fallThrough;this.listeners={};this.eventHandler=OpenLayers.Function.bindAsEventListener(this.handleBrowserEvent,this);this.clearMouseListener=OpenLayers.Function.bind(this.clearMouseCache,this);this.eventTypes=[];if(eventTypes!=null){for(var i=0,len=eventTypes.length;i<len;i++){this.addEventType(eventTypes[i]);}}
59786 if(element!=null){this.attachToElement(element);}},destroy:function(){if(this.element){OpenLayers.Event.stopObservingElement(this.element);if(this.element.hasScrollEvent){OpenLayers.Event.stopObserving(window,"scroll",this.clearMouseListener);}}
59787 this.element=null;this.listeners=null;this.object=null;this.eventTypes=null;this.fallThrough=null;this.eventHandler=null;},addEventType:function(eventName){if(!this.listeners[eventName]){this.eventTypes.push(eventName);this.listeners[eventName]=[];}},attachToElement:function(element){if(this.element){OpenLayers.Event.stopObservingElement(this.element);}
59788 this.element=element;for(var i=0,len=this.BROWSER_EVENTS.length;i<len;i++){var eventType=this.BROWSER_EVENTS[i];this.addEventType(eventType);OpenLayers.Event.observe(element,eventType,this.eventHandler);}
59789 OpenLayers.Event.observe(element,"dragstart",OpenLayers.Event.stop);},on:function(object){for(var type in object){if(type!="scope"){this.register(type,object.scope,object[type]);}}},register:function(type,obj,func){if((func!=null)&&(OpenLayers.Util.indexOf(this.eventTypes,type)!=-1)){if(obj==null){obj=this.object;}
59790 var listeners=this.listeners[type];listeners.push({obj:obj,func:func});}},registerPriority:function(type,obj,func){if(func!=null){if(obj==null){obj=this.object;}
59791 var listeners=this.listeners[type];if(listeners!=null){listeners.unshift({obj:obj,func:func});}}},un:function(object){for(var type in object){if(type!="scope"){this.unregister(type,object.scope,object[type]);}}},unregister:function(type,obj,func){if(obj==null){obj=this.object;}
59792 var listeners=this.listeners[type];if(listeners!=null){for(var i=0,len=listeners.length;i<len;i++){if(listeners[i].obj==obj&&listeners[i].func==func){listeners.splice(i,1);break;}}}},remove:function(type){if(this.listeners[type]!=null){this.listeners[type]=[];}},triggerEvent:function(type,evt){var listeners=this.listeners[type];if(!listeners||listeners.length==0){return;}
59793 if(evt==null){evt={};}
59794 evt.object=this.object;evt.element=this.element;if(!evt.type){evt.type=type;}
59795 var listeners=listeners.slice(),continueChain;for(var i=0,len=listeners.length;i<len;i++){var callback=listeners[i];continueChain=callback.func.apply(callback.obj,[evt]);if((continueChain!=undefined)&&(continueChain==false)){break;}}
59796 if(!this.fallThrough){OpenLayers.Event.stop(evt,true);}
59797 return continueChain;},handleBrowserEvent:function(evt){if(this.includeXY){evt.xy=this.getMousePosition(evt);}
59798 this.triggerEvent(evt.type,evt);},clearMouseCache:function(){this.element.scrolls=null;this.element.lefttop=null;this.element.offsets=null;},getMousePosition:function(evt){if(!this.includeXY){this.clearMouseCache();}else if(!this.element.hasScrollEvent){OpenLayers.Event.observe(window,"scroll",this.clearMouseListener);this.element.hasScrollEvent=true;}
59799 if(!this.element.scrolls){this.element.scrolls=[(document.documentElement.scrollLeft||document.body.scrollLeft),(document.documentElement.scrollTop||document.body.scrollTop)];}
59800 if(!this.element.lefttop){this.element.lefttop=[(document.documentElement.clientLeft||0),(document.documentElement.clientTop||0)];}
59801 if(!this.element.offsets){this.element.offsets=OpenLayers.Util.pagePosition(this.element);this.element.offsets[0]+=this.element.scrolls[0];this.element.offsets[1]+=this.element.scrolls[1];}
59802 return new OpenLayers.Pixel((evt.clientX+this.element.scrolls[0])-this.element.offsets[0]
59803 -this.element.lefttop[0],(evt.clientY+this.element.scrolls[1])-this.element.offsets[1]
59804 -this.element.lefttop[1]);},CLASS_NAME:"OpenLayers.Events"});OpenLayers.Format=OpenLayers.Class({options:null,externalProjection:null,internalProjection:null,data:null,keepData:false,initialize:function(options){OpenLayers.Util.extend(this,options);this.options=options;},destroy:function(){},read:function(data){OpenLayers.Console.userError(OpenLayers.i18n("readNotImplemented"));},write:function(object){OpenLayers.Console.userError(OpenLayers.i18n("writeNotImplemented"));},CLASS_NAME:"OpenLayers.Format"});OpenLayers.Lang["ar"]=OpenLayers.Util.applyDefaults({'permalink':"وصلة دائمة",'baseLayer':"الطبقة الاساسية",'readNotImplemented':"القراءة غير محققة.",'writeNotImplemented':"الكتابة غير محققة",'errorLoadingGML':"خطأ عند تحميل الملف جي ام ال ${url}",'scale':"النسبة = 1 : ${scaleDenom}",'W':"غ",'E':"شر",'N':"شم",'S':"ج"});OpenLayers.Lang["be-tarask"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Неапрацаваны вынік запыту ${statusText}",'permalink':"Сталая спасылка",'overlays':"Слаі",'baseLayer':"Базавы слой",'sameProjection':"Аглядная мапа працуе толькі калі яна мае тую ж праекцыю, што і асноўная мапа",'readNotImplemented':"Функцыянальнасьць чытаньня ня створаная.",'writeNotImplemented':"Функцыянальнасьць запісу ня створаная.",'noFID':"Немагчыма абнавіць магчымасьць, для якога не існуе FID.",'errorLoadingGML':"Памылка загрузкі файла GML ${url}",'browserNotSupported':"Ваш браўзэр не падтрымлівае вэктарную графіку. У цяперашні момант падтрымліваюцца: ${renderers}",'componentShouldBe':"addFeatures : кампанэнт павінен быць ${geomType}",'getFeatureError':"getFeatureFromEvent выкліканы для слоя бяз рэндэру. Звычайна гэта азначае, што Вы зьнішчылі слой, але пакінулі зьвязаны зь ім апрацоўшчык.",'minZoomLevelError':"Уласьцівасьць minZoomLevel прызначана толькі для выкарыстаньня са слаямі вытворнымі ад FixedZoomLevels. Тое, што  гэты wfs-слой правяраецца на minZoomLevel — рэха прошлага. Але мы ня можам выдаліць гэтую магчымасьць, таму што ад яе залежаць некаторыя заснаваныя на OL дастасаваньні. Тым ня менш, праверка minZoomLevel будзе выдаленая ў вэрсіі 3.0. Калі ласка, выкарыстоўваеце замест яе ўстаноўкі мінімальнага/максымальнага памераў, як апісана тут: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-транзакцыя: ПОСЬПЕХ ${response}",'commitFailed':"WFS-транзакцыя: ПАМЫЛКА ${response}",'googleWarning':"Не атрымалася загрузіць слой Google. \x3cbr\x3e\x3cbr\x3eКаб пазбавіцца гэтага паведамленьня, выберыце новы базавы слой у сьпісе ў верхнім правым куце.\x3cbr\x3e\x3cbr\x3e Хутчэй за ўсё, прычына ў тым, што скрыпт бібліятэкі Google Maps ня быў уключаныя альбо не ўтрымлівае слушны API-ключ для Вашага сайта.\x3cbr\x3e\x3cbr\x3eРаспрацоўшчыкам: Для таго, каб даведацца як зрабіць так, каб усё працавала, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eнацісьніце тут\x3c/a\x3e",'getLayerWarning':"Немагчыма загрузіць слой ${layerType}.\x3cbr\x3e\x3cbr\x3eКаб пазбавіцца гэтага паведамленьня, выберыце новы базавы слой у сьпісе ў верхнім правым куце.\x3cbr\x3e\x3cbr\x3eХутчэй за ўсё, прычына ў тым, што скрыпт бібліятэкі ${layerLib} ня быў слушна ўключаны.\x3cbr\x3e\x3cbr\x3eРаспрацоўшчыкам: Для таго, каб даведацца як зрабіць так, каб усё працавала, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eнацісьніце тут\x3c/a\x3e",'scale':"Маштаб = 1 : ${scaleDenom}",'W':"З",'E':"У",'N':"Пн",'S':"Пд",'layerAlreadyAdded':"Вы паспрабавалі дадаць слой ${layerName} на мапу, але ён ужо дададзены",'reprojectDeprecated':"Вы выкарыстоўваеце ўстаноўку \'reproject\' для слоя ${layerName}. Гэтая ўстаноўка зьяўляецца састарэлай: яна выкарыстоўвалася для падтрымкі паказу зьвестак на камэрцыйных базавых мапах, але гэта функцыя цяпер рэалізаваная ў убудаванай падтрымцы сфэрычнай праекцыі Мэркатара. Дадатковая інфармацыя ёсьць на http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Гэты мэтад састарэлы і будзе выдалены ў вэрсіі 3.0. Калі ласка, замест яго выкарыстоўвайце ${newMethod}.",'boundsAddError':"Вам неабходна падаць абодва значэньні x і y для функцыі складаньня.",'lonlatAddError':"Вам неабходна падаць абодва значэньні lon і lat для функцыі складаньня.",'pixelAddError':"Вам неабходна падаць абодва значэньні x і y для функцыі складаньня.",'unsupportedGeometryType':"Тып геамэтрыі не падтрымліваецца: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: верагодна элемэнт з ідэнтыфікатарам ${elemId} займае няслушнае месца.",'filterEvaluateNotImplemented':"evaluate не рэалізаваны для гэтага тыпу фільтру."});OpenLayers.Lang["bg"]=OpenLayers.Util.applyDefaults({'permalink':"Постоянна препратка",'baseLayer':"Основен слой",'errorLoadingGML':"Грешка при зареждане на GML файл ${url}",'scale':"Мащаб = 1 : ${scaleDenom}",'layerAlreadyAdded':"Опитахте да добавите слой ${layerName} в картата, но той вече е добавен",'methodDeprecated':"Този метод е остарял и ще бъде премахват в 3.0. Вместо него използвайте ${newMethod}."});OpenLayers.Lang["br"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Distro evel reked anveret ${statusText}",'permalink':"Peurliamm",'overlays':"Gwiskadoù",'baseLayer':"Gwiskad diazez",'sameProjection':"Ne\'z ar gartenn lec\'hiañ en-dro nemet pa vez heñvel ar banndres anezhi ha hini ar gartenn bennañ",'readNotImplemented':"N\'eo ket emplementet al lenn.",'writeNotImplemented':"N\'eo ket emplementet ar skrivañ.",'noFID':"N\'haller ket hizivaat un elfenn ma n\'eus ket a niverenn-anaout (FID) eviti.",'errorLoadingGML':"Fazi e-ser kargañ ar restr GML ${url}",'browserNotSupported':"N\'eo ket skoret an daskor vektorel gant ho merdeer. Setu aze an daskorerioù skoret evit ar poent :\n${renderers}",'componentShouldBe':"addFeatures : bez\' e tlefe ar parzh besañ eus ar seurt ${geomType}",'getFeatureError':"Galvet eo bet getFeatureFromEvent called war ur gwiskad hep daskorer. Kement-se a dalvez ez eus bet freuzet ur gwiskad hag hoc\'h eus miret un embreger bennak stag outañ.",'minZoomLevelError':"Ne zleer implijout ar perzh minZoomLevel nemet evit gwiskadoù FixedZoomLevels-descendent. Ar fed ma wiria ar gwiskad WHS-se hag-eñ ez eus eus minZoomLevel zo un aspadenn gozh. Koulskoude n\'omp ket evit e ziverkañ kuit da derriñ arloadoù diazezet war OL a c\'hallfe bezañ stag outañ. Setu perak eo dispredet -- Lamet kuit e vo ar gwiriañ minZoomLevel a-is er stumm 3.0. Ober gant an arventennoù bihanañ/brasañ evel deskrivet amañ e plas : http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Treuzgread WFS : MAT EO ${response}",'commitFailed':"Treuzgread WFS Transaction: C\'HWITET ${response}",'googleWarning':"N\'eus ket bet gallet kargañ ar gwiskad Google ent reizh.\x3cbr\x3e\x3cbr\x3eEvit en em zizober eus ar c\'hemenn-mañ, dibabit ur BaseLayer nevez en diuzer gwiskadoù er c\'horn dehoù el laez.\x3cbr\x3e\x3cbr\x3eSur a-walc\'h eo peogwir n\'eo ket bet ensoc\'het levraoueg Google Maps pe neuze ne glot ket an alc\'hwez API gant ho lec\'hienn.\x3cbr\x3e\x3cbr\x3eDiorroerien : Evit reizhañ an dra-se, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclick here\x3c/a\x3e",'getLayerWarning':"N\'haller ket kargañ ar gwiskad ${layerType} ent reizh.\x3cbr\x3e\x3cbr\x3eEvit en em zizober eus ar c\'hemenn-mañ, dibabit ur BaseLayer nevez en diuzer gwiskadoù er c\'horn dehoù el laez.\x3cbr\x3e\x3cbr\x3eSur a-walc\'h eo peogwir n\'eo ket bet ensoc\'het mat al levraoueg ${layerLib}.\x3cbr\x3e\x3cbr\x3eDiorroerien : Evit gouzout penaos reizhañ an dra-se, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclick here\x3c/a\x3e",'scale':"Skeul = 1 : ${scaleDenom}",'W':"K",'E':"R",'N':"N",'S':"S",'layerAlreadyAdded':"Klasket hoc\'h eus ouzhpennañ ar gwiskad : ${layerName} d\'ar gartenn, met ouzhpennet e oa bet c\'hoazh",'reprojectDeprecated':"Emaoc\'h oc\'h implijout an dibarzh \'reproject\' war ar gwiskad ${layerName}. Dispredet eo an dibarzh-mañ : bet eo hag e talveze da ziskwel roadennoù war-c\'horre kartennoù diazez kenwerzhel, un dra hag a c\'haller ober bremañ gant an arc\'hwel dre skor banndres boullek Mercator. Muioc\'h a ditouroù a c\'haller da gaout war http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Dispredet eo an daore-se ha tennet e vo kuit eus ar stumm 3.0. Grit gant ${newMethod} e plas.",'boundsAddError':"Rekis eo tremen an div dalvoudenn x ha y d\'an arc\'hwel add.",'lonlatAddError':"Rekis eo tremen an div dalvoudenn hedred ha ledred d\'an arc\'hwel add.",'pixelAddError':"Rekis eo tremen an div dalvoudenn x ha y d\'an arc\'hwel add.",'unsupportedGeometryType':"Seurt mentoniezh anskoret : ${geomType}",'pagePositionFailed':"C\'hwitet eo OpenLayers.Util.pagePosition : marteze emañ lec\'hiet fall an elfenn id ${elemId}.",'filterEvaluateNotImplemented':"N\'eo ket bet emplementet ar priziañ evit seurt siloù c\'hoazh."});OpenLayers.Lang["el"]=OpenLayers.Util.applyDefaults({'scale':"Κλίμακα ~ 1 : ${scaleDenom}"});OpenLayers.Lang.en={'unhandledRequest':"Unhandled request return ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Base Layer",'sameProjection':"The overview map only works when it is in the same projection as the main map",'readNotImplemented':"Read not implemented.",'writeNotImplemented':"Write not implemented.",'noFID':"Can't update a feature for which there is no FID.",'errorLoadingGML':"Error in loading GML file ${url}",'browserNotSupported':"Your browser does not support vector rendering. Currently supported renderers are:\n${renderers}",'componentShouldBe':"addFeatures : component should be an ${geomType}",'getFeatureError':"getFeatureFromEvent called on layer with no renderer. This usually means you "+"destroyed a layer, but not some handler which is associated with it.",'minZoomLevelError':"The minZoomLevel property is only intended for use "+"with the FixedZoomLevels-descendent layers. That this "+"wfs layer checks for minZoomLevel is a relic of the"+"past. We cannot, however, remove it without possibly "+"breaking OL based applications that may depend on it."+" Therefore we are deprecating it -- the minZoomLevel "+"check below will be removed at 3.0. Please instead "+"use min/max resolution setting as described here: "+"http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS Transaction: SUCCESS ${response}",'commitFailed':"WFS Transaction: FAILED ${response}",'googleWarning':"The Google Layer was unable to load correctly.<br><br>"+"To get rid of this message, select a new BaseLayer "+"in the layer switcher in the upper-right corner.<br><br>"+"Most likely, this is because the Google Maps library "+"script was either not included, or does not contain the "+"correct API key for your site.<br><br>"+"Developers: For help getting this working correctly, "+"<a href='http://trac.openlayers.org/wiki/Google' "+"target='_blank'>click here</a>",'getLayerWarning':"The ${layerType} Layer was unable to load correctly.<br><br>"+"To get rid of this message, select a new BaseLayer "+"in the layer switcher in the upper-right corner.<br><br>"+"Most likely, this is because the ${layerLib} library "+"script was not correctly included.<br><br>"+"Developers: For help getting this working correctly, "+"<a href='http://trac.openlayers.org/wiki/${layerLib}' "+"target='_blank'>click here</a>",'scale':"Scale = 1 : ${scaleDenom}",'W':'W','E':'E','N':'N','S':'S','graticule':'Graticule','layerAlreadyAdded':"You tried to add the layer: ${layerName} to the map, but it has already been added",'reprojectDeprecated':"You are using the 'reproject' option "+"on the ${layerName} layer. This option is deprecated: "+"its use was designed to support displaying data over commercial "+"basemaps, but that functionality should now be achieved by using "+"Spherical Mercator support. More information is available from "+"http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"This method has been deprecated and will be removed in 3.0. "+"Please use ${newMethod} instead.",'boundsAddError':"You must pass both x and y values to the add function.",'lonlatAddError':"You must pass both lon and lat values to the add function.",'pixelAddError':"You must pass both x and y values to the add function.",'unsupportedGeometryType':"Unsupported geometry type: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: element with id ${elemId} may be misplaced.",'filterEvaluateNotImplemented':"evaluate is not implemented for this filter type.",'end':''};OpenLayers.Lang["fi"]=OpenLayers.Util.applyDefaults({'permalink':"Ikilinkki",'overlays':"Kerrokset",'baseLayer':"Peruskerros",'sameProjection':"Yleiskuvakarttaa voi käyttää vain, kun sillä on sama projektio kuin pääkartalla.",'W':"L",'E':"I",'N':"P",'S':"E"});OpenLayers.Lang["fur"]=OpenLayers.Util.applyDefaults({'permalink':"Leam Permanent",'overlays':"Livei parsore",'baseLayer':"Livel di base",'browserNotSupported':"Il to sgarfadôr nol supuarte la renderizazion vetoriâl. Al moment a son supuartâts:\n${renderers}",'scale':"Scjale = 1 : ${scaleDenom}",'W':"O",'E':"E",'N':"N",'S':"S"});OpenLayers.Lang["gl"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Solicitude non xerada; a resposta foi: ${statusText}",'permalink':"Ligazón permanente",'overlays':"Capas superpostas",'baseLayer':"Capa base",'sameProjection':"A vista xeral do mapa só funciona cando está na mesma proxección có mapa principal",'readNotImplemented':"Lectura non implementada.",'writeNotImplemented':"Escritura non implementada.",'noFID':"Non se pode actualizar a funcionalidade para a que non hai FID.",'errorLoadingGML':"Erro ao cargar o ficheiro GML ${url}",'browserNotSupported':"O seu navegador non soporta a renderización de vectores. Os renderizadores soportados actualmente son:\n${renderers}",'componentShouldBe':"addFeatures: o compoñente debera ser de tipo ${geomType}",'getFeatureError':"getFeatureFromEvent ten sido chamado a unha capa sen renderizador. Isto normalmente significa que destruíu unha capa, mais non o executador que está asociado con ela.",'minZoomLevelError':"A propiedade minZoomLevel é só para uso conxuntamente coas capas FixedZoomLevels-descendent. O feito de que esa capa wfs verifique o minZoomLevel é unha reliquia do pasado. Non podemos, con todo, eliminala sen a posibilidade de non romper as aplicacións baseadas en OL que poidan depender dela. Por iso a estamos deixando obsoleta (a comprobación minZoomLevel de embaixo será eliminada na versión 3.0). Por favor, no canto diso use o axuste de resolución mín/máx tal e como está descrito aquí: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transacción WFS: ÉXITO ${response}",'commitFailed':"Transacción WFS: FALLIDA ${response}",'googleWarning':"A capa do Google non puido cargarse correctamente.\x3cbr\x3e\x3cbr\x3ePara evitar esta mensaxe, escolla unha nova capa base no seleccionador de capas na marxe superior dereita.\x3cbr\x3e\x3cbr\x3eProbablemente, isto acontece porque a escritura da libraría do Google Maps ou ben non foi incluída ou ben non contén a clave API correcta para o seu sitio.\x3cbr\x3e\x3cbr\x3eDesenvolvedores: para axudar a facer funcionar isto correctamente, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3epremede aquí\x3c/a\x3e",'getLayerWarning':"A capa ${layerType} foi incapaz de cargarse correctamente.\x3cbr\x3e\x3cbr\x3ePara evitar esta mensaxe, escolla unha nova capa base no seleccionador de capas na marxe superior dereita.\x3cbr\x3e\x3cbr\x3eProbablemente, isto acontece porque a escritura da libraría ${layerLib} non foi ben incluída.\x3cbr\x3e\x3cbr\x3eDesenvolvedores: para axudar a facer funcionar isto correctamente, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3epremede aquí\x3c/a\x3e",'scale':"Escala = 1 : ${scaleDenom}",'W':"O",'E':"L",'N':"N",'S':"S",'layerAlreadyAdded':"Intentou engadir a capa: ${layerName} ao mapa, pero xa fora engadida",'reprojectDeprecated':"Está usando a opción \"reproject\" na capa ${layerName}. Esta opción está obsoleta: o seu uso foi deseñado para a visualización de datos sobre mapas base comerciais, pero esta funcionalidade debera agora ser obtida utilizando a proxección Spherical Mercator. Hai dispoñible máis información en http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Este método está obsoleto e será eliminado na versión 3.0. Por favor, no canto deste use ${newMethod}.",'boundsAddError':"Debe achegar os valores x e y á función add.",'lonlatAddError':"Debe achegar tanto o valor lon coma o lat á función add.",'pixelAddError':"Debe achegar os valores x e y á función add.",'unsupportedGeometryType':"Tipo xeométrico non soportado: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition fallou: o elemento con id ${elemId} pode non estar na súa posición.",'filterEvaluateNotImplemented':"avaliar non está implementado para este tipo de filtro."});OpenLayers.Lang["gsw"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nit behandleti Aafrogsruckmäldig ${statusText}",'permalink':"Permalink",'overlays':"Iberlagerige",'baseLayer':"Grundcharte",'sameProjection':"D Ibersichts-Charte funktioniert nume, wänn si di glych Projäktion brucht wie d Hauptcharte",'readNotImplemented':"Läse nit implementiert.",'writeNotImplemented':"Schrybe nit implementiert.",'noFID':"E Feature, wu s kei FID derfir git, cha nit aktualisiert wäre.",'errorLoadingGML':"Fähler bim Lade vu dr GML-Datei ${url}",'browserNotSupported':"Dyy Browser unterstitzt kei Vektordarstellig. Aktuäll unterstitzti Renderer:\n${renderers}",'componentShouldBe':"addFeatures : Komponänt sott dr Typ ${geomType} syy",'getFeatureError':"getFeatureFromEvent isch uf eme Layer ohni Renderer ufgruefe wore. Des heisst normalerwys, ass Du e Layer kaputt gmacht hesch, aber nit dr Handler, wu derzue ghert.",'minZoomLevelError':"D minZoomLevel-Eigeschaft isch nume dänk fir d Layer, wu vu dr FixedZoomLevels abstamme. Ass dää wfs-Layer minZoomLevel prieft, scih e Relikt us dr Vergangeheit. Mir chenne s aber nit ändere ohni OL_basierti Aawändige villicht kaputt gehn, wu dervu abhänge.  Us däm Grund het die Funktion d Eigeschaft \'deprecated\' iberchuu. D minZoomLevel-Priefig unte wird in dr Version 3.0 usegnuu. Bitte verwänd statt däm e min/max-Uflesig wie s do bschriben isch: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-Transaktion: ERFOLGRYCH ${response}",'commitFailed':"WFS-Transaktion: FÄHLGSCHLAA ${response}",'googleWarning':"Dr Google-Layer het nit korräkt chenne glade wäre.\x3cbr\x3e\x3cbr\x3eGo die Mäldig nimi z kriege, wehl e andere Hintergrundlayer us em LayerSwitcher im rächte obere Ecke.\x3cbr\x3e\x3cbr\x3eDää Fähler git s seli hyfig, wel s Skript vu dr Google-Maps-Bibliothek nit yybunde woren isch oder wel s kei giltige API-Schlissel fir Dyy URL din het.\x3cbr\x3e\x3cbr\x3eEntwickler: Fir Hilf zum korräkte Yybinde vum Google-Layer \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3edoo drucke\x3c/a\x3e",'getLayerWarning':"Dr ${layerType}-Layer het nit korräkt chenne glade wäre.\x3cbr\x3e\x3cbr\x3eGo die Mäldig nimi z kriege, wehl e andere Hintergrundlayer us em LayerSwitcher im rächte obere Ecke.\x3cbr\x3e\x3cbr\x3eDää Fähler git s seli hyfig, wel s Skript vu dr \'${layerLib}\'-Bibliothek nit yybunde woren isch oder wel s kei giltige API-Schlissel fir Dyy URL din het.\x3cbr\x3e\x3cbr\x3eEntwickler: Fir Hilf zum korräkte Yybinde vu Layer \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3edoo drucke\x3c/a\x3e",'scale':"Maßstab = 1 : ${scaleDenom}",'W':"W",'E':"O",'N':"N",'S':"S",'layerAlreadyAdded':"Du hesch versuecht dää Layer in d Charte yyzfiege: ${layerName}, aber är isch schoi yygfiegt",'reprojectDeprecated':"Du bruchsch d \'reproject\'-Option bim ${layerName}-Layer. Die Option isch nimi giltig: si isch aagleit wore go   Date iber kommerziälli Grundcharte lege, aber des sott mer jetz mache mit dr Unterstitzig vu Spherical Mercator. Meh Informatione git s uf http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Die Methode isch veraltet un wird us dr Version 3.0 usegnuu. Bitte verwäbnd statt däm ${newMethod}.",'boundsAddError':"Du muesch e x-Wärt un e y-Wärt yygee bi dr Zuefieg-Funktion",'lonlatAddError':"Du meusch e Lengi- un e Breiti-Grad yygee bi dr Zuefieg-Funktion.",'pixelAddError':"Du muesch x- un y-Wärt aagee bi dr Zuefieg-Funktion.",'unsupportedGeometryType':"Nit unterstitze Geometrii-Typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition fählgschlaa: Elemänt mit ID ${elemId} isch villicht falsch gsetzt.",'filterEvaluateNotImplemented':"evaluiere isch nit implemäntiert in däm Filtertyp."});OpenLayers.Lang["hr"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nepodržani zahtjev ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Osnovna karta",'sameProjection':"Pregledna karta radi jedino kao je u istoj projekciji kao i glava karta",'readNotImplemented':"Čitanje nije implementirano.",'writeNotImplemented':"Pisanje nije implementirano.",'noFID':"Ne mogu ažurirati značajku za koju ne postoji FID.",'errorLoadingGML':"Greška u učitavanju GML datoteke ${url}",'browserNotSupported':"Vaš preglednik ne podržava vektorsko renderiranje. Trenutno podržani rendereri su: ${renderers}",'componentShouldBe':"addFeatures : komponenta bi trebala biti ${geomType}",'getFeatureError':"getFeatureFromEvent je pozvao Layer bez renderera. Ovo obično znači da ste uništiili Layer, a ne neki Handler koji je povezan s njim.",'commitSuccess':"WFS Transakcija: USPJEŠNA ${response}",'commitFailed':"WFS Transakcija: NEUSPJEŠNA ${response}",'scale':"Mjerilo = 1 : ${scaleDenom}",'layerAlreadyAdded':"Pokušali ste dodati layer:  ${layerName} na kartu, ali je već dodan",'methodDeprecated':"Ova metoda nije odobrena i biti će maknuta u 3.0. Koristite ${newMethod}.",'boundsAddError':"Morate dati obje vrijednosti ,  x i y  da bi dodali funkciju.",'lonlatAddError':"Morate dati obje vrijednosti , (lon i lat) da bi dodali funkciju.",'pixelAddError':"Morate dati obje vrijednosti ,  x i y  da bi dodali funkciju.",'unsupportedGeometryType':"Nepodržani tip geometrije: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition nije uspjelo: element sa id ${elemId} može biti krivo smješten."});OpenLayers.Lang["hsb"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Wotmołwa njewobdźěłaneho naprašowanja ${statusText}",'permalink':"Trajny wotkaz",'overlays':"Naworštowanja",'baseLayer':"Zakładna runina",'sameProjection':"Přehladowa karta jenož funguje, hdyž je w samsnej projekciji kaž hłowna karta",'readNotImplemented':"Čitanje njeimplementowane.",'writeNotImplemented':"Pisanje njeimplementowane.",'noFID':"Funkcija, za kotruž FID njeje, njeda so aktualizować.",'errorLoadingGML':"Zmylk při začitowanju dataje ${url}",'browserNotSupported':"Twój wobhladowak wektorowe rysowanje njepodpěruje. Tuchwilu podpěrowane rysowaki su:\n${renderers}",'componentShouldBe':"addFeatures: komponenta měła ${geomType} być",'getFeatureError':"getFeatureFromEvent bu na woršće bjez rysowak zawołany. To zwjetša woznamjenja, zo sy worštu zničił, ale nic wobdźěłak, kotryž je z njej zwjazany.",'minZoomLevelError':"Kajkosć minZoomLevel je jenož za wužiwanje z worštami myslena, kotrež wot FixedZoomLevels pochadźeja. Zo tuta woršta wfs za minZoomLevel přepruwuje, je relikt zańdźenosće. Njemóžemy wšak ju wotstronić, bjeztoho zo aplikacije, kotrež na OpenLayers bazěruja a snano tutu kajkosć wužiwaja, hižo njefunguja. Tohodla smy ju jako zestarjenu woznamjenili -- přepruwowanje za minZoomLevel budu so we wersiji 3.0 wotstronjeć. Prošu wužij město toho nastajenje min/max, kaž je tu wopisane: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-Transakcija: WUSPĚŠNA ${response}",'commitFailed':"WFS-Transakcija: NJEPORADŹENA ${response}",'googleWarning':"Woršta Google njemóžeše so korektnje začitać.\x3cbr\x3e\x3cbr\x3eZo by tutu zdźělenku wotbył, wubjer nowy BaseLayer z wuběra worštow horjeka naprawo.\x3cbr\x3e\x3cbr\x3eNajskerje so to stawa, dokelž skript biblioteki Google Maps pak njebu zapřijaty pak njewobsahuje korektny kluč API za twoje sydło.\x3cbr\x3e\x3cbr\x3eWuwiwarjo: Za pomoc ke korektnemu fungowanju worštow\n\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3etu kliknyć\x3c/a\x3e",'getLayerWarning':"Woršta ${layerType} njemóžeše so korektnje začitać.\x3cbr\x3e\x3cbr\x3eZo by tutu zdźělenku wotbył, wubjer nowy BaseLayer z wuběra worštow horjeka naprawo.\x3cbr\x3e\x3cbr\x3eNajskerje so to stawa, dokelž skript biblioteki ${layerLib} njebu korektnje zapřijaty.\x3cbr\x3e\x3cbr\x3eWuwiwarjo: Za pomoc ke korektnemu fungowanju worštow\n\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3etu kliknyć\x3c/a\x3e",'scale':"Měritko = 1 : ${scaleDenom}",'W':"Z",'E':"W",'N':"S",'S':"J",'layerAlreadyAdded':"Sy spytał runinu ${layerName} karće dodać, ale je so hižo dodała",'reprojectDeprecated':"Wužiwaš opciju \"reproject\" wořšty ${layerName}. Tuta opcija je zestarjena: jeje wužiwanje bě myslene, zo by zwobraznjenje datow nad komercielnymi bazowymi kartami podpěrało, ale funkcionalnosć měła so nětko z pomocu Sperical Mercator docpěć. Dalše informacije steja na http://trac.openlayers.org/wiki/SphericalMercator k dispoziciji.",'methodDeprecated':"Tuta metoda je so njeschwaliła a budźe so w 3.0 wotstronjeć. Prošu wužij ${newMethod} město toho.",'boundsAddError':"Dyrbiš hódnotu x kaž tež y funkciji \"add\" přepodać.",'lonlatAddError':"Dyrbiš hódnotu lon kaž tež lat funkciji \"add\" přepodać.",'pixelAddError':"Dyrbiš hódnotu x kaž tež y funkciji \"add\" přepodać.",'unsupportedGeometryType':"Njepodpěrowany geometrijowy typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition je so njeporadźił: element z id ${elemId} bu snano wopak zaměstnjeny.",'filterEvaluateNotImplemented':"wuhódnoćenje njeje za tutón filtrowy typ implementowany."});OpenLayers.Lang["hu"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nem kezelt kérés visszatérése ${statusText}",'permalink':"Permalink",'overlays':"Rávetítések",'baseLayer':"Alapréteg",'sameProjection':"Az áttekintő térkép csak abban az esetben működik, ha ugyanazon a vetületen van, mint a fő térkép.",'readNotImplemented':"Olvasás nincs végrehajtva.",'writeNotImplemented':"Írás nincs végrehajtva.",'noFID':"Nem frissíthető olyan jellemző, amely nem rendelkezik FID-del.",'errorLoadingGML':"Hiba GML-fájl betöltésekor ${url}",'browserNotSupported':"A böngészője nem támogatja a vektoros renderelést. A jelenleg támogatott renderelők:\n${renderers}",'componentShouldBe':"addFeatures : az összetevőnek ilyen típusúnak kell lennie: ${geomType}",'getFeatureError':"getFeatureFromEvent réteget hívott meg renderelő nélkül. Ez rendszerint azt jelenti, hogy megsemmisített egy fóliát, de néhány ahhoz társított kezelőt nem.",'minZoomLevelError':"A minZoomLevel tulajdonságot csak a következővel való használatra szánták: FixedZoomLevels-leszármazott fóliák. Ez azt jelenti, hogy a minZoomLevel wfs fólia jelölőnégyzetei már a múlté. Mi azonban nem távolíthatjuk el annak a veszélye nélkül, hogy az esetlegesen ettől függő OL alapú alkalmazásokat tönkretennénk. Ezért ezt érvénytelenítjük -- a minZoomLevel az alul levő jelölőnégyzet a 3.0-s verzióból el lesz távolítva. Kérjük, helyette használja a  min/max felbontás beállítást, amelyről az alábbi helyen talál leírást: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS tranzakció: SIKERES ${response}",'commitFailed':"WFS tranzakció: SIKERTELEN ${response}",'googleWarning':"A Google fólia betöltése sikertelen.\x3cbr\x3e\x3cbr\x3eAhhoz, hogy ez az üzenet eltűnjön, válasszon egy új BaseLayer fóliát a jobb felső sarokban található fóliakapcsoló segítségével.\x3cbr\x3e\x3cbr\x3eNagy valószínűséggel ez azért van, mert a Google Maps könyvtár parancsfájlja nem található, vagy nem tartalmazza az Ön oldalához tartozó megfelelő API-kulcsot.\x3cbr\x3e\x3cbr\x3eFejlesztőknek: A helyes működtetésre vonatkozó segítség az alábbi helyen érhető el, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3ekattintson ide\x3c/a\x3e",'getLayerWarning':"A(z) ${layerType} fólia nem töltődött be helyesen.\x3cbr\x3e\x3cbr\x3eAhhoz, hogy ez az üzenet eltűnjön, válasszon egy új BaseLayer fóliát a jobb felső sarokban található fóliakapcsoló segítségével.\x3cbr\x3e\x3cbr\x3eNagy valószínűséggel ez azért van, mert a(z) ${layerLib} könyvtár parancsfájlja helytelen.\x3cbr\x3e\x3cbr\x3eFejlesztőknek: A helyes működtetésre vonatkozó segítség az alábbi helyen érhető el, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3ekattintson ide\x3c/a\x3e",'scale':"Lépték = 1 : ${scaleDenom}",'W':"Ny",'E':"K",'N':"É",'S':"D",'layerAlreadyAdded':"Megpróbálta hozzáadni a(z) ${layerName} fóliát a térképhez, de az már hozzá van adva",'reprojectDeprecated':"Ön a \'reproject\' beállítást használja a(z) ${layerName} fólián. Ez a beállítás érvénytelen: használata az üzleti alaptérképek fölötti adatok megjelenítésének támogatására szolgált, de ezt a funkció ezentúl a Gömbi Mercator használatával érhető el. További információ az alábbi helyen érhető el: http://trac.openlayers.org/wiki/SphericalMercator",'methodDeprecated':"Ez a módszer érvénytelenítve lett és a 3.0-s verzióból el lesz távolítva. Használja a(z) ${newMethod} módszert helyette.",'boundsAddError':"Az x és y értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'lonlatAddError':"A hossz. és szél. értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'pixelAddError':"Az x és y értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'unsupportedGeometryType':"Nem támogatott geometriatípus: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition sikertelen: lehetséges, hogy a(z) ${elemId} azonosítójú elem téves helyre került.",'filterEvaluateNotImplemented':"ennél a szűrőtípusnál kiértékelés nem hajtódik végre."});OpenLayers.Lang["ia"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Le responsa a un requesta non esseva maneate: ${statusText}",'permalink':"Permaligamine",'overlays':"Superpositiones",'baseLayer':"Strato de base",'sameProjection':"Le mini-carta functiona solmente si illo es in le mesme projection que le carta principal",'readNotImplemented':"Lectura non implementate.",'writeNotImplemented':"Scriptura non implementate.",'noFID':"Non pote actualisar un elemento sin FID.",'errorLoadingGML':"Error al cargamento del file GML ${url}",'browserNotSupported':"Tu navigator non supporta le rendition de vectores. Le renditores actualmente supportate es:\n${renderers}",'componentShouldBe':"addFeatures: le componente debe esser del typo ${geomType}",'getFeatureError':"getFeatureFromEvent ha essite appellate in un strato sin renditor. Isto significa generalmente que tu ha destruite un strato, ma lassava un gestor associate con illo.",'minZoomLevelError':"Le proprietate minZoomLevel es solmente pro uso con le stratos descendente de FixedZoomLevels. Le facto que iste strato WFS verifica minZoomLevel es un reliquia del passato. Nonobstante, si nos lo remove immediatemente, nos pote rumper applicationes a base de OL que depende de illo. Ergo nos lo declara obsolete; le verification de minZoomLevel in basso essera removite in version 3.0. Per favor usa in su loco le configuration de resolutiones min/max como describite a: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transaction WFS: SUCCESSO ${response}",'commitFailed':"Transaction WFS: FALLEVA ${response}",'googleWarning':"Le strato Google non poteva esser cargate correctemente.\x3cbr\x3e\x3cbr\x3ePro disfacer te de iste message, selige un nove BaseLayer in le selector de strato in alto a dextra.\x3cbr\x3e\x3cbr\x3eMulto probabilemente, isto es proque le script del libreria de Google Maps non esseva includite o non contine le clave API correcte pro tu sito.\x3cbr\x3e\x3cbr\x3eDisveloppatores: Pro adjuta de corriger isto, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclicca hic\x3c/a",'getLayerWarning':"Le strato ${layerType} non poteva esser cargate correctemente.\x3cbr\x3e\x3cbr\x3ePro disfacer te de iste message, selige un nove BaseLayer in le selector de strato in alto a dextra.\x3cbr\x3e\x3cbr\x3eMulto probabilemente, isto es proque le script del libreria de ${layerLib} non esseva correctemente includite.\x3cbr\x3e\x3cbr\x3eDisveloppatores: Pro adjuta de corriger isto, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclicca hic\x3c/a\x3e",'scale':"Scala = 1 : ${scaleDenom}",'W':"W",'E':"E",'N':"N",'S':"S",'layerAlreadyAdded':"Tu tentava adder le strato: ${layerName} al carta, ma illo es ja presente",'reprojectDeprecated':"Tu usa le option \'reproject\' in le strato ${layerName} layer. Iste option es obsolescente: illo esseva pro poter monstrar datos super cartas de base commercial, ma iste functionalitate pote ora esser attingite con le uso de Spherical Mercator. Ulterior information es disponibile a http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Iste methodo ha essite declarate obsolescente e essera removite in version 3.0. Per favor usa ${newMethod} in su loco.",'boundsAddError':"Tu debe passar le duo valores x e y al function add.",'lonlatAddError':"Tu debe passar le duo valores lon e lat al function add.",'pixelAddError':"Tu debe passar le duo valores x e y al function add.",'unsupportedGeometryType':"Typo de geometria non supportate: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition falleva: le elemento con id ${elemId} pote esser mal placiate.",'filterEvaluateNotImplemented':"\"evaluate\" non es implementate pro iste typo de filtro."});OpenLayers.Lang["id"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Permintaan yang tak tertangani menghasilkan ${statusText}",'permalink':"Pranala permanen",'overlays':"Hamparan",'baseLayer':"Lapisan Dasar",'sameProjection':"Peta tinjauan hanya bekerja bila dalam proyeksi yang sama dengan peta utama",'readNotImplemented':"Membaca tidak diterapkan.",'writeNotImplemented':"Menyimpan tidak diterapkan.",'noFID':"Tidak dapat memperbarui fitur yang tidak memiliki FID.",'errorLoadingGML':"Kesalahan dalam memuat berkas GML ${url}",'browserNotSupported':"Peramban Anda tidak mendukung penggambaran vektor. Penggambar yang didukung saat ini adalah:\n${renderers}",'componentShouldBe':"addFeatures : komponen harus berupa ${geomType}",'getFeatureError':"getFeatureFromEvent diterapkan pada lapisan tanpa penggambar. Ini biasanya berarti Anda menghapus sebuah lapisan, tetapi tidak menghapus penangan yang terkait dengannya.",'minZoomLevelError':"Properti minZoomLevel hanya ditujukan bekerja dengan lapisan FixedZoomLevels-descendent. Pengecekan minZoomLevel oleh lapisan wfs adalah peninggalan masa lalu. Kami tidak dapat menghapusnya tanpa kemungkinan merusak aplikasi berbasis OL yang mungkin bergantung padanya. Karenanya, kami menganggapnya tidak berlaku -- Cek minZoomLevel di bawah ini akan dihapus pada 3.0. Silakan gunakan penyetelan resolusi min/maks seperti dijabarkan di sini: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS Transaksi: BERHASIL ${respon}",'commitFailed':"WFS Transaksi: GAGAL ${respon}",'googleWarning':"Lapisan Google tidak dapat dimuat dengan benar.\x3cbr\x3e\x3cbr\x3eUntuk menghilangkan pesan ini, pilih suatu BaseLayer baru melalui penukar lapisan (layer switcher) di ujung kanan atas.\x3cbr\x3e\x3cbr\x3eKemungkinan besar ini karena pustaka skrip Google Maps tidak disertakan atau tidak mengandung kunci API yang tepat untuk situs Anda.\x3cbr\x3e\x3cbr\x3ePengembang: Untuk bantuan mengatasi masalah ini, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eklik di sini\x3c/a\x3e",'getLayerWarning':"Lapisan ${layerType} tidak dapat dimuat dengan benar.\x3cbr\x3e\x3cbr\x3eUntuk menghilangkan pesan ini, pilih suatu BaseLayer baru melalui penukar lapisan (layer switcher) di ujung kanan atas.\x3cbr\x3e\x3cbr\x3eKemungkinan besar ini karena pustaka skrip Google Maps tidak disertakan dengan benar.\x3cbr\x3e\x3cbr\x3ePengembang: Untuk bantuan mengatasi masalah ini, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eklik di sini\x3c/a\x3e",'scale':"Sekala = 1 : ${scaleDenom}",'W':"B",'E':"T",'N':"U",'S':"S",'layerAlreadyAdded':"Anda mencoba menambahkan lapisan: ${layerName} ke dalam peta, tapi lapisan itu telah ditambahkan",'reprojectDeprecated':"Anda menggunakan opsi \'reproject\' pada lapisan ${layerName}. Opsi ini telah ditinggalkan: penggunaannya dirancang untuk mendukung tampilan data melalui peta dasar komersial, tapi fungsionalitas tersebut saat ini harus dilakukan dengan menggunakan dukungan Spherical Mercator. Informasi lebih lanjut tersedia di http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Metode ini telah usang dan akan dihapus di 3.0. Sebaliknya, harap gunakan ${newMethod}.",'boundsAddError':"Anda harus memberikan kedua nilai x dan y ke fungsi penambah.",'lonlatAddError':"Anda harus memberikan kedua nilai lon dan lat ke fungsi penambah.",'pixelAddError':"Anda harus memberikan kedua nilai x dan y ke fungsi penambah.",'unsupportedGeometryType':"Tipe geometri tak didukung: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition gagal: elemen dengan id ${elemId} mungkin salah tempat.",'filterEvaluateNotImplemented':"evaluasi tidak tersedia untuk tipe filter ini."});OpenLayers.Lang["io"]=OpenLayers.Util.applyDefaults({'scale':"Skalo = 1 : ${scaleDenom}"});OpenLayers.Lang["is"]=OpenLayers.Util.applyDefaults({'permalink':"Varanlegur tengill",'overlays':"Þekjur",'baseLayer':"Grunnlag",'sameProjection':"Yfirlitskortið virkar aðeins ef það er í sömu vörpun og aðalkortið",'readNotImplemented':"Skrifun er óútfærð.",'writeNotImplemented':"Lestur er óútfærður.",'errorLoadingGML':"Villa kom upp við að hlaða inn GML skránni ${url}",'scale':"Skali = 1 : ${scaleDenom}",'layerAlreadyAdded':"Þú reyndir að bæta laginu ${layerName} á kortið en það er þegar búið að bæta því við",'methodDeprecated':"Þetta fall hefur verið úrelt og verður fjarlægt í 3.0. Notaðu ${newMethod} í staðin."});OpenLayers.Lang["ja"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"未処理の要求は ${statusText} を返します",'permalink':"パーマリンク",'overlays':"オーバーレイ",'baseLayer':"基底レイヤー",'sameProjection':"概観地図はメインの地図と同じ投影法をとる場合のみ機能します",'readNotImplemented':"読み込みは実装されていません。",'writeNotImplemented':"書き込みは実装されていません。",'noFID':"FID のない地物は更新できません。",'errorLoadingGML':"GML ファイル ${url} の読み込みエラー",'browserNotSupported':"あなたのブラウザはベクターグラフィックスの描写に対応していません。現時点で対応しているソフトウェアは以下のものです。\n${renderers}",'componentShouldBe':"addFeatures: 要素は ${geomType} であるべきです",'getFeatureError':"getFeatureFromEvent がレンダラーのないレイヤーから呼ばれました。通常、これはあなたがレイヤーを、それに関連づけられたいくつかのハンドラを除いて、破壊してしまったことを意味します。",'minZoomLevelError':"minZoomLevel プロパティは FixedZoomLevels を継承するレイヤーでの使用のみを想定しています。この minZoomLevel に対する WFS レイヤーの検査は歴史的なものです。しかしながら、この検査を除去するとそれに依存する OpenLayers ベースのアプリケーションを破壊してしまう可能性があります。よって廃止が予定されており、この minZoomLevel 検査はバージョン3.0で除去されます。代わりに、http://trac.openlayers.org/wiki/SettingZoomLevels で解説されている、最小および最大解像度設定を使用してください。",'commitSuccess':"WFS トランザクション: 成功 ${response}",'commitFailed':"WFS トランザクション: 失敗 ${response}",'googleWarning':"Google レイヤーが正しく読み込みを行えませんでした。\x3cbr\x3e\x3cbr\x3eこのメッセージを消すには、右上の隅にあるレイヤー切り替え部分で新しい基底レイヤーを選んでください。\x3cbr\x3e\x3cbr\x3eおそらく、これは Google マップ用ライブラリのスクリプトが組み込まれていないか、あなたのサイトに対応する正しい API キーが設定されていないためです。\x3cbr\x3e\x3cbr\x3e開発者の方へ: 正しい動作をさせるために\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eこちらのウィキ\x3c/a\x3eを参照してください。",'getLayerWarning':"${layerType} レイヤーが正しく読み込みを行えませんでした。\x3cbr\x3e\x3cbr\x3eこのメッセージを消すには、右上の隅にあるレイヤー切り替え部分で新しい基底レイヤーを選んでください。\x3cbr\x3e\x3cbr\x3eおそらく、これは ${layerLib} ライブラリのスクリプトが正しく組み込まれていないためです。\x3cbr\x3e\x3cbr\x3e開発者の方へ: 正しい動作をさせるために\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eこちらのウィキ\x3c/a\x3eを参照してください。",'scale':"縮尺 = 1 : ${scaleDenom}",'W':"西",'E':"東",'N':"北",'S':"南",'layerAlreadyAdded':"あなたは「${layerName}」を地図に追加しようと試みましたが、そのレイヤーは既に追加されています",'reprojectDeprecated':"あなたは「${layerName}」レイヤーで reproject オプションを使っています。このオプションは商用の基底地図上に情報を表示する目的で設計されましたが、現在ではその機能は Spherical Mercator サポートを利用して実現されており、このオプションの使用は非推奨です。追加の情報は http://trac.openlayers.org/wiki/SphericalMercator で入手できます。",'methodDeprecated':"このメソッドは廃止が予定されており、バージョン3.0で除去されます。代わりに ${newMethod} を使用してください。",'boundsAddError':"x と y 両方の値を add 関数に渡さなければなりません。",'lonlatAddError':"lon と lat 両方の値を add 関数に渡さなければなりません。",'pixelAddError':"x と y の値両方を add 関数に渡さなければなりません。",'unsupportedGeometryType':"未対応の形状型: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition が失敗しました: id ${elemId} をもつ要素が誤った位置にある可能性があります。",'filterEvaluateNotImplemented':"このフィルター型について evaluate は実装されていません。"});OpenLayers.Lang["km"]=OpenLayers.Util.applyDefaults({'permalink':"តំណភ្ជាប់អចិន្ត្រៃយ៍",'baseLayer':"ស្រទាប់បាត​",'errorLoadingGML':"កំហុសកំឡុងពេលផ្ទុកឯកសារ GML ${url}",'scale':"មាត្រដ្ឋាន = ១ ៖ ${scaleDenom}"});OpenLayers.Lang["ksh"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Met dä Antwoot op en Aanfrooch ham_mer nix aanjefange: ${statusText}",'permalink':"Lengk op Duuer",'overlays':"Drövver jelaat",'baseLayer':"Jrund-Nivoh",'sameProjection':"De Övverseeschs_Kaat deiht et bloß, wann se de sälve Projäxjuhn bruche deiht, wi de Houp_Kaat",'readNotImplemented':"„\x3ccode lang=\"en\"\x3eread\x3c/code\x3e“ is em Projramm nit fürjesinn.",'writeNotImplemented':"„\x3ccode lang=\"en\"\x3ewrite\x3c/code\x3e“ is em Projramm nit fürjesinn.",'noFID':"En Saach, woh kein \x3ci lang=\"en\"\x3eFID\x3c/i\x3e för doh es, löht sesch nit ändere.",'errorLoadingGML':"Fähler beim \x3ci lang=\"en\"\x3eGML\x3c/i\x3e-Datei-Laade vun \x3ccode\x3e${url}\x3c/code\x3e",'browserNotSupported':"Dinge Brauser kann kein Väktore ußjävve. De Zoote Ußjaabe, di em Momang jon, sen:\n${renderers}",'componentShouldBe':"\x3ccode lang=\"en\"\x3eaddFeatures\x3c/code\x3e: dä Aandeil sullt vun dä Zoot „\x3ccode lang=\"en\"\x3e${geomType}\x3c/code\x3e“ sin.",'getFeatureError':"\x3ccode lang=\"en\"\x3egetFeatureFromEvent\x3c/code\x3e es vun enem Nivoh opjeroofe woode, woh et kei Projramm zom Ußjävve jit. Dat bedügg för jewöhnlesch, dat De e Nivoh kapott jemaat häs, ävver nit e Projramm för domet ömzejonn, wat domet verbonge es.",'minZoomLevelError':"De Eijeschaff „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“ es bloß doför jedaach, dat mer se met dä Nivvohß bruch, di vun \x3ccode lang=\"en\"\x3eFixedZoomLevels\x3c/code\x3e affhange don. Dat dat \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Nivvoh övverhoup de Eijeschaff „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“ pröhfe deiht, es noch övveresch vun fröhjer. Mer künne dat ävver jez nit fott lohße, oohne dat mer Jevaa loufe, dat Aanwendunge vun OpenLayers nit mieh loufe, di sesch doh velleijsch noch drop am verlohße sin. Dröm sare mer, dat mer et nit mieh han welle, un de „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“-Eijeschaff weed hee vun de Version 3.0 af nit mieh jeprööf wäde. Nemm doför de Enstellung för de hühßte un de kleinßte Oplöhsung, esu wi et en http://trac.openlayers.org/wiki/SettingZoomLevels opjeschrevve es.",'commitSuccess':"Dä \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Vörjang es joot jeloufe: ${response}",'commitFailed':"Dä \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Vörjang es scheif jejange: ${response}",'googleWarning':"Dat Nivvoh \x3ccode lang=\"en\"\x3eGoogle\x3c/code\x3e kunnt nit reschtesch jelaade wääde.\x3cbr /\x3e\x3cbr /\x3eÖm hee di Nohreesch loß ze krijje, donn en ander Jrund-Nivvoh ußsöhke, rähß bovve en de Äk.\x3cbr /\x3e\x3cbr /\x3eWascheinlesch es dat wiel dat \x3ci lang=\"en\"\x3eGoogle-Maps\x3c/i\x3e-Skrepp entweeder nit reschtesch enjebonge wood, udder nit dä reschtejje \x3ci lang=\"en\"\x3eAPI\x3c/i\x3e-Schlößel för Ding Web-ßait scheke deiht.\x3cbr /\x3e\x3cbr /\x3eFör Projrammierer jidd_et Hölp do_drövver, \x3ca href=\"http://trac.openlayers.org/wiki/Google\" target=\"_blank\"\x3ewi mer dat aan et Loufe brengk\x3c/a\x3e.",'getLayerWarning':"Dat Nivvoh \x3ccode\x3e${layerType}\x3c/code\x3e kunnt nit reschtesch jelaade wääde.\x3cbr /\x3e\x3cbr /\x3eÖm hee di Nohreesch loß ze krijje, donn en ander Jrund-Nivvoh ußsöhkre, rähß bovve en de Äk.\x3cbr /\x3e\x3cbr /\x3eWascheinlesch es dat, wiel dat Skrepp \x3ccode\x3e${layerLib}\x3c/code\x3e nit reschtesch enjebonge wood.\x3cbr /\x3e\x3cbr /\x3eFör Projrammierer jidd_Et Hölp do_drövver, \x3ca href=\"http://trac.openlayers.org/wiki/${layerLib}\" target=\"_blank\"\x3ewi mer dat aan et Loufe brengk\x3c/a\x3e.",'scale':"Mohßshtaab = 1 : ${scaleDenom}",'W':"W",'E':"O",'N':"N",'S':"S",'layerAlreadyAdded':"Do häß versöhk, dat Nivvoh \x3ccode\x3e${layerName}\x3c/code\x3e en di Kaat eren ze bränge, et wohr ävver ald do dren.",'reprojectDeprecated':"Do bruchs de Ußwahl \x3ccode\x3ereproject\x3c/code\x3e op däm Nivvoh \x3ccode\x3e${layerName}\x3c/code\x3e. Di Ußwahl es nit mieh jähn jesinn. Se wohr doför jedaach, öm Date op jeschääfsmäßesch eruß jejovve Kaate bovve drop ze moole, wat ävver enzwesche besser met dä Öngershtözung för de ßfääresche Mäkaator Beldscher jeiht. Doh kanns De mieh drövver fenge op dä Sigg: http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Hee di Metood es nim_mih aktoäll un et weed se en dä Version 3.0 nit mieh jävve. Nemm \x3ccode\x3e${newMethod}\x3c/code\x3e doföör.",'boundsAddError':"Do moß beeds vun de \x3ccode\x3ex\x3c/code\x3e un \x3ccode\x3ey\x3c/code\x3e Wääte aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'lonlatAddError':"Do moß beeds \x3ccode\x3elon\x3c/code\x3e un \x3ccode\x3elat\x3c/code\x3e aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'pixelAddError':"Do moß beeds \x3ccode\x3ex\x3c/code\x3e un \x3ccode\x3ey\x3c/code\x3e aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'unsupportedGeometryType':"De Zoot Jommetrii dom_mer nit ongershtöze: \x3ccode\x3e${geomType}\x3c/code\x3e",'pagePositionFailed':"\x3ccode lang=\"en\"\x3eOpenLayers.Util.pagePosition\x3c/code\x3e es donevve jejange: dat Denge met dä Kännong \x3ccode\x3e${elemId}\x3c/code\x3e künnt am verkeehte Plaz sin.",'filterEvaluateNotImplemented':"„\x3ccode lang=\"en\"\x3eevaluate\x3c/code\x3e“ es för di Zoot Fellter nit enjereschdt."});OpenLayers.Lang["nds"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Unbehannelt Trüchmellels för de Anfraag ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Achtergrundkoort",'sameProjection':"De Översichtskoort geiht blot, wenn de sülve Projekschoon as bi de Hööftkoort bruukt warrt",'readNotImplemented':"Lesen is nich inricht.",'writeNotImplemented':"Schrieven is nich inricht.",'noFID':"En Feature, dat keen FID hett, kann nich aktuell maakt warrn.",'errorLoadingGML':"Fehler bi’t Laden vun de GML-Datei ${url}",'browserNotSupported':"Dien Browser ünnerstütt keen Vektorbiller. Ünnerstütt Renderers:\n${renderers}",'componentShouldBe':"addFeatures : Kumponent schull man den Typ ${geomType} hebben",'getFeatureError':"getFeatureFromEvent is von en Laag ahn Render opropen worrn. Dat bedüüdt normalerwies, dat en Laag wegmaakt worrn is, aver nich de Handler, de dor op verwiest.",'commitSuccess':"WFS-Transakschoon: hett klappt ${response}",'commitFailed':"WFS-Transakschoon: hett nich klappt ${response}",'scale':"Skaal = 1 : ${scaleDenom}",'layerAlreadyAdded':"Du versöchst de Laag „${layerName}“ to de Koort totofögen, man de is al toföögt",'methodDeprecated':"Disse Methood is oold un schall dat in 3.0 nich mehr geven. Bruuk dor man beter ${newMethod} för.",'boundsAddError':"De Weert x un y, de mööt all beid an de add-Funkschoon övergeven warrn.",'lonlatAddError':"De Weert lon un lat, de mööt all beid an de add-Funkschoon övergeven warrn.",'pixelAddError':"De Weert x un y, de mööt all beid an de add-Funkschoon övergeven warrn.",'unsupportedGeometryType':"Nich ünnerstütt Geometrie-Typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition güng nich: Element mit de Id ${elemId} is villicht an’n verkehrten Platz."});OpenLayers.Lang["nn"]=OpenLayers.Util.applyDefaults({'scale':"Skala = 1 : ${scaleDenom}",'layerAlreadyAdded':"Du freista å leggja til laget «${layerName}» på kartet, men det har alt vorte lagt til.",'boundsAddError':"Du er nøydd til å gje både ein x- og ein y-verdi til «add»-funksjonen.",'lonlatAddError':"Du er nøydd til å gje både lon- og lat-verdiar til «add»-funksjonen.",'pixelAddError':"Du er nøydd til å gje både ein x- og ein y-verdi til «add»-funksjonen."});OpenLayers.Lang["oc"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Requèsta pas gerida, retorna ${statusText}",'permalink':"Permaligam",'overlays':"Calques",'baseLayer':"Calc de basa",'sameProjection':"La carta de situacion fonciona pas que quora sa projeccion es la meteissa que la de la carta principala",'readNotImplemented':"Lectura pas implementada.",'writeNotImplemented':"Escritura pas implementada.",'noFID':"Impossible de metre a jorn un objècte sens identificant (fid).",'errorLoadingGML':"Error al cargament del fichièr GML ${url}",'browserNotSupported':"Vòstre navegidor supòrta pas lo rendut vectorial. Los renderers actualament suportats son : \n${renderers}",'componentShouldBe':"addFeatures : lo compausant deuriá èsser de tipe ${geomType}",'getFeatureError':"getFeatureFromEvent es estat apelat sus un calc sens renderer. Aquò significa generalament qu\'avètz destruch aqueste jaç, mas qu\'avètz conservat un handler que li èra associat.",'minZoomLevelError':"La proprietat minZoomLevel deu èsser utilizada solament per de jaces FixedZoomLevels-descendent. Lo fach qu\'aqueste jaç WFS verifique la preséncia de minZoomLevel es una relica del passat. Çaquelà, la podèm suprimir sens copar d\'aplicacions que ne poirián dependre. Es per aquò que la depreciam -- la verificacion del minZoomLevel serà suprimida en version 3.0. A la plaça, mercés d\'utilizar los paramètres de resolucions min/max tal coma descrich sus : http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transaccion WFS : SUCCES ${response}",'commitFailed':"Transaccion WFS : FRACAS ${response}",'googleWarning':"Lo jaç Google es pas estat en mesura de se cargar corrèctament.\x3cbr\x3e\x3cbr\x3ePer suprimir aqueste messatge, causissètz una BaseLayer novèla dins lo selector de jaç en naut a drecha.\x3cbr\x3e\x3cbr\x3eAquò es possiblament causat par la non-inclusion de la librariá Google Maps, o alara perque que la clau de l\'API correspond pas a vòstre site.\x3cbr\x3e\x3cbr\x3eDesvolopaires : per saber cossí corregir aquò, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclicatz aicí\x3c/a\x3e",'getLayerWarning':"Lo jaç ${layerType} es pas en mesura de se cargar corrèctament.\x3cbr\x3e\x3cbr\x3ePer suprimir aqueste messatge, causissètz una  BaseLayer novèla dins lo selector de jaç en naut a drecha.\x3cbr\x3e\x3cbr\x3eAquò es possiblament causat per la non-inclusion de la librariá ${layerLib}.\x3cbr\x3e\x3cbr\x3eDesvolopaires : per saber cossí corregir aquí, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclicatz aicí\x3c/a\x3e",'scale':"Escala ~ 1 : ${scaleDenom}",'W':"O",'E':"È",'N':"N",'S':"S",'layerAlreadyAdded':"Avètz ensajat d\'apondre a la carta lo calc : ${layerName}, mas ja es present",'reprojectDeprecated':"Utilizatz l\'opcion \'reproject\' sul jaç ${layerName}. Aquesta opcion es despreciada : Son usatge permetiá d\'afichar de donadas al dessús de jaces raster comercials. Aquesta foncionalitat ara es suportada en utilizant lo supòrt de la projeccion Mercator Esferica. Mai d\'informacion es disponibla sus http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Aqueste metòde es despreciada, e serà suprimida a la version 3.0. Mercés d\'utilizar ${newMethod} a la plaça.",'boundsAddError':"Vos cal passar las doas valors x e y a la foncion add.",'lonlatAddError':"Vos cal passar las doas valors lon e lat a la foncion add.",'pixelAddError':"Vos cal passar las doas valors x e y a la foncion add.",'unsupportedGeometryType':"Tipe de geometria pas suportat : ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition a fracassat : l\'element d\'id ${elemId} poiriá èsser mal posicionat.",'filterEvaluateNotImplemented':"evaluar es pas encara estat implementat per aqueste tipe de filtre."});OpenLayers.Lang["pt"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Servidor devolveu erro não contemplado ${statusText}",'permalink':"Ligação permanente",'overlays':"Sobreposições",'baseLayer':"Camada Base",'sameProjection':"O mapa panorâmico só funciona quando está na mesma projeção que o mapa principal",'readNotImplemented':"Leitura não implementada.",'writeNotImplemented':"Escrita não implementada.",'noFID':"Não é possível atualizar um elemento para a qual não há FID.",'errorLoadingGML':"Erro ao carregar ficheiro GML ${url}",'browserNotSupported':"O seu navegador não suporta renderização vetorial. Actualmente os renderizadores suportados são:\n${renderers}",'componentShouldBe':"addFeatures: componente deve ser um(a) ${geomType}",'getFeatureError':"getFeatureFromEvent foi chamado numa camada sem renderizador. Isto normalmente significa que destruiu uma camada, mas não um manipulador \'\'(handler)\'\' que lhe está associado.",'minZoomLevelError':"A propriedade minZoomLevel só deve ser usada com as camadas descendentes da FixedZoomLevels. A verificação da propriedade por esta camada wfs é uma relíquia do passado. No entanto, não podemos removê-la sem correr o risco de afectar aplicações OL que dependam dela. Portanto, estamos a torná-la obsoleta -- a verificação minZoomLevel será removida na versão 3.0. Em vez dela, por favor, use as opções de resolução min/max descritas aqui: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transacção WFS: SUCESSO ${response}",'commitFailed':"Transacção WFS: FALHOU ${response}",'googleWarning':"A Camada Google não foi correctamente carregada.\x3cbr\x3e\x3cbr\x3ePara deixar de receber esta mensagem, seleccione uma nova Camada-Base no \'\'switcher\'\' de camadas no canto superior direito.\x3cbr\x3e\x3cbr\x3eProvavelmente, isto acontece porque o \'\'script\'\' da biblioteca do Google Maps não foi incluído ou não contém a chave API correcta para o seu sítio.\x3cbr\x3e\x3cbr\x3eProgramadores: Para ajuda sobre como solucionar o problema \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclique aqui\x3c/a\x3e .",'getLayerWarning':"A camada ${layerType} não foi correctamente carregada.\x3cbr\x3e\x3cbr\x3ePara desactivar esta mensagem, seleccione uma nova Camada-Base no \'\'switcher\'\' de camadas no canto superior direito.\x3cbr\x3e\x3cbr\x3eProvavelmente, isto acontece porque o \'\'script\'\' da biblioteca ${layerLib} não foi incluído correctamente.\x3cbr\x3e\x3cbr\x3eProgramadores: Para ajuda sobre como solucionar o problema \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclique aqui\x3c/a\x3e .",'scale':"Escala = 1 : ${scaleDenom}",'W':"O",'E':"E",'N':"N",'S':"S",'layerAlreadyAdded':"Você tentou adicionar a camada: ${layerName} ao mapa, mas ela já tinha sido adicionada antes",'reprojectDeprecated':"Está usando a opção \'reproject\' na camada ${layerName}. Esta opção é obsoleta: foi concebida para permitir a apresentação de dados sobre mapas-base comerciais, mas esta funcionalidade é agora suportada pelo Mercator Esférico. Mais informação está disponível em http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Este método foi declarado obsoleto e será removido na versão 3.0. Por favor, use ${newMethod} em vez disso.",'boundsAddError':"Você deve passar tanto o valor x como o y à função de adição.",'lonlatAddError':"Você deve passar tanto o valor lon como o lat à função de adição.",'pixelAddError':"Você deve passar tanto o valor x como o y à função de adição.",'unsupportedGeometryType':"Tipo de geometria não suportado: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition falhou: o elemento com o id ${elemId} poderá estar mal-posicionado.",'filterEvaluateNotImplemented':"avaliar não está implementado para este tipo de filtro."});OpenLayers.Lang["ru"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Необработанный запрос вернул ${statusText}",'permalink':"Постоянная ссылка",'overlays':"Слои",'baseLayer':"Основной слой",'sameProjection':"Обзорная карта работает только тогда, когда имеет ту же проекцию, что и основная",'readNotImplemented':"Чтение не реализовано.",'writeNotImplemented':"Запись не реализована.",'noFID':"Невозможно обновить объект, для которого нет FID.",'errorLoadingGML':"Ошибка при загрузке файла GML ${url}",'browserNotSupported':"Ваш браузер не поддерживает векторную графику. На данный момент поддерживаются:\n${renderers}",'componentShouldBe':"addFeatures: компонент должен быть ${geomType}",'getFeatureError':"getFeatureFromEvent вызван для слоя без рендерера. Обычно это говорит о том, что вы уничтожили слой, но оставили связанный с ним обработчик.",'minZoomLevelError':"Свойство minZoomLevel предназначено только для использования со слоями, являющимися потомками FixedZoomLevels. То, что этот WFS-слой проверяется на minZoomLevel — реликт прошлого. Однако мы не можем удалить эту функцию, так как, возможно, от неё зависят некоторые основанные на OpenLayers приложения. Функция объявлена устаревшей — проверка minZoomLevel будет удалена в 3.0. Пожалуйста, используйте вместо неё настройку мин/макс разрешения, описанную здесь: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Транзакция WFS: УСПЕШНО ${response}",'commitFailed':"Транзакция WFS: ОШИБКА ${response}",'googleWarning':"Слой Google не удалось нормально загрузить.\x3cbr\x3e\x3cbr\x3eЧтобы избавиться от этого сообщения, выбите другой основной слой в переключателе в правом верхнем углу.\x3cbr\x3e\x3cbr\x3eСкорее всего, причина в том, что библиотека Google Maps не была включена или не содержит корректного API-ключа для вашего сайта.\x3cbr\x3e\x3cbr\x3eРазработчикам: чтобы узнать, как сделать, чтобы всё заработало, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eщёлкните тут\x3c/a\x3e",'getLayerWarning':"Слой ${layerType} не удалось нормально загрузить. \x3cbr\x3e\x3cbr\x3eЧтобы избавиться от этого сообщения, выбите другой основной слой в переключателе в правом верхнем углу.\x3cbr\x3e\x3cbr\x3eСкорее всего, причина в том, что библиотека ${layerLib} не была включена или была включена некорректно.\x3cbr\x3e\x3cbr\x3eРазработчикам: чтобы узнать, как сделать, чтобы всё заработало, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eщёлкните тут\x3c/a\x3e",'scale':"Масштаб = 1 : ${scaleDenom}",'W':"З",'E':"В",'N':"С",'S':"Ю",'layerAlreadyAdded':"Вы попытались добавить слой «${layerName}» на карту, но он уже был добавлен",'reprojectDeprecated':"Вы используете опцию \'reproject\' для слоя ${layerName}. Эта опция является устаревшей: ее использование предполагалось для поддержки показа данных поверх коммерческих базовых карт, но теперь этот функционал несёт встроенная поддержка сферической проекции Меркатора. Больше сведений доступно на http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Этот метод считается устаревшим и будет удалён в версии 3.0. Пожалуйста, пользуйтесь ${newMethod}.",'boundsAddError':"Функции add надо передавать оба значения, x и y.",'lonlatAddError':"Функции add надо передавать оба значения, lon и lat.",'pixelAddError':"Функции add надо передавать оба значения, x и y.",'unsupportedGeometryType':"Неподдерживаемый тип геометрии: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: элемент с id ${elemId} может находиться не в нужном месте.",'filterEvaluateNotImplemented':"evaluate не реализовано для фильтра данного типа."});OpenLayers.Lang["sk"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Neobslúžené požiadavky vracajú ${statusText}",'permalink':"Trvalý odkaz",'overlays':"Prekrytia",'baseLayer':"Základná vrstva",'sameProjection':"Prehľadová mapka funguje iba vtedy, keď je v rovnakej projekcii ako hlavná mapa",'readNotImplemented':"Čítanie nie je implementované.",'writeNotImplemented':"Zápis nie je implementovaný.",'noFID':"Nie je možné aktualizovať vlastnosť, pre ktorú neexistuje FID.",'errorLoadingGML':"Chyba pri načítaní súboru GML ${url}",'browserNotSupported':"Váš prehliadač nepodporuje vykresľovanie vektorov. Momentálne podporované vykresľovače sú:\n${renderers}",'componentShouldBe':"addFeatures: komponent by mal byť ${geomType}",'getFeatureError':"getFeatureFromEvent bola zavolaná na vrstve bez vykresľovača. To zvyčajne znamená, že ste odstránili vrstvu, ale nie niektorú z obslúh, ktorá je s ňou asociovaná.",'minZoomLevelError':"Vlastnosť minZoomLevel je určený iba na použitie s vrstvami odvodenými od FixedZoomLevels. To, že táto wfs vrstva kontroluje minZoomLevel je pozostatok z minulosti. Nemôžeme ho však odstrániť, aby sme sa vyhli možnému porušeniu aplikácií založených na Open Layers, ktoré na tomto môže závisieť. Preto ho označujeme ako zavrhovaný - dolu uvedená kontrola minZoomLevel bude odstránená vo verzii 3.0. Použite prosím namiesto toho kontrolu min./max. rozlíšenia podľa tu uvedeného popisu: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transakcia WFS: ÚSPEŠNÁ ${response}",'commitFailed':"Transakcia WFS: ZLYHALA ${response}",'googleWarning':"Vrstvu Google nebolo možné správne načítať.\x3cbr\x3e\x3cbr\x3eAby ste sa tejto správy zbavili vyberte novú BaseLayer v prepínači vrstiev v pravom hornom rohu.\x3cbr\x3e\x3cbr\x3eToto sa stalo pravdepodobne preto, že skript knižnice Google Maps buď nebol načítaný alebo neobsahuje správny kľúč API pre vašu lokalitu.\x3cbr\x3e\x3cbr\x3eVývojári: Tu môžete získať \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3epomoc so sfunkčnením\x3c/a\x3e",'getLayerWarning':"Vrstvu ${layerType} nebolo možné správne načítať.\x3cbr\x3e\x3cbr\x3eAby ste sa tejto správy zbavili vyberte novú BaseLayer v prepínači vrstiev v pravom hornom rohu.\x3cbr\x3e\x3cbr\x3eToto sa stalo pravdepodobne preto, že skript knižnice ${layerType} buď nebol načítaný alebo neobsahuje správny kľúč API pre vašu lokalitu.\x3cbr\x3e\x3cbr\x3eVývojári: Tu môžete získať \x3ca href=\'http://trac.openlayers.org/wiki/${layerType}\' target=\'_blank\'\x3epomoc so sfunkčnením\x3c/a\x3e",'scale':"Mierka = 1 : ${scaleDenom}",'layerAlreadyAdded':"Pokúsili ste sa do mapy pridať vrstvu ${layerName}, ale tá už bola pridaná",'reprojectDeprecated':"Používate voľby „reproject“ vrstvy ${layerType}. Táto voľba je zzavrhovaná: jej použitie bolo navrhnuté na podporu zobrazovania údajov nad komerčnými základovými mapami, ale túto funkcionalitu je teraz možné dosiahnuť pomocou Spherical Mercator. Ďalšie informácie získate na stránke http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Táto metóda je zavrhovaná a bude odstránená vo verzii 3.0. Použite prosím namiesto nej metódu ${newMethod}.",'boundsAddError':"Sčítacej funkcii musíte dať hodnoty x aj y.",'lonlatAddError':"Sčítacej funkcii musíte dať hodnoty lon (zem. dĺžka) aj lat (zem. šírka).",'pixelAddError':"Sčítacej funkcii musíte dať hodnoty x aj y.",'unsupportedGeometryType':"Nepodporovaný typ geometrie: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition zlyhalo: prvok s id ${elemId} môže byť zle umiestnený.",'filterEvaluateNotImplemented':"evaluate nie je implementovaný pre tento typ filtra"});OpenLayers.Lang["te"]=OpenLayers.Util.applyDefaults({'permalink':"స్థిరలింకు",'W':"ప",'E':"తూ",'N':"ఉ",'S':"ద"});OpenLayers.Lang["vi"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Không xử lý được phản hồi ${statusText} cho yêu cầu",'permalink':"Liên kết thường trực",'overlays':"Lấp bản đồ",'baseLayer':"Lớp nền",'sameProjection':"Bản đồ toàn cảnh chỉ hoạt động khi cùng phép chiếu với bản đồ chính",'readNotImplemented':"Chưa hỗ trợ chức năng đọc.",'writeNotImplemented':"Chưa hỗ trợ chức năng viết.",'noFID':"Không thể cập nhật tính năng thiếu FID.",'errorLoadingGML':"Lỗi tải tập tin GML tại ${url}",'browserNotSupported':"Trình duyệt của bạn không hỗ trợ chức năng vẽ bằng vectơ. Hiện hỗ trợ các bộ kết xuất:\n${renderers}",'componentShouldBe':"addFeatures: bộ phận cần phải là ${geomType}",'getFeatureError':"getFeatureFromEvent được gọi từ lớp không có bộ kết xuất. Thường thì có lẽ lớp bị xóa nhưng một phần xử lý của nó vẫn còn.",'minZoomLevelError':"Chỉ nên sử dụng thuộc tính minZoomLevel với các lớp FixedZoomLevels-descendent. Việc lớp wfs này tìm cho minZoomLevel là di tích còn lại từ xưa. Tuy nhiên, nếu chúng tôi dời nó thì sẽ vỡ các chương trình OpenLayers mà dựa trên nó. Bởi vậy chúng tôi phản đối sử dụng nó\x26nbsp;– bước tìm cho minZoomLevel sẽ được dời vào phiên bản 3.0. Xin sử dụng thiết lập độ phân tích tối thiểu / tối đa thay thế, theo hướng dẫn này: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Giao dịch WFS: THÀNH CÔNG ${response}",'commitFailed':"Giao dịch WFS: THẤT BẠI ${response}",'googleWarning':"Không thể tải lớp Google đúng đắn.\x3cbr\x3e\x3cbr\x3eĐể tránh thông báo này lần sau, hãy chọn BaseLayer mới dùng điều khiển chọn lớp ở góc trên phải.\x3cbr\x3e\x3cbr\x3eChắc script thư viện Google Maps hoặc không được bao gồm hoặc không chứa khóa API hợp với website của bạn.\x3cbr\x3e\x3cbr\x3e\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eTrợ giúp về tính năng này\x3c/a\x3e cho người phát triển.",'getLayerWarning':"Không thể tải lớp ${layerType} đúng đắn.\x3cbr\x3e\x3cbr\x3eĐể tránh thông báo này lần sau, hãy chọn BaseLayer mới dùng điều khiển chọn lớp ở góc trên phải.\x3cbr\x3e\x3cbr\x3eChắc script thư viện ${layerLib} không được bao gồm đúng kiểu.\x3cbr\x3e\x3cbr\x3e\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eTrợ giúp về tính năng này\x3c/a\x3e cho người phát triển.",'scale':"Tỷ lệ = 1 : ${scaleDenom}",'W':"T",'E':"Đ",'N':"B",'S':"N",'layerAlreadyAdded':"Bạn muốn thêm lớp ${layerName} vào bản đồ, nhưng lớp này đã được thêm",'reprojectDeprecated':"Bạn đang áp dụng chế độ “reproject” vào lớp ${layerName}. Chế độ này đã bị phản đối: nó có mục đích hỗ trợ lấp dữ liệu trên các nền bản đồ thương mại; nên thực hiện hiệu ứng đó dùng tính năng Mercator Hình cầu. Có sẵn thêm chi tiết tại http://trac.openlayers.org/wiki/SphericalMercator .",'methodDeprecated':"Phương thức này đã bị phản đối và sẽ bị dời vào phiên bản 3.0. Xin hãy sử dụng ${newMethod} thay thế.",'boundsAddError':"Cần phải cho cả giá trị x và y vào hàm add.",'lonlatAddError':"Cần phải cho cả giá trị lon và lat vào hàm add.",'pixelAddError':"Cần phải cho cả giá trị x và y vào hàm add.",'unsupportedGeometryType':"Không hỗ trợ kiểu địa lý: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition bị thất bại: nguyên tố với ID ${elemId} có thể ở chỗ sai.",'filterEvaluateNotImplemented':"chưa hỗ trợ evaluate cho loại bộ lọc này."});OpenLayers.Popup.AnchoredBubble=OpenLayers.Class(OpenLayers.Popup.Anchored,{rounded:false,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){this.padding=new OpenLayers.Bounds(0,OpenLayers.Popup.AnchoredBubble.CORNER_SIZE,0,OpenLayers.Popup.AnchoredBubble.CORNER_SIZE);OpenLayers.Popup.Anchored.prototype.initialize.apply(this,arguments);},draw:function(px){OpenLayers.Popup.Anchored.prototype.draw.apply(this,arguments);this.setContentHTML();this.setBackgroundColor();this.setOpacity();return this.div;},updateRelativePosition:function(){this.setRicoCorners();},setSize:function(contentSize){OpenLayers.Popup.Anchored.prototype.setSize.apply(this,arguments);this.setRicoCorners();},setBackgroundColor:function(color){if(color!=undefined){this.backgroundColor=color;}
59805 if(this.div!=null){if(this.contentDiv!=null){this.div.style.background="transparent";OpenLayers.Rico.Corner.changeColor(this.groupDiv,this.backgroundColor);}}},setOpacity:function(opacity){OpenLayers.Popup.Anchored.prototype.setOpacity.call(this,opacity);if(this.div!=null){if(this.groupDiv!=null){OpenLayers.Rico.Corner.changeOpacity(this.groupDiv,this.opacity);}}},setBorder:function(border){this.border=0;},setRicoCorners:function(){var corners=this.getCornersToRound(this.relativePosition);var options={corners:corners,color:this.backgroundColor,bgColor:"transparent",blend:false};if(!this.rounded){OpenLayers.Rico.Corner.round(this.div,options);this.rounded=true;}else{OpenLayers.Rico.Corner.reRound(this.groupDiv,options);this.setBackgroundColor();this.setOpacity();}},getCornersToRound:function(){var corners=['tl','tr','bl','br'];var corner=OpenLayers.Bounds.oppositeQuadrant(this.relativePosition);OpenLayers.Util.removeItem(corners,corner);return corners.join(" ");},CLASS_NAME:"OpenLayers.Popup.AnchoredBubble"});OpenLayers.Popup.AnchoredBubble.CORNER_SIZE=5;OpenLayers.Popup.Framed=OpenLayers.Class(OpenLayers.Popup.Anchored,{imageSrc:null,imageSize:null,isAlphaImage:false,positionBlocks:null,blocks:null,fixedRelativePosition:false,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){OpenLayers.Popup.Anchored.prototype.initialize.apply(this,arguments);if(this.fixedRelativePosition){this.updateRelativePosition();this.calculateRelativePosition=function(px){return this.relativePosition;};}
59806 this.contentDiv.style.position="absolute";this.contentDiv.style.zIndex=1;if(closeBox){this.closeDiv.style.zIndex=1;}
59807 this.groupDiv.style.position="absolute";this.groupDiv.style.top="0px";this.groupDiv.style.left="0px";this.groupDiv.style.height="100%";this.groupDiv.style.width="100%";},destroy:function(){this.imageSrc=null;this.imageSize=null;this.isAlphaImage=null;this.fixedRelativePosition=false;this.positionBlocks=null;for(var i=0;i<this.blocks.length;i++){var block=this.blocks[i];if(block.image){block.div.removeChild(block.image);}
59808 block.image=null;if(block.div){this.groupDiv.removeChild(block.div);}
59809 block.div=null;}
59810 this.blocks=null;OpenLayers.Popup.Anchored.prototype.destroy.apply(this,arguments);},setBackgroundColor:function(color){},setBorder:function(){},setOpacity:function(opacity){},setSize:function(contentSize){OpenLayers.Popup.Anchored.prototype.setSize.apply(this,arguments);this.updateBlocks();},updateRelativePosition:function(){this.padding=this.positionBlocks[this.relativePosition].padding;if(this.closeDiv){var contentDivPadding=this.getContentDivPadding();this.closeDiv.style.right=contentDivPadding.right+
59811 this.padding.right+"px";this.closeDiv.style.top=contentDivPadding.top+
59812 this.padding.top+"px";}
59813 this.updateBlocks();},calculateNewPx:function(px){var newPx=OpenLayers.Popup.Anchored.prototype.calculateNewPx.apply(this,arguments);newPx=newPx.offset(this.positionBlocks[this.relativePosition].offset);return newPx;},createBlocks:function(){this.blocks=[];var firstPosition=null;for(var key in this.positionBlocks){firstPosition=key;break;}
59814 var position=this.positionBlocks[firstPosition];for(var i=0;i<position.blocks.length;i++){var block={};this.blocks.push(block);var divId=this.id+'_FrameDecorationDiv_'+i;block.div=OpenLayers.Util.createDiv(divId,null,null,null,"absolute",null,"hidden",null);var imgId=this.id+'_FrameDecorationImg_'+i;var imageCreator=(this.isAlphaImage)?OpenLayers.Util.createAlphaImageDiv:OpenLayers.Util.createImage;block.image=imageCreator(imgId,null,this.imageSize,this.imageSrc,"absolute",null,null,null);block.div.appendChild(block.image);this.groupDiv.appendChild(block.div);}},updateBlocks:function(){if(!this.blocks){this.createBlocks();}
59815 if(this.size&&this.relativePosition){var position=this.positionBlocks[this.relativePosition];for(var i=0;i<position.blocks.length;i++){var positionBlock=position.blocks[i];var block=this.blocks[i];var l=positionBlock.anchor.left;var b=positionBlock.anchor.bottom;var r=positionBlock.anchor.right;var t=positionBlock.anchor.top;var w=(isNaN(positionBlock.size.w))?this.size.w-(r+l):positionBlock.size.w;var h=(isNaN(positionBlock.size.h))?this.size.h-(b+t):positionBlock.size.h;block.div.style.width=(w<0?0:w)+'px';block.div.style.height=(h<0?0:h)+'px';block.div.style.left=(l!=null)?l+'px':'';block.div.style.bottom=(b!=null)?b+'px':'';block.div.style.right=(r!=null)?r+'px':'';block.div.style.top=(t!=null)?t+'px':'';block.image.style.left=positionBlock.position.x+'px';block.image.style.top=positionBlock.position.y+'px';}
59816 this.contentDiv.style.left=this.padding.left+"px";this.contentDiv.style.top=this.padding.top+"px";}},CLASS_NAME:"OpenLayers.Popup.Framed"});OpenLayers.Projection=OpenLayers.Class({proj:null,projCode:null,initialize:function(projCode,options){OpenLayers.Util.extend(this,options);this.projCode=projCode;if(window.Proj4js){this.proj=new Proj4js.Proj(projCode);}},getCode:function(){return this.proj?this.proj.srsCode:this.projCode;},getUnits:function(){return this.proj?this.proj.units:null;},toString:function(){return this.getCode();},equals:function(projection){if(projection&&projection.getCode){return this.getCode()==projection.getCode();}else{return false;}},destroy:function(){delete this.proj;delete this.projCode;},CLASS_NAME:"OpenLayers.Projection"});OpenLayers.Projection.transforms={};OpenLayers.Projection.addTransform=function(from,to,method){if(!OpenLayers.Projection.transforms[from]){OpenLayers.Projection.transforms[from]={};}
59817 OpenLayers.Projection.transforms[from][to]=method;};OpenLayers.Projection.transform=function(point,source,dest){if(source.proj&&dest.proj){point=Proj4js.transform(source.proj,dest.proj,point);}else if(source&&dest&&OpenLayers.Projection.transforms[source.getCode()]&&OpenLayers.Projection.transforms[source.getCode()][dest.getCode()]){OpenLayers.Projection.transforms[source.getCode()][dest.getCode()](point);}
59818 return point;};OpenLayers.Protocol.WFS.v1=OpenLayers.Class(OpenLayers.Protocol,{version:null,srsName:"EPSG:4326",featureType:null,featureNS:null,geometryName:"the_geom",schema:null,featurePrefix:"feature",formatOptions:null,readFormat:null,initialize:function(options){OpenLayers.Protocol.prototype.initialize.apply(this,[options]);if(!options.format){this.format=OpenLayers.Format.WFST(OpenLayers.Util.extend({version:this.version,featureType:this.featureType,featureNS:this.featureNS,featurePrefix:this.featurePrefix,geometryName:this.geometryName,srsName:this.srsName,schema:this.schema},this.formatOptions));}
59819 if(!this.featureNS&&this.featurePrefix){var readNode=this.format.readNode;this.format.readNode=function(node,obj){if(!this.featureNS&&node.prefix==this.featurePrefix){this.featureNS=node.namespaceURI;this.setNamespace("feature",this.featureNS);}
59820 return readNode.apply(this,arguments);};}},destroy:function(){if(this.options&&!this.options.format){this.format.destroy();}
59821 this.format=null;OpenLayers.Protocol.prototype.destroy.apply(this);},read:function(options){OpenLayers.Protocol.prototype.read.apply(this,arguments);options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options||{});var response=new OpenLayers.Protocol.Response({requestType:"read"});var data=OpenLayers.Format.XML.prototype.write.apply(this.format,[this.format.writeNode("wfs:GetFeature",options)]);response.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleRead,response,options),params:options.params,headers:options.headers,data:data});return response;},handleRead:function(response,options){if(options.callback){var request=response.priv;if(request.status>=200&&request.status<300){response.features=this.parseFeatures(request);response.code=OpenLayers.Protocol.Response.SUCCESS;}else{response.code=OpenLayers.Protocol.Response.FAILURE;}
59822 options.callback.call(options.scope,response);}},parseFeatures:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
59823 if(!doc||doc.length<=0){return null;}
59824 return(this.readFormat!==null)?this.readFormat.read(doc):this.format.read(doc);},commit:function(features,options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options);var response=new OpenLayers.Protocol.Response({requestType:"commit",reqFeatures:features});response.priv=OpenLayers.Request.POST({url:options.url,data:this.format.write(features,options),callback:this.createCallback(this.handleCommit,response,options)});return response;},handleCommit:function(response,options){if(options.callback){var request=response.priv;var data=request.responseXML;if(!data||!data.documentElement){data=request.responseText;}
59825 var obj=this.format.read(data)||{};response.insertIds=obj.insertIds||[];response.code=(obj.success)?OpenLayers.Protocol.Response.SUCCESS:OpenLayers.Protocol.Response.FAILURE;options.callback.call(options.scope,response);}},filterDelete:function(filter,options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options);var response=new OpenLayers.Protocol.Response({requestType:"commit"});var root=this.format.createElementNSPlus("wfs:Transaction",{attributes:{service:"WFS",version:this.version}});var deleteNode=this.format.createElementNSPlus("wfs:Delete",{attributes:{typeName:(options.featureNS?this.featurePrefix+":":"")+
59826 options.featureType}});if(options.featureNS){deleteNode.setAttribute("xmlns:"+this.featurePrefix,options.featureNS);}
59827 var filterNode=this.format.writeNode("ogc:Filter",filter);deleteNode.appendChild(filterNode);root.appendChild(deleteNode);var data=OpenLayers.Format.XML.prototype.write.apply(this.format,[root]);return OpenLayers.Request.POST({url:this.url,callback:options.callback||function(){},data:data});},abort:function(response){if(response){response.priv.abort();}},CLASS_NAME:"OpenLayers.Protocol.WFS.v1"});OpenLayers.Renderer.SVG=OpenLayers.Class(OpenLayers.Renderer.Elements,{xmlns:"http://www.w3.org/2000/svg",xlinkns:"http://www.w3.org/1999/xlink",MAX_PIXEL:15000,translationParameters:null,symbolMetrics:null,isGecko:null,supportUse:null,initialize:function(containerID){if(!this.supported()){return;}
59828 OpenLayers.Renderer.Elements.prototype.initialize.apply(this,arguments);this.translationParameters={x:0,y:0};this.supportUse=(navigator.userAgent.toLowerCase().indexOf("applewebkit/5")==-1);this.isGecko=(navigator.userAgent.toLowerCase().indexOf("gecko/")!=-1);this.symbolMetrics={};},destroy:function(){OpenLayers.Renderer.Elements.prototype.destroy.apply(this,arguments);},supported:function(){var svgFeature="http://www.w3.org/TR/SVG11/feature#";return(document.implementation&&(document.implementation.hasFeature("org.w3c.svg","1.0")||document.implementation.hasFeature(svgFeature+"SVG","1.1")||document.implementation.hasFeature(svgFeature+"BasicStructure","1.1")));},inValidRange:function(x,y,xyOnly){var left=x+(xyOnly?0:this.translationParameters.x);var top=y+(xyOnly?0:this.translationParameters.y);return(left>=-this.MAX_PIXEL&&left<=this.MAX_PIXEL&&top>=-this.MAX_PIXEL&&top<=this.MAX_PIXEL);},setExtent:function(extent,resolutionChanged){OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,arguments);var resolution=this.getResolution();var left=-extent.left/resolution;var top=extent.top/resolution;if(resolutionChanged){this.left=left;this.top=top;var extentString="0 0 "+this.size.w+" "+this.size.h;this.rendererRoot.setAttributeNS(null,"viewBox",extentString);this.translate(0,0);return true;}else{var inRange=this.translate(left-this.left,top-this.top);if(!inRange){this.setExtent(extent,true);}
59829 return inRange;}},translate:function(x,y){if(!this.inValidRange(x,y,true)){return false;}else{var transformString="";if(x||y){transformString="translate("+x+","+y+")";}
59830 this.root.setAttributeNS(null,"transform",transformString);this.translationParameters={x:x,y:y};return true;}},setSize:function(size){OpenLayers.Renderer.prototype.setSize.apply(this,arguments);this.rendererRoot.setAttributeNS(null,"width",this.size.w);this.rendererRoot.setAttributeNS(null,"height",this.size.h);},getNodeType:function(geometry,style){var nodeType=null;switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":if(style.externalGraphic){nodeType="image";}else if(this.isComplexSymbol(style.graphicName)){nodeType=this.supportUse===false?"svg":"use";}else{nodeType="circle";}
59831 break;case"OpenLayers.Geometry.Rectangle":nodeType="rect";break;case"OpenLayers.Geometry.LineString":nodeType="polyline";break;case"OpenLayers.Geometry.LinearRing":nodeType="polygon";break;case"OpenLayers.Geometry.Polygon":case"OpenLayers.Geometry.Curve":case"OpenLayers.Geometry.Surface":nodeType="path";break;default:break;}
59832 return nodeType;},setStyle:function(node,style,options){style=style||node._style;options=options||node._options;var r=parseFloat(node.getAttributeNS(null,"r"));var widthFactor=1;var pos;if(node._geometryClass=="OpenLayers.Geometry.Point"&&r){node.style.visibility="";if(style.graphic===false){node.style.visibility="hidden";}else if(style.externalGraphic){pos=this.getPosition(node);if(style.graphicTitle){node.setAttributeNS(null,"title",style.graphicTitle);}
59833 if(style.graphicWidth&&style.graphicHeight){node.setAttributeNS(null,"preserveAspectRatio","none");}
59834 var width=style.graphicWidth||style.graphicHeight;var height=style.graphicHeight||style.graphicWidth;width=width?width:style.pointRadius*2;height=height?height:style.pointRadius*2;var xOffset=(style.graphicXOffset!=undefined)?style.graphicXOffset:-(0.5*width);var yOffset=(style.graphicYOffset!=undefined)?style.graphicYOffset:-(0.5*height);var opacity=style.graphicOpacity||style.fillOpacity;node.setAttributeNS(null,"x",(pos.x+xOffset).toFixed());node.setAttributeNS(null,"y",(pos.y+yOffset).toFixed());node.setAttributeNS(null,"width",width);node.setAttributeNS(null,"height",height);node.setAttributeNS(this.xlinkns,"href",style.externalGraphic);node.setAttributeNS(null,"style","opacity: "+opacity);}else if(this.isComplexSymbol(style.graphicName)){var offset=style.pointRadius*3;var size=offset*2;var id=this.importSymbol(style.graphicName);pos=this.getPosition(node);widthFactor=this.symbolMetrics[id][0]*3/size;var parent=node.parentNode;var nextSibling=node.nextSibling;if(parent){parent.removeChild(node);}
59835 if(this.supportUse===false){var src=document.getElementById(id);node.firstChild&&node.removeChild(node.firstChild);node.appendChild(src.firstChild.cloneNode(true));node.setAttributeNS(null,"viewBox",src.getAttributeNS(null,"viewBox"));}else{node.setAttributeNS(this.xlinkns,"href","#"+id);}
59836 node.setAttributeNS(null,"width",size);node.setAttributeNS(null,"height",size);node.setAttributeNS(null,"x",pos.x-offset);node.setAttributeNS(null,"y",pos.y-offset);if(nextSibling){parent.insertBefore(node,nextSibling);}else if(parent){parent.appendChild(node);}}else{node.setAttributeNS(null,"r",style.pointRadius);}
59837 var rotation=style.rotation;if((rotation!==undefined||node._rotation!==undefined)&&pos){node._rotation=rotation;rotation|=0;if(node.nodeName!=="svg"){node.setAttributeNS(null,"transform","rotate("+rotation+" "+pos.x+" "+
59838 pos.y+")");}else{var metrics=this.symbolMetrics[id];node.firstChild.setAttributeNS(null,"transform","rotate("+style.rotation+" "+metrics[1]+" "+metrics[2]+")");}}}
59839 if(options.isFilled){node.setAttributeNS(null,"fill",style.fillColor);node.setAttributeNS(null,"fill-opacity",style.fillOpacity);}else{node.setAttributeNS(null,"fill","none");}
59840 if(options.isStroked){node.setAttributeNS(null,"stroke",style.strokeColor);node.setAttributeNS(null,"stroke-opacity",style.strokeOpacity);node.setAttributeNS(null,"stroke-width",style.strokeWidth*widthFactor);node.setAttributeNS(null,"stroke-linecap",style.strokeLinecap||"round");node.setAttributeNS(null,"stroke-linejoin","round");style.strokeDashstyle&&node.setAttributeNS(null,"stroke-dasharray",this.dashStyle(style,widthFactor));}else{node.setAttributeNS(null,"stroke","none");}
59841 if(style.pointerEvents){node.setAttributeNS(null,"pointer-events",style.pointerEvents);}
59842 if(style.cursor!=null){node.setAttributeNS(null,"cursor",style.cursor);}
59843 return node;},dashStyle:function(style,widthFactor){var w=style.strokeWidth*widthFactor;var str=style.strokeDashstyle;switch(str){case'solid':return'none';case'dot':return[1,4*w].join();case'dash':return[4*w,4*w].join();case'dashdot':return[4*w,4*w,1,4*w].join();case'longdash':return[8*w,4*w].join();case'longdashdot':return[8*w,4*w,1,4*w].join();default:return OpenLayers.String.trim(str).replace(/\s+/g,",");}},createNode:function(type,id){var node=document.createElementNS(this.xmlns,type);if(id){node.setAttributeNS(null,"id",id);}
59844 return node;},nodeTypeCompare:function(node,type){return(type==node.nodeName);},createRenderRoot:function(){return this.nodeFactory(this.container.id+"_svgRoot","svg");},createRoot:function(suffix){return this.nodeFactory(this.container.id+suffix,"g");},createDefs:function(){var defs=this.nodeFactory(this.container.id+"_defs","defs");this.rendererRoot.appendChild(defs);return defs;},drawPoint:function(node,geometry){return this.drawCircle(node,geometry,1);},drawCircle:function(node,geometry,radius){var resolution=this.getResolution();var x=(geometry.x/resolution+this.left);var y=(this.top-geometry.y/resolution);if(this.inValidRange(x,y)){node.setAttributeNS(null,"cx",x);node.setAttributeNS(null,"cy",y);node.setAttributeNS(null,"r",radius);return node;}else{return false;}},drawLineString:function(node,geometry){var componentsResult=this.getComponentsString(geometry.components);if(componentsResult.path){node.setAttributeNS(null,"points",componentsResult.path);return(componentsResult.complete?node:null);}else{return false;}},drawLinearRing:function(node,geometry){var componentsResult=this.getComponentsString(geometry.components);if(componentsResult.path){node.setAttributeNS(null,"points",componentsResult.path);return(componentsResult.complete?node:null);}else{return false;}},drawPolygon:function(node,geometry){var d="";var draw=true;var complete=true;var linearRingResult,path;for(var j=0,len=geometry.components.length;j<len;j++){d+=" M";linearRingResult=this.getComponentsString(geometry.components[j].components," ");path=linearRingResult.path;if(path){d+=" "+path;complete=linearRingResult.complete&&complete;}else{draw=false;}}
59845 d+=" z";if(draw){node.setAttributeNS(null,"d",d);node.setAttributeNS(null,"fill-rule","evenodd");return complete?node:null;}else{return false;}},drawRectangle:function(node,geometry){var resolution=this.getResolution();var x=(geometry.x/resolution+this.left);var y=(this.top-geometry.y/resolution);if(this.inValidRange(x,y)){node.setAttributeNS(null,"x",x);node.setAttributeNS(null,"y",y);node.setAttributeNS(null,"width",geometry.width/resolution);node.setAttributeNS(null,"height",geometry.height/resolution);return node;}else{return false;}},drawSurface:function(node,geometry){var d=null;var draw=true;for(var i=0,len=geometry.components.length;i<len;i++){if((i%3)==0&&(i/3)==0){var component=this.getShortString(geometry.components[i]);if(!component){draw=false;}
59846 d="M "+component;}else if((i%3)==1){var component=this.getShortString(geometry.components[i]);if(!component){draw=false;}
59847 d+=" C "+component;}else{var component=this.getShortString(geometry.components[i]);if(!component){draw=false;}
59848 d+=" "+component;}}
59849 d+=" Z";if(draw){node.setAttributeNS(null,"d",d);return node;}else{return false;}},drawText:function(featureId,style,location){var resolution=this.getResolution();var x=(location.x/resolution+this.left);var y=(location.y/resolution-this.top);var label=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX,"text");var tspan=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX+"_tspan","tspan");label.setAttributeNS(null,"x",x);label.setAttributeNS(null,"y",-y);if(style.fontColor){label.setAttributeNS(null,"fill",style.fontColor);}
59850 if(style.fontOpacity){label.setAttributeNS(null,"opacity",style.fontOpacity);}
59851 if(style.fontFamily){label.setAttributeNS(null,"font-family",style.fontFamily);}
59852 if(style.fontSize){label.setAttributeNS(null,"font-size",style.fontSize);}
59853 if(style.fontWeight){label.setAttributeNS(null,"font-weight",style.fontWeight);}
59854 if(style.labelSelect===true){label.setAttributeNS(null,"pointer-events","visible");label._featureId=featureId;tspan._featureId=featureId;tspan._geometry=location;tspan._geometryClass=location.CLASS_NAME;}else{label.setAttributeNS(null,"pointer-events","none");}
59855 var align=style.labelAlign||"cm";label.setAttributeNS(null,"text-anchor",OpenLayers.Renderer.SVG.LABEL_ALIGN[align[0]]||"middle");if(this.isGecko){label.setAttributeNS(null,"dominant-baseline",OpenLayers.Renderer.SVG.LABEL_ALIGN[align[1]]||"central");}else{tspan.setAttributeNS(null,"baseline-shift",OpenLayers.Renderer.SVG.LABEL_VSHIFT[align[1]]||"-35%");}
59856 tspan.textContent=style.label;if(!label.parentNode){label.appendChild(tspan);this.textRoot.appendChild(label);}},getComponentsString:function(components,separator){var renderCmp=[];var complete=true;var len=components.length;var strings=[];var str,component;for(var i=0;i<len;i++){component=components[i];renderCmp.push(component);str=this.getShortString(component);if(str){strings.push(str);}else{if(i>0){if(this.getShortString(components[i-1])){strings.push(this.clipLine(components[i],components[i-1]));}}
59857 if(i<len-1){if(this.getShortString(components[i+1])){strings.push(this.clipLine(components[i],components[i+1]));}}
59858 complete=false;}}
59859 return{path:strings.join(separator||","),complete:complete};},clipLine:function(badComponent,goodComponent){if(goodComponent.equals(badComponent)){return"";}
59860 var resolution=this.getResolution();var maxX=this.MAX_PIXEL-this.translationParameters.x;var maxY=this.MAX_PIXEL-this.translationParameters.y;var x1=goodComponent.x/resolution+this.left;var y1=this.top-goodComponent.y/resolution;var x2=badComponent.x/resolution+this.left;var y2=this.top-badComponent.y/resolution;var k;if(x2<-maxX||x2>maxX){k=(y2-y1)/(x2-x1);x2=x2<0?-maxX:maxX;y2=y1+(x2-x1)*k;}
59861 if(y2<-maxY||y2>maxY){k=(x2-x1)/(y2-y1);y2=y2<0?-maxY:maxY;x2=x1+(y2-y1)*k;}
59862 return x2+","+y2;},getShortString:function(point){var resolution=this.getResolution();var x=(point.x/resolution+this.left);var y=(this.top-point.y/resolution);if(this.inValidRange(x,y)){return x+","+y;}else{return false;}},getPosition:function(node){return({x:parseFloat(node.getAttributeNS(null,"cx")),y:parseFloat(node.getAttributeNS(null,"cy"))});},importSymbol:function(graphicName){if(!this.defs){this.defs=this.createDefs();}
59863 var id=this.container.id+"-"+graphicName;if(document.getElementById(id)!=null){return id;}
59864 var symbol=OpenLayers.Renderer.symbol[graphicName];if(!symbol){throw new Error(graphicName+' is not a valid symbol name');}
59865 var symbolNode=this.nodeFactory(id,"symbol");var node=this.nodeFactory(null,"polygon");symbolNode.appendChild(node);var symbolExtent=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE,0,0);var points=[];var x,y;for(var i=0;i<symbol.length;i=i+2){x=symbol[i];y=symbol[i+1];symbolExtent.left=Math.min(symbolExtent.left,x);symbolExtent.bottom=Math.min(symbolExtent.bottom,y);symbolExtent.right=Math.max(symbolExtent.right,x);symbolExtent.top=Math.max(symbolExtent.top,y);points.push(x,",",y);}
59866 node.setAttributeNS(null,"points",points.join(" "));var width=symbolExtent.getWidth();var height=symbolExtent.getHeight();var viewBox=[symbolExtent.left-width,symbolExtent.bottom-height,width*3,height*3];symbolNode.setAttributeNS(null,"viewBox",viewBox.join(" "));this.symbolMetrics[id]=[Math.max(width,height),symbolExtent.getCenterLonLat().lon,symbolExtent.getCenterLonLat().lat];this.defs.appendChild(symbolNode);return symbolNode.id;},getFeatureIdFromEvent:function(evt){var featureId=OpenLayers.Renderer.Elements.prototype.getFeatureIdFromEvent.apply(this,arguments);if(this.supportUse===false&&!featureId){var target=evt.target;featureId=target.parentNode&&target!=this.rendererRoot&&target.parentNode._featureId;}
59867 return featureId;},CLASS_NAME:"OpenLayers.Renderer.SVG"});OpenLayers.Renderer.SVG.LABEL_ALIGN={"l":"start","r":"end","b":"bottom","t":"hanging"};OpenLayers.Renderer.SVG.LABEL_VSHIFT={"t":"-70%","b":"0"};OpenLayers.Renderer.VML=OpenLayers.Class(OpenLayers.Renderer.Elements,{xmlns:"urn:schemas-microsoft-com:vml",symbolCache:{},offset:null,initialize:function(containerID){if(!this.supported()){return;}
59868 if(!document.namespaces.olv){document.namespaces.add("olv",this.xmlns);var style=document.createStyleSheet();var shapes=['shape','rect','oval','fill','stroke','imagedata','group','textbox'];for(var i=0,len=shapes.length;i<len;i++){style.addRule('olv\\:'+shapes[i],"behavior: url(#default#VML); "+"position: absolute; display: inline-block;");}}
59869 OpenLayers.Renderer.Elements.prototype.initialize.apply(this,arguments);},destroy:function(){OpenLayers.Renderer.Elements.prototype.destroy.apply(this,arguments);},supported:function(){return!!(document.namespaces);},setExtent:function(extent,resolutionChanged){OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,arguments);var resolution=this.getResolution();var left=(extent.left/resolution)|0;var top=(extent.top/resolution-this.size.h)|0;if(resolutionChanged||!this.offset){this.offset={x:left,y:top};left=0;top=0;}else{left=left-this.offset.x;top=top-this.offset.y;}
59870 var org=left+" "+top;this.root.coordorigin=org;var roots=[this.root,this.vectorRoot,this.textRoot];var root;for(var i=0,len=roots.length;i<len;++i){root=roots[i];var size=this.size.w+" "+this.size.h;root.coordsize=size;}
59871 this.root.style.flip="y";return true;},setSize:function(size){OpenLayers.Renderer.prototype.setSize.apply(this,arguments);var roots=[this.rendererRoot,this.root,this.vectorRoot,this.textRoot];var w=this.size.w+"px";var h=this.size.h+"px";var root;for(var i=0,len=roots.length;i<len;++i){root=roots[i];root.style.width=w;root.style.height=h;}},getNodeType:function(geometry,style){var nodeType=null;switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":if(style.externalGraphic){nodeType="olv:rect";}else if(this.isComplexSymbol(style.graphicName)){nodeType="olv:shape";}else{nodeType="olv:oval";}
59872 break;case"OpenLayers.Geometry.Rectangle":nodeType="olv:rect";break;case"OpenLayers.Geometry.LineString":case"OpenLayers.Geometry.LinearRing":case"OpenLayers.Geometry.Polygon":case"OpenLayers.Geometry.Curve":case"OpenLayers.Geometry.Surface":nodeType="olv:shape";break;default:break;}
59873 return nodeType;},setStyle:function(node,style,options,geometry){style=style||node._style;options=options||node._options;var fillColor=style.fillColor;if(node._geometryClass==="OpenLayers.Geometry.Point"){if(style.externalGraphic){if(style.graphicTitle){node.title=style.graphicTitle;}
59874 var width=style.graphicWidth||style.graphicHeight;var height=style.graphicHeight||style.graphicWidth;width=width?width:style.pointRadius*2;height=height?height:style.pointRadius*2;var resolution=this.getResolution();var xOffset=(style.graphicXOffset!=undefined)?style.graphicXOffset:-(0.5*width);var yOffset=(style.graphicYOffset!=undefined)?style.graphicYOffset:-(0.5*height);node.style.left=(((geometry.x/resolution-this.offset.x)+xOffset)|0)+"px";node.style.top=(((geometry.y/resolution-this.offset.y)-(yOffset+height))|0)+"px";node.style.width=width+"px";node.style.height=height+"px";node.style.flip="y";fillColor="none";options.isStroked=false;}else if(this.isComplexSymbol(style.graphicName)){var cache=this.importSymbol(style.graphicName);node.path=cache.path;node.coordorigin=cache.left+","+cache.bottom;var size=cache.size;node.coordsize=size+","+size;this.drawCircle(node,geometry,style.pointRadius);node.style.flip="y";}else{this.drawCircle(node,geometry,style.pointRadius);}}
59875 if(options.isFilled){node.fillcolor=fillColor;}else{node.filled="false";}
59876 var fills=node.getElementsByTagName("fill");var fill=(fills.length==0)?null:fills[0];if(!options.isFilled){if(fill){node.removeChild(fill);}}else{if(!fill){fill=this.createNode('olv:fill',node.id+"_fill");}
59877 fill.opacity=style.fillOpacity;if(node._geometryClass==="OpenLayers.Geometry.Point"&&style.externalGraphic){if(style.graphicOpacity){fill.opacity=style.graphicOpacity;}
59878 fill.src=style.externalGraphic;fill.type="frame";if(!(style.graphicWidth&&style.graphicHeight)){fill.aspect="atmost";}}
59879 if(fill.parentNode!=node){node.appendChild(fill);}}
59880 var rotation=style.rotation;if((rotation!==undefined||node._rotation!==undefined)){node._rotation=rotation;if(style.externalGraphic){this.graphicRotate(node,xOffset,yOffset,style);fill.opacity=0;}else if(node._geometryClass==="OpenLayers.Geometry.Point"){node.style.rotation=rotation||0;}}
59881 var strokes=node.getElementsByTagName("stroke");var stroke=(strokes.length==0)?null:strokes[0];if(!options.isStroked){node.stroked=false;if(stroke){stroke.on=false;}}else{if(!stroke){stroke=this.createNode('olv:stroke',node.id+"_stroke");node.appendChild(stroke);}
59882 stroke.on=true;stroke.color=style.strokeColor;stroke.weight=style.strokeWidth+"px";stroke.opacity=style.strokeOpacity;stroke.endcap=style.strokeLinecap=='butt'?'flat':(style.strokeLinecap||'round');if(style.strokeDashstyle){stroke.dashstyle=this.dashStyle(style);}}
59883 if(style.cursor!="inherit"&&style.cursor!=null){node.style.cursor=style.cursor;}
59884 return node;},graphicRotate:function(node,xOffset,yOffset,style){var style=style||node._style;var rotation=style.rotation||0;var aspectRatio,size;if(!(style.graphicWidth&&style.graphicHeight)){var img=new Image();img.onreadystatechange=OpenLayers.Function.bind(function(){if(img.readyState=="complete"||img.readyState=="interactive"){aspectRatio=img.width/img.height;size=Math.max(style.pointRadius*2,style.graphicWidth||0,style.graphicHeight||0);xOffset=xOffset*aspectRatio;style.graphicWidth=size*aspectRatio;style.graphicHeight=size;this.graphicRotate(node,xOffset,yOffset,style);}},this);img.src=style.externalGraphic;return;}else{size=Math.max(style.graphicWidth,style.graphicHeight);aspectRatio=style.graphicWidth/style.graphicHeight;}
59885 var width=Math.round(style.graphicWidth||size*aspectRatio);var height=Math.round(style.graphicHeight||size);node.style.width=width+"px";node.style.height=height+"px";var image=document.getElementById(node.id+"_image");if(!image){image=this.createNode("olv:imagedata",node.id+"_image");node.appendChild(image);}
59886 image.style.width=width+"px";image.style.height=height+"px";image.src=style.externalGraphic;image.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader("+"src='', sizingMethod='scale')";var rot=rotation*Math.PI/180;var sintheta=Math.sin(rot);var costheta=Math.cos(rot);var filter="progid:DXImageTransform.Microsoft.Matrix(M11="+costheta+",M12="+(-sintheta)+",M21="+sintheta+",M22="+costheta+",SizingMethod='auto expand')\n";var opacity=style.graphicOpacity||style.fillOpacity;if(opacity&&opacity!=1){filter+="progid:DXImageTransform.Microsoft.BasicImage(opacity="+
59887 opacity+")\n";}
59888 node.style.filter=filter;var centerPoint=new OpenLayers.Geometry.Point(-xOffset,-yOffset);var imgBox=new OpenLayers.Bounds(0,0,width,height).toGeometry();imgBox.rotate(style.rotation,centerPoint);var imgBounds=imgBox.getBounds();node.style.left=Math.round(parseInt(node.style.left)+imgBounds.left)+"px";node.style.top=Math.round(parseInt(node.style.top)-imgBounds.bottom)+"px";},postDraw:function(node){node.style.visibility="visible";var fillColor=node._style.fillColor;var strokeColor=node._style.strokeColor;if(fillColor=="none"&&node.fillcolor!=fillColor){node.fillcolor=fillColor;}
59889 if(strokeColor=="none"&&node.strokecolor!=strokeColor){node.strokecolor=strokeColor;}},setNodeDimension:function(node,geometry){var bbox=geometry.getBounds();if(bbox){var resolution=this.getResolution();var scaledBox=new OpenLayers.Bounds((bbox.left/resolution-this.offset.x)|0,(bbox.bottom/resolution-this.offset.y)|0,(bbox.right/resolution-this.offset.x)|0,(bbox.top/resolution-this.offset.y)|0);node.style.left=scaledBox.left+"px";node.style.top=scaledBox.top+"px";node.style.width=scaledBox.getWidth()+"px";node.style.height=scaledBox.getHeight()+"px";node.coordorigin=scaledBox.left+" "+scaledBox.top;node.coordsize=scaledBox.getWidth()+" "+scaledBox.getHeight();}},dashStyle:function(style){var dash=style.strokeDashstyle;switch(dash){case'solid':case'dot':case'dash':case'dashdot':case'longdash':case'longdashdot':return dash;default:var parts=dash.split(/[ ,]/);if(parts.length==2){if(1*parts[0]>=2*parts[1]){return"longdash";}
59890 return(parts[0]==1||parts[1]==1)?"dot":"dash";}else if(parts.length==4){return(1*parts[0]>=2*parts[1])?"longdashdot":"dashdot";}
59891 return"solid";}},createNode:function(type,id){var node=document.createElement(type);if(id){node.id=id;}
59892 node.unselectable='on';node.onselectstart=OpenLayers.Function.False;return node;},nodeTypeCompare:function(node,type){var subType=type;var splitIndex=subType.indexOf(":");if(splitIndex!=-1){subType=subType.substr(splitIndex+1);}
59893 var nodeName=node.nodeName;splitIndex=nodeName.indexOf(":");if(splitIndex!=-1){nodeName=nodeName.substr(splitIndex+1);}
59894 return(subType==nodeName);},createRenderRoot:function(){return this.nodeFactory(this.container.id+"_vmlRoot","div");},createRoot:function(suffix){return this.nodeFactory(this.container.id+suffix,"olv:group");},drawPoint:function(node,geometry){return this.drawCircle(node,geometry,1);},drawCircle:function(node,geometry,radius){if(!isNaN(geometry.x)&&!isNaN(geometry.y)){var resolution=this.getResolution();node.style.left=(((geometry.x/resolution-this.offset.x)|0)-radius)+"px";node.style.top=(((geometry.y/resolution-this.offset.y)|0)-radius)+"px";var diameter=radius*2;node.style.width=diameter+"px";node.style.height=diameter+"px";return node;}
59895 return false;},drawLineString:function(node,geometry){return this.drawLine(node,geometry,false);},drawLinearRing:function(node,geometry){return this.drawLine(node,geometry,true);},drawLine:function(node,geometry,closeLine){this.setNodeDimension(node,geometry);var resolution=this.getResolution();var numComponents=geometry.components.length;var parts=new Array(numComponents);var comp,x,y;for(var i=0;i<numComponents;i++){comp=geometry.components[i];x=(comp.x/resolution-this.offset.x)|0;y=(comp.y/resolution-this.offset.y)|0;parts[i]=" "+x+","+y+" l ";}
59896 var end=(closeLine)?" x e":" e";node.path="m"+parts.join("")+end;return node;},drawPolygon:function(node,geometry){this.setNodeDimension(node,geometry);var resolution=this.getResolution();var path=[];var linearRing,i,j,len,ilen,comp,x,y;for(j=0,len=geometry.components.length;j<len;j++){linearRing=geometry.components[j];path.push("m");for(i=0,ilen=linearRing.components.length;i<ilen;i++){comp=linearRing.components[i];x=(comp.x/resolution-this.offset.x)|0;y=(comp.y/resolution-this.offset.y)|0;path.push(" "+x+","+y);if(i==0){path.push(" l");}}
59897 path.push(" x ");}
59898 path.push("e");node.path=path.join("");return node;},drawRectangle:function(node,geometry){var resolution=this.getResolution();node.style.left=((geometry.x/resolution-this.offset.x)|0)+"px";node.style.top=((geometry.y/resolution-this.offset.y)|0)+"px";node.style.width=((geometry.width/resolution)|0)+"px";node.style.height=((geometry.height/resolution)|0)+"px";return node;},drawText:function(featureId,style,location){var label=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX,"olv:rect");var textbox=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX+"_textbox","olv:textbox");var resolution=this.getResolution();label.style.left=((location.x/resolution-this.offset.x)|0)+"px";label.style.top=((location.y/resolution-this.offset.y)|0)+"px";label.style.flip="y";textbox.innerText=style.label;if(style.fontColor){textbox.style.color=style.fontColor;}
59899 if(style.fontOpacity){textbox.style.filter='alpha(opacity='+(style.fontOpacity*100)+')';}
59900 if(style.fontFamily){textbox.style.fontFamily=style.fontFamily;}
59901 if(style.fontSize){textbox.style.fontSize=style.fontSize;}
59902 if(style.fontWeight){textbox.style.fontWeight=style.fontWeight;}
59903 if(style.labelSelect===true){label._featureId=featureId;textbox._featureId=featureId;textbox._geometry=location;textbox._geometryClass=location.CLASS_NAME;}
59904 textbox.style.whiteSpace="nowrap";textbox.inset="1px,0px,0px,0px";if(!label.parentNode){label.appendChild(textbox);this.textRoot.appendChild(label);}
59905 var align=style.labelAlign||"cm";if(align.length==1){align+="m";}
59906 var xshift=textbox.clientWidth*(OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(0,1)]);var yshift=textbox.clientHeight*(OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(1,1)]);label.style.left=parseInt(label.style.left)-xshift-1+"px";label.style.top=parseInt(label.style.top)+yshift+"px";},drawSurface:function(node,geometry){this.setNodeDimension(node,geometry);var resolution=this.getResolution();var path=[];var comp,x,y;for(var i=0,len=geometry.components.length;i<len;i++){comp=geometry.components[i];x=(comp.x/resolution-this.offset.x)|0;y=(comp.y/resolution-this.offset.y)|0;if((i%3)==0&&(i/3)==0){path.push("m");}else if((i%3)==1){path.push(" c");}
59907 path.push(" "+x+","+y);}
59908 path.push(" x e");node.path=path.join("");return node;},moveRoot:function(renderer){var layer=this.map.getLayer(renderer.container.id);if(layer instanceof OpenLayers.Layer.Vector.RootContainer){layer=this.map.getLayer(this.container.id);}
59909 layer&&layer.renderer.clear();OpenLayers.Renderer.Elements.prototype.moveRoot.apply(this,arguments);layer&&layer.redraw();},importSymbol:function(graphicName){var id=this.container.id+"-"+graphicName;var cache=this.symbolCache[id];if(cache){return cache;}
59910 var symbol=OpenLayers.Renderer.symbol[graphicName];if(!symbol){throw new Error(graphicName+' is not a valid symbol name');}
59911 var symbolExtent=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE,0,0);var pathitems=["m"];for(var i=0;i<symbol.length;i=i+2){var x=symbol[i];var y=symbol[i+1];symbolExtent.left=Math.min(symbolExtent.left,x);symbolExtent.bottom=Math.min(symbolExtent.bottom,y);symbolExtent.right=Math.max(symbolExtent.right,x);symbolExtent.top=Math.max(symbolExtent.top,y);pathitems.push(x);pathitems.push(y);if(i==0){pathitems.push("l");}}
59912 pathitems.push("x e");var path=pathitems.join(" ");var diff=(symbolExtent.getWidth()-symbolExtent.getHeight())/2;if(diff>0){symbolExtent.bottom=symbolExtent.bottom-diff;symbolExtent.top=symbolExtent.top+diff;}else{symbolExtent.left=symbolExtent.left+diff;symbolExtent.right=symbolExtent.right-diff;}
59913 cache={path:path,size:symbolExtent.getWidth(),left:symbolExtent.left,bottom:symbolExtent.bottom};this.symbolCache[id]=cache;return cache;},CLASS_NAME:"OpenLayers.Renderer.VML"});OpenLayers.Renderer.VML.LABEL_SHIFT={"l":0,"c":.5,"r":1,"t":0,"m":.5,"b":1};OpenLayers.Tile=OpenLayers.Class({EVENT_TYPES:["loadstart","loadend","reload","unload"],events:null,id:null,layer:null,url:null,bounds:null,size:null,position:null,isLoading:false,initialize:function(layer,position,bounds,url,size){this.layer=layer;this.position=position.clone();this.bounds=bounds.clone();this.url=url;this.size=size.clone();this.id=OpenLayers.Util.createUniqueID("Tile_");this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);},unload:function(){if(this.isLoading){this.isLoading=false;this.events.triggerEvent("unload");}},destroy:function(){this.layer=null;this.bounds=null;this.size=null;this.position=null;this.events.destroy();this.events=null;},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile(this.layer,this.position,this.bounds,this.url,this.size);}
59914 OpenLayers.Util.applyDefaults(obj,this);return obj;},draw:function(){var maxExtent=this.layer.maxExtent;var withinMaxExtent=(maxExtent&&this.bounds.intersectsBounds(maxExtent,false));this.shouldDraw=(withinMaxExtent||this.layer.displayOutsideMaxExtent);this.clear();return this.shouldDraw;},moveTo:function(bounds,position,redraw){if(redraw==null){redraw=true;}
59915 this.bounds=bounds.clone();this.position=position.clone();if(redraw){this.draw();}},clear:function(){},getBoundsFromBaseLayer:function(position){var msg=OpenLayers.i18n('reprojectDeprecated',{'layerName':this.layer.name});OpenLayers.Console.warn(msg);var topLeft=this.layer.map.getLonLatFromLayerPx(position);var bottomRightPx=position.clone();bottomRightPx.x+=this.size.w;bottomRightPx.y+=this.size.h;var bottomRight=this.layer.map.getLonLatFromLayerPx(bottomRightPx);if(topLeft.lon>bottomRight.lon){if(topLeft.lon<0){topLeft.lon=-180-(topLeft.lon+180);}else{bottomRight.lon=180+bottomRight.lon+180;}}
59916 var bounds=new OpenLayers.Bounds(topLeft.lon,bottomRight.lat,bottomRight.lon,topLeft.lat);return bounds;},showTile:function(){if(this.shouldDraw){this.show();}},show:function(){},hide:function(){},CLASS_NAME:"OpenLayers.Tile"});OpenLayers.Control.MouseToolbar=OpenLayers.Class(OpenLayers.Control.MouseDefaults,{mode:null,buttons:null,direction:"vertical",buttonClicked:null,initialize:function(position,direction){OpenLayers.Control.prototype.initialize.apply(this,arguments);this.position=new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,OpenLayers.Control.MouseToolbar.Y);if(position){this.position=position;}
59917 if(direction){this.direction=direction;}
59918 this.measureDivs=[];},destroy:function(){for(var btnId in this.buttons){var btn=this.buttons[btnId];btn.map=null;btn.events.destroy();}
59919 OpenLayers.Control.MouseDefaults.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);OpenLayers.Control.MouseDefaults.prototype.draw.apply(this,arguments);this.buttons={};var sz=new OpenLayers.Size(28,28);var centered=new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,0);this._addButton("zoombox","drag-rectangle-off.png","drag-rectangle-on.png",centered,sz,"Shift->Drag to zoom to area");centered=centered.add((this.direction=="vertical"?0:sz.w),(this.direction=="vertical"?sz.h:0));this._addButton("pan","panning-hand-off.png","panning-hand-on.png",centered,sz,"Drag the map to pan.");centered=centered.add((this.direction=="vertical"?0:sz.w),(this.direction=="vertical"?sz.h:0));this.switchModeTo("pan");return this.div;},_addButton:function(id,img,activeImg,xy,sz,title){var imgLocation=OpenLayers.Util.getImagesLocation()+img;var activeImgLocation=OpenLayers.Util.getImagesLocation()+activeImg;var btn=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MouseToolbar_"+id,xy,sz,imgLocation,"absolute");this.div.appendChild(btn);btn.imgLocation=imgLocation;btn.activeImgLocation=activeImgLocation;btn.events=new OpenLayers.Events(this,btn,null,true);btn.events.on({"mousedown":this.buttonDown,"mouseup":this.buttonUp,"dblclick":OpenLayers.Event.stop,scope:this});btn.action=id;btn.title=title;btn.alt=title;btn.map=this.map;this.buttons[id]=btn;return btn;},buttonDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59920 this.buttonClicked=evt.element.action;OpenLayers.Event.stop(evt);},buttonUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59921 if(this.buttonClicked!=null){if(this.buttonClicked==evt.element.action){this.switchModeTo(evt.element.action);}
59922 OpenLayers.Event.stop(evt);this.buttonClicked=null;}},defaultDblClick:function(evt){this.switchModeTo("pan");this.performedDrag=false;var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom+1);OpenLayers.Event.stop(evt);return false;},defaultMouseDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59923 this.mouseDragStart=evt.xy.clone();this.performedDrag=false;this.startViaKeyboard=false;if(evt.shiftKey&&this.mode!="zoombox"){this.switchModeTo("zoombox");this.startViaKeyboard=true;}else if(evt.altKey&&this.mode!="measure"){this.switchModeTo("measure");}else if(!this.mode){this.switchModeTo("pan");}
59924 switch(this.mode){case"zoombox":this.map.div.style.cursor="crosshair";this.zoomBox=OpenLayers.Util.createDiv('zoomBox',this.mouseDragStart,null,null,"absolute","2px solid red");this.zoomBox.style.backgroundColor="white";this.zoomBox.style.filter="alpha(opacity=50)";this.zoomBox.style.opacity="0.50";this.zoomBox.style.fontSize="1px";this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.viewPortDiv.appendChild(this.zoomBox);this.performedDrag=true;break;case"measure":var distance="";if(this.measureStart){var measureEnd=this.map.getLonLatFromViewPortPx(this.mouseDragStart);distance=OpenLayers.Util.distVincenty(this.measureStart,measureEnd);distance=Math.round(distance*100)/100;distance=distance+"km";this.measureStartBox=this.measureBox;}
59925 this.measureStart=this.map.getLonLatFromViewPortPx(this.mouseDragStart);;this.measureBox=OpenLayers.Util.createDiv(null,this.mouseDragStart.add(-2-parseInt(this.map.layerContainerDiv.style.left),-2-parseInt(this.map.layerContainerDiv.style.top)),null,null,"absolute");this.measureBox.style.width="4px";this.measureBox.style.height="4px";this.measureBox.style.fontSize="1px";this.measureBox.style.backgroundColor="red";this.measureBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBox);if(distance){this.measureBoxDistance=OpenLayers.Util.createDiv(null,this.mouseDragStart.add(-2-parseInt(this.map.layerContainerDiv.style.left),2-parseInt(this.map.layerContainerDiv.style.top)),null,null,"absolute");this.measureBoxDistance.innerHTML=distance;this.measureBoxDistance.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBoxDistance);this.measureDivs.push(this.measureBoxDistance);}
59926 this.measureBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBox);this.measureDivs.push(this.measureBox);break;default:this.map.div.style.cursor="move";break;}
59927 document.onselectstart=OpenLayers.Function.False;OpenLayers.Event.stop(evt);},switchModeTo:function(mode){if(mode!=this.mode){if(this.mode&&this.buttons[this.mode]){OpenLayers.Util.modifyAlphaImageDiv(this.buttons[this.mode],null,null,null,this.buttons[this.mode].imgLocation);}
59928 if(this.mode=="measure"&&mode!="measure"){for(var i=0,len=this.measureDivs.length;i<len;i++){if(this.measureDivs[i]){this.map.layerContainerDiv.removeChild(this.measureDivs[i]);}}
59929 this.measureDivs=[];this.measureStart=null;}
59930 this.mode=mode;if(this.buttons[mode]){OpenLayers.Util.modifyAlphaImageDiv(this.buttons[mode],null,null,null,this.buttons[mode].activeImgLocation);}
59931 switch(this.mode){case"zoombox":this.map.div.style.cursor="crosshair";break;default:this.map.div.style.cursor="";break;}}},leaveMode:function(){this.switchModeTo("pan");},defaultMouseMove:function(evt){if(this.mouseDragStart!=null){switch(this.mode){case"zoombox":var deltaX=Math.abs(this.mouseDragStart.x-evt.xy.x);var deltaY=Math.abs(this.mouseDragStart.y-evt.xy.y);this.zoomBox.style.width=Math.max(1,deltaX)+"px";this.zoomBox.style.height=Math.max(1,deltaY)+"px";if(evt.xy.x<this.mouseDragStart.x){this.zoomBox.style.left=evt.xy.x+"px";}
59932 if(evt.xy.y<this.mouseDragStart.y){this.zoomBox.style.top=evt.xy.y+"px";}
59933 break;default:var deltaX=this.mouseDragStart.x-evt.xy.x;var deltaY=this.mouseDragStart.y-evt.xy.y;var size=this.map.getSize();var newXY=new OpenLayers.Pixel(size.w/2+deltaX,size.h/2+deltaY);var newCenter=this.map.getLonLatFromViewPortPx(newXY);this.map.setCenter(newCenter,null,true);this.mouseDragStart=evt.xy.clone();}
59934 this.performedDrag=true;}},defaultMouseUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59935 switch(this.mode){case"zoombox":this.zoomBoxEnd(evt);if(this.startViaKeyboard){this.leaveMode();}
59936 break;case"pan":if(this.performedDrag){this.map.setCenter(this.map.center);}}
59937 document.onselectstart=null;this.mouseDragStart=null;this.map.div.style.cursor="default";},defaultMouseOut:function(evt){if(this.mouseDragStart!=null&&OpenLayers.Util.mouseLeft(evt,this.map.div)){if(this.zoomBox){this.removeZoomBox();if(this.startViaKeyboard){this.leaveMode();}}
59938 this.mouseDragStart=null;this.map.div.style.cursor="default";}},defaultClick:function(evt){if(this.performedDrag){this.performedDrag=false;return false;}},CLASS_NAME:"OpenLayers.Control.MouseToolbar"});OpenLayers.Control.MouseToolbar.X=6;OpenLayers.Control.MouseToolbar.Y=300;OpenLayers.Control.NavigationHistory=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOGGLE,previous:null,previousOptions:null,next:null,nextOptions:null,limit:50,autoActivate:true,clearOnDeactivate:false,registry:null,nextStack:null,previousStack:null,listeners:null,restoring:false,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.registry=OpenLayers.Util.extend({"moveend":this.getState},this.registry);var previousOptions={trigger:OpenLayers.Function.bind(this.previousTrigger,this),displayClass:this.displayClass+" "+this.displayClass+"Previous"};OpenLayers.Util.extend(previousOptions,this.previousOptions);this.previous=new OpenLayers.Control.Button(previousOptions);var nextOptions={trigger:OpenLayers.Function.bind(this.nextTrigger,this),displayClass:this.displayClass+" "+this.displayClass+"Next"};OpenLayers.Util.extend(nextOptions,this.nextOptions);this.next=new OpenLayers.Control.Button(nextOptions);this.clear();},onPreviousChange:function(state,length){if(state&&!this.previous.active){this.previous.activate();}else if(!state&&this.previous.active){this.previous.deactivate();}},onNextChange:function(state,length){if(state&&!this.next.active){this.next.activate();}else if(!state&&this.next.active){this.next.deactivate();}},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this);this.previous.destroy();this.next.destroy();this.deactivate();for(var prop in this){this[prop]=null;}},setMap:function(map){this.map=map;this.next.setMap(map);this.previous.setMap(map);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.next.draw();this.previous.draw();},previousTrigger:function(){var current=this.previousStack.shift();var state=this.previousStack.shift();if(state!=undefined){this.nextStack.unshift(current);this.previousStack.unshift(state);this.restoring=true;this.restore(state);this.restoring=false;this.onNextChange(this.nextStack[0],this.nextStack.length);this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);}else{this.previousStack.unshift(current);}
59939 return state;},nextTrigger:function(){var state=this.nextStack.shift();if(state!=undefined){this.previousStack.unshift(state);this.restoring=true;this.restore(state);this.restoring=false;this.onNextChange(this.nextStack[0],this.nextStack.length);this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);}
59940 return state;},clear:function(){this.previousStack=[];this.previous.deactivate();this.nextStack=[];this.next.deactivate();},getState:function(){return{center:this.map.getCenter(),resolution:this.map.getResolution(),projection:this.map.getProjectionObject(),units:this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units};},restore:function(state){var center,zoom;if(this.map.getProjectionObject()==state.projection){zoom=this.map.getZoomForResolution(state.resolution);center=state.center;}else{center=state.center.clone();center.transform(state.projection,this.map.getProjectionObject());var sourceUnits=state.units;var targetUnits=this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units;var resolutionFactor=sourceUnits&&targetUnits?OpenLayers.INCHES_PER_UNIT[sourceUnits]/OpenLayers.INCHES_PER_UNIT[targetUnits]:1;zoom=this.map.getZoomForResolution(resolutionFactor*state.resolution);}
59941 this.map.setCenter(center,zoom);},setListeners:function(){this.listeners={};for(var type in this.registry){this.listeners[type]=OpenLayers.Function.bind(function(){if(!this.restoring){var state=this.registry[type].apply(this,arguments);this.previousStack.unshift(state);if(this.previousStack.length>1){this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);}
59942 if(this.previousStack.length>(this.limit+1)){this.previousStack.pop();}
59943 if(this.nextStack.length>0){this.nextStack=[];this.onNextChange(null,0);}}
59944 return true;},this);}},activate:function(){var activated=false;if(this.map){if(OpenLayers.Control.prototype.activate.apply(this)){if(this.listeners==null){this.setListeners();}
59945 for(var type in this.listeners){this.map.events.register(type,this,this.listeners[type]);}
59946 activated=true;if(this.previousStack.length==0){this.initStack();}}}
59947 return activated;},initStack:function(){if(this.map.getCenter()){this.listeners.moveend();}},deactivate:function(){var deactivated=false;if(this.map){if(OpenLayers.Control.prototype.deactivate.apply(this)){for(var type in this.listeners){this.map.events.unregister(type,this,this.listeners[type]);}
59948 if(this.clearOnDeactivate){this.clear();}
59949 deactivated=true;}}
59950 return deactivated;},CLASS_NAME:"OpenLayers.Control.NavigationHistory"});OpenLayers.Control.PanPanel=OpenLayers.Class(OpenLayers.Control.Panel,{slideFactor:50,initialize:function(options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.Pan(OpenLayers.Control.Pan.NORTH,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.SOUTH,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.EAST,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.WEST,{slideFactor:this.slideFactor})]);},CLASS_NAME:"OpenLayers.Control.PanPanel"});OpenLayers.Control.PanZoomBar=OpenLayers.Class(OpenLayers.Control.PanZoom,{zoomStopWidth:18,zoomStopHeight:11,slider:null,sliderEvents:null,zoombarDiv:null,divEvents:null,zoomWorldIcon:false,forceFixedZoomLevel:false,mouseDragStart:null,zoomStart:null,initialize:function(){OpenLayers.Control.PanZoom.prototype.initialize.apply(this,arguments);},destroy:function(){this._removeZoomBar();this.map.events.un({"changebaselayer":this.redraw,scope:this});OpenLayers.Control.PanZoom.prototype.destroy.apply(this,arguments);delete this.mouseDragStart;delete this.zoomStart;},setMap:function(map){OpenLayers.Control.PanZoom.prototype.setMap.apply(this,arguments);this.map.events.register("changebaselayer",this,this.redraw);},redraw:function(){if(this.div!=null){this.removeButtons();this._removeZoomBar();}
59951 this.draw();},draw:function(px){OpenLayers.Control.prototype.draw.apply(this,arguments);px=this.position.clone();this.buttons=[];var sz=new OpenLayers.Size(18,18);var centered=new OpenLayers.Pixel(px.x+sz.w/2,px.y);var wposition=sz.w;if(this.zoomWorldIcon){centered=new OpenLayers.Pixel(px.x+sz.w,px.y);}
59952 this._addButton("panup","north-mini.png",centered,sz);px.y=centered.y+sz.h;this._addButton("panleft","west-mini.png",px,sz);if(this.zoomWorldIcon){this._addButton("zoomworld","zoom-world-mini.png",px.add(sz.w,0),sz);wposition*=2;}
59953 this._addButton("panright","east-mini.png",px.add(wposition,0),sz);this._addButton("pandown","south-mini.png",centered.add(0,sz.h*2),sz);this._addButton("zoomin","zoom-plus-mini.png",centered.add(0,sz.h*3+5),sz);centered=this._addZoomBar(centered.add(0,sz.h*4+5));this._addButton("zoomout","zoom-minus-mini.png",centered,sz);return this.div;},_addZoomBar:function(centered){var imgLocation=OpenLayers.Util.getImagesLocation();var id=this.id+"_"+this.map.id;var zoomsToEnd=this.map.getNumZoomLevels()-1-this.map.getZoom();var slider=OpenLayers.Util.createAlphaImageDiv(id,centered.add(-1,zoomsToEnd*this.zoomStopHeight),new OpenLayers.Size(20,9),imgLocation+"slider.png","absolute");this.slider=slider;this.sliderEvents=new OpenLayers.Events(this,slider,null,true,{includeXY:true});this.sliderEvents.on({"mousedown":this.zoomBarDown,"mousemove":this.zoomBarDrag,"mouseup":this.zoomBarUp,"dblclick":this.doubleClick,"click":this.doubleClick});var sz=new OpenLayers.Size();sz.h=this.zoomStopHeight*this.map.getNumZoomLevels();sz.w=this.zoomStopWidth;var div=null;if(OpenLayers.Util.alphaHack()){var id=this.id+"_"+this.map.id;div=OpenLayers.Util.createAlphaImageDiv(id,centered,new OpenLayers.Size(sz.w,this.zoomStopHeight),imgLocation+"zoombar.png","absolute",null,"crop");div.style.height=sz.h+"px";}else{div=OpenLayers.Util.createDiv('OpenLayers_Control_PanZoomBar_Zoombar'+this.map.id,centered,sz,imgLocation+"zoombar.png");}
59954 this.zoombarDiv=div;this.divEvents=new OpenLayers.Events(this,div,null,true,{includeXY:true});this.divEvents.on({"mousedown":this.divClick,"mousemove":this.passEventToSlider,"dblclick":this.doubleClick,"click":this.doubleClick});this.div.appendChild(div);this.startTop=parseInt(div.style.top);this.div.appendChild(slider);this.map.events.register("zoomend",this,this.moveZoomBar);centered=centered.add(0,this.zoomStopHeight*this.map.getNumZoomLevels());return centered;},_removeZoomBar:function(){this.sliderEvents.un({"mousedown":this.zoomBarDown,"mousemove":this.zoomBarDrag,"mouseup":this.zoomBarUp,"dblclick":this.doubleClick,"click":this.doubleClick});this.sliderEvents.destroy();this.divEvents.un({"mousedown":this.divClick,"mousemove":this.passEventToSlider,"dblclick":this.doubleClick,"click":this.doubleClick});this.divEvents.destroy();this.div.removeChild(this.zoombarDiv);this.zoombarDiv=null;this.div.removeChild(this.slider);this.slider=null;this.map.events.unregister("zoomend",this,this.moveZoomBar);},passEventToSlider:function(evt){this.sliderEvents.handleBrowserEvent(evt);},divClick:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59955 var y=evt.xy.y;var top=OpenLayers.Util.pagePosition(evt.object)[1];var levels=(y-top)/this.zoomStopHeight;if(this.forceFixedZoomLevel||!this.map.fractionalZoom){levels=Math.floor(levels);}
59956 var zoom=(this.map.getNumZoomLevels()-1)-levels;zoom=Math.min(Math.max(zoom,0),this.map.getNumZoomLevels()-1);this.map.zoomTo(zoom);OpenLayers.Event.stop(evt);},zoomBarDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59957 this.map.events.on({"mousemove":this.passEventToSlider,"mouseup":this.passEventToSlider,scope:this});this.mouseDragStart=evt.xy.clone();this.zoomStart=evt.xy.clone();this.div.style.cursor="move";this.zoombarDiv.offsets=null;OpenLayers.Event.stop(evt);},zoomBarDrag:function(evt){if(this.mouseDragStart!=null){var deltaY=this.mouseDragStart.y-evt.xy.y;var offsets=OpenLayers.Util.pagePosition(this.zoombarDiv);if((evt.clientY-offsets[1])>0&&(evt.clientY-offsets[1])<parseInt(this.zoombarDiv.style.height)-2){var newTop=parseInt(this.slider.style.top)-deltaY;this.slider.style.top=newTop+"px";this.mouseDragStart=evt.xy.clone();}
59958 OpenLayers.Event.stop(evt);}},zoomBarUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59959 if(this.mouseDragStart){this.div.style.cursor="";this.map.events.un({"mouseup":this.passEventToSlider,"mousemove":this.passEventToSlider,scope:this});var deltaY=this.zoomStart.y-evt.xy.y;var zoomLevel=this.map.zoom;if(!this.forceFixedZoomLevel&&this.map.fractionalZoom){zoomLevel+=deltaY/this.zoomStopHeight;zoomLevel=Math.min(Math.max(zoomLevel,0),this.map.getNumZoomLevels()-1);}else{zoomLevel+=Math.round(deltaY/this.zoomStopHeight);}
59960 this.map.zoomTo(zoomLevel);this.mouseDragStart=null;this.zoomStart=null;OpenLayers.Event.stop(evt);}},moveZoomBar:function(){var newTop=((this.map.getNumZoomLevels()-1)-this.map.getZoom())*this.zoomStopHeight+this.startTop+1;this.slider.style.top=newTop+"px";},CLASS_NAME:"OpenLayers.Control.PanZoomBar"});OpenLayers.Control.Permalink=OpenLayers.Class(OpenLayers.Control,{argParserClass:OpenLayers.Control.ArgParser,element:null,base:'',displayProjection:null,initialize:function(element,base,options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.element=OpenLayers.Util.getElement(element);this.base=base||document.location.href;},destroy:function(){if(this.element.parentNode==this.div){this.div.removeChild(this.element);}
59961 this.element=null;this.map.events.unregister('moveend',this,this.updateLink);OpenLayers.Control.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Control.prototype.setMap.apply(this,arguments);for(var i=0,len=this.map.controls.length;i<len;i++){var control=this.map.controls[i];if(control.CLASS_NAME==this.argParserClass.CLASS_NAME){if(control.displayProjection!=this.displayProjection){this.displayProjection=control.displayProjection;}
59962 break;}}
59963 if(i==this.map.controls.length){this.map.addControl(new this.argParserClass({'displayProjection':this.displayProjection}));}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.element){this.div.className=this.displayClass;this.element=document.createElement("a");this.element.innerHTML=OpenLayers.i18n("permalink");this.element.href="";this.div.appendChild(this.element);}
59964 this.map.events.on({'moveend':this.updateLink,'changelayer':this.updateLink,'changebaselayer':this.updateLink,scope:this});this.updateLink();return this.div;},updateLink:function(){var href=this.base;if(href.indexOf('?')!=-1){href=href.substring(0,href.indexOf('?'));}
59965 href+='?'+OpenLayers.Util.getParameterString(this.createParams());this.element.href=href;},createParams:function(center,zoom,layers){center=center||this.map.getCenter();var params=OpenLayers.Util.getParameters(this.base);if(center){params.zoom=zoom||this.map.getZoom();var lat=center.lat;var lon=center.lon;if(this.displayProjection){var mapPosition=OpenLayers.Projection.transform({x:lon,y:lat},this.map.getProjectionObject(),this.displayProjection);lon=mapPosition.x;lat=mapPosition.y;}
59966 params.lat=Math.round(lat*100000)/100000;params.lon=Math.round(lon*100000)/100000;layers=layers||this.map.layers;params.layers='';for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];if(layer.isBaseLayer){params.layers+=(layer==this.map.baseLayer)?"B":"0";}else{params.layers+=(layer.getVisibility())?"T":"F";}}}
59967 return params;},CLASS_NAME:"OpenLayers.Control.Permalink"});OpenLayers.Control.ZoomPanel=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.ZoomIn(),new OpenLayers.Control.ZoomToMaxExtent(),new OpenLayers.Control.ZoomOut()]);},CLASS_NAME:"OpenLayers.Control.ZoomPanel"});OpenLayers.Format.CSWGetDomain=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Format.CSWGetDomain.DEFAULTS);var cls=OpenLayers.Format.CSWGetDomain["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported CSWGetDomain version: "+options.version;}
59968 return new cls(options);};OpenLayers.Format.CSWGetDomain.DEFAULTS={"version":"2.0.2"};OpenLayers.Format.CSWGetRecords=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Format.CSWGetRecords.DEFAULTS);var cls=OpenLayers.Format.CSWGetRecords["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported CSWGetRecords version: "+options.version;}
59969 return new cls(options);};OpenLayers.Format.CSWGetRecords.DEFAULTS={"version":"2.0.2"};OpenLayers.Format.JSON=OpenLayers.Class(OpenLayers.Format,{indent:"    ",space:" ",newline:"\n",level:0,pretty:false,initialize:function(options){OpenLayers.Format.prototype.initialize.apply(this,[options]);},read:function(json,filter){try{if(/^[\],:{}\s]*$/.test(json.replace(/\\["\\\/bfnrtu]/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){var object=eval('('+json+')');if(typeof filter==='function'){function walk(k,v){if(v&&typeof v==='object'){for(var i in v){if(v.hasOwnProperty(i)){v[i]=walk(i,v[i]);}}}
59970 return filter(k,v);}
59971 object=walk('',object);}
59972 if(this.keepData){this.data=object;}
59973 return object;}}catch(e){}
59974 return null;},write:function(value,pretty){this.pretty=!!pretty;var json=null;var type=typeof value;if(this.serialize[type]){try{json=this.serialize[type].apply(this,[value]);}catch(err){OpenLayers.Console.error("Trouble serializing: "+err);}}
59975 return json;},writeIndent:function(){var pieces=[];if(this.pretty){for(var i=0;i<this.level;++i){pieces.push(this.indent);}}
59976 return pieces.join('');},writeNewline:function(){return(this.pretty)?this.newline:'';},writeSpace:function(){return(this.pretty)?this.space:'';},serialize:{'object':function(object){if(object==null){return"null";}
59977 if(object.constructor==Date){return this.serialize.date.apply(this,[object]);}
59978 if(object.constructor==Array){return this.serialize.array.apply(this,[object]);}
59979 var pieces=['{'];this.level+=1;var key,keyJSON,valueJSON;var addComma=false;for(key in object){if(object.hasOwnProperty(key)){keyJSON=OpenLayers.Format.JSON.prototype.write.apply(this,[key,this.pretty]);valueJSON=OpenLayers.Format.JSON.prototype.write.apply(this,[object[key],this.pretty]);if(keyJSON!=null&&valueJSON!=null){if(addComma){pieces.push(',');}
59980 pieces.push(this.writeNewline(),this.writeIndent(),keyJSON,':',this.writeSpace(),valueJSON);addComma=true;}}}
59981 this.level-=1;pieces.push(this.writeNewline(),this.writeIndent(),'}');return pieces.join('');},'array':function(array){var json;var pieces=['['];this.level+=1;for(var i=0,len=array.length;i<len;++i){json=OpenLayers.Format.JSON.prototype.write.apply(this,[array[i],this.pretty]);if(json!=null){if(i>0){pieces.push(',');}
59982 pieces.push(this.writeNewline(),this.writeIndent(),json);}}
59983 this.level-=1;pieces.push(this.writeNewline(),this.writeIndent(),']');return pieces.join('');},'string':function(string){var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};if(/["\\\x00-\x1f]/.test(string)){return'"'+string.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c;}
59984 c=b.charCodeAt();return'\\u00'+
59985 Math.floor(c/16).toString(16)+
59986 (c%16).toString(16);})+'"';}
59987 return'"'+string+'"';},'number':function(number){return isFinite(number)?String(number):"null";},'boolean':function(bool){return String(bool);},'date':function(date){function format(number){return(number<10)?'0'+number:number;}
59988 return'"'+date.getFullYear()+'-'+
59989 format(date.getMonth()+1)+'-'+
59990 format(date.getDate())+'T'+
59991 format(date.getHours())+':'+
59992 format(date.getMinutes())+':'+
59993 format(date.getSeconds())+'"';}},CLASS_NAME:"OpenLayers.Format.JSON"});OpenLayers.Format.WFST=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Format.WFST.DEFAULTS);var cls=OpenLayers.Format.WFST["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported WFST version: "+options.version;}
59994 return new cls(options);};OpenLayers.Format.WFST.DEFAULTS={"version":"1.0.0"};OpenLayers.Format.XML=OpenLayers.Class(OpenLayers.Format,{namespaces:null,namespaceAlias:null,defaultPrefix:null,readers:{},writers:{},xmldom:null,initialize:function(options){if(window.ActiveXObject){this.xmldom=new ActiveXObject("Microsoft.XMLDOM");}
59995 OpenLayers.Format.prototype.initialize.apply(this,[options]);this.namespaces=OpenLayers.Util.extend({},this.namespaces);this.namespaceAlias={};for(var alias in this.namespaces){this.namespaceAlias[this.namespaces[alias]]=alias;}},destroy:function(){this.xmldom=null;OpenLayers.Format.prototype.destroy.apply(this,arguments);},setNamespace:function(alias,uri){this.namespaces[alias]=uri;this.namespaceAlias[uri]=alias;},read:function(text){var index=text.indexOf('<');if(index>0){text=text.substring(index);}
59996 var node=OpenLayers.Util.Try(OpenLayers.Function.bind((function(){var xmldom;if(window.ActiveXObject&&!this.xmldom){xmldom=new ActiveXObject("Microsoft.XMLDOM");}else{xmldom=this.xmldom;}
59997 xmldom.loadXML(text);return xmldom;}),this),function(){return new DOMParser().parseFromString(text,'text/xml');},function(){var req=new XMLHttpRequest();req.open("GET","data:"+"text/xml"+";charset=utf-8,"+encodeURIComponent(text),false);if(req.overrideMimeType){req.overrideMimeType("text/xml");}
59998 req.send(null);return req.responseXML;});if(this.keepData){this.data=node;}
59999 return node;},write:function(node){var data;if(this.xmldom){data=node.xml;}else{var serializer=new XMLSerializer();if(node.nodeType==1){var doc=document.implementation.createDocument("","",null);if(doc.importNode){node=doc.importNode(node,true);}
60000 doc.appendChild(node);data=serializer.serializeToString(doc);}else{data=serializer.serializeToString(node);}}
60001 return data;},createElementNS:function(uri,name){var element;if(this.xmldom){if(typeof uri=="string"){element=this.xmldom.createNode(1,name,uri);}else{element=this.xmldom.createNode(1,name,"");}}else{element=document.createElementNS(uri,name);}
60002 return element;},createTextNode:function(text){var node;if(typeof text!=="string"){text=String(text);}
60003 if(this.xmldom){node=this.xmldom.createTextNode(text);}else{node=document.createTextNode(text);}
60004 return node;},getElementsByTagNameNS:function(node,uri,name){var elements=[];if(node.getElementsByTagNameNS){elements=node.getElementsByTagNameNS(uri,name);}else{var allNodes=node.getElementsByTagName("*");var potentialNode,fullName;for(var i=0,len=allNodes.length;i<len;++i){potentialNode=allNodes[i];fullName=(potentialNode.prefix)?(potentialNode.prefix+":"+name):name;if((name=="*")||(fullName==potentialNode.nodeName)){if((uri=="*")||(uri==potentialNode.namespaceURI)){elements.push(potentialNode);}}}}
60005 return elements;},getAttributeNodeNS:function(node,uri,name){var attributeNode=null;if(node.getAttributeNodeNS){attributeNode=node.getAttributeNodeNS(uri,name);}else{var attributes=node.attributes;var potentialNode,fullName;for(var i=0,len=attributes.length;i<len;++i){potentialNode=attributes[i];if(potentialNode.namespaceURI==uri){fullName=(potentialNode.prefix)?(potentialNode.prefix+":"+name):name;if(fullName==potentialNode.nodeName){attributeNode=potentialNode;break;}}}}
60006 return attributeNode;},getAttributeNS:function(node,uri,name){var attributeValue="";if(node.getAttributeNS){attributeValue=node.getAttributeNS(uri,name)||"";}else{var attributeNode=this.getAttributeNodeNS(node,uri,name);if(attributeNode){attributeValue=attributeNode.nodeValue;}}
60007 return attributeValue;},getChildValue:function(node,def){var value=def||"";if(node){for(var child=node.firstChild;child;child=child.nextSibling){switch(child.nodeType){case 3:case 4:value+=child.nodeValue;}}}
60008 return value;},concatChildValues:function(node,def){var value="";var child=node.firstChild;var childValue;while(child){childValue=child.nodeValue;if(childValue){value+=childValue;}
60009 child=child.nextSibling;}
60010 if(value==""&&def!=undefined){value=def;}
60011 return value;},isSimpleContent:function(node){var simple=true;for(var child=node.firstChild;child;child=child.nextSibling){if(child.nodeType===1){simple=false;break;}}
60012 return simple;},contentType:function(node){var simple=false,complex=false;var type=OpenLayers.Format.XML.CONTENT_TYPE.EMPTY;for(var child=node.firstChild;child;child=child.nextSibling){switch(child.nodeType){case 1:complex=true;break;case 8:break;default:simple=true;}
60013 if(complex&&simple){break;}}
60014 if(complex&&simple){type=OpenLayers.Format.XML.CONTENT_TYPE.MIXED;}else if(complex){return OpenLayers.Format.XML.CONTENT_TYPE.COMPLEX;}else if(simple){return OpenLayers.Format.XML.CONTENT_TYPE.SIMPLE;}
60015 return type;},hasAttributeNS:function(node,uri,name){var found=false;if(node.hasAttributeNS){found=node.hasAttributeNS(uri,name);}else{found=!!this.getAttributeNodeNS(node,uri,name);}
60016 return found;},setAttributeNS:function(node,uri,name,value){if(node.setAttributeNS){node.setAttributeNS(uri,name,value);}else{if(this.xmldom){if(uri){var attribute=node.ownerDocument.createNode(2,name,uri);attribute.nodeValue=value;node.setAttributeNode(attribute);}else{node.setAttribute(name,value);}}else{throw"setAttributeNS not implemented";}}},createElementNSPlus:function(name,options){options=options||{};var uri=options.uri||this.namespaces[options.prefix];if(!uri){var loc=name.indexOf(":");uri=this.namespaces[name.substring(0,loc)];}
60017 if(!uri){uri=this.namespaces[this.defaultPrefix];}
60018 var node=this.createElementNS(uri,name);if(options.attributes){this.setAttributes(node,options.attributes);}
60019 var value=options.value;if(value!=null){node.appendChild(this.createTextNode(value));}
60020 return node;},setAttributes:function(node,obj){var value,uri;for(var name in obj){if(obj[name]!=null&&obj[name].toString){value=obj[name].toString();uri=this.namespaces[name.substring(0,name.indexOf(":"))]||null;this.setAttributeNS(node,uri,name,value);}}},readNode:function(node,obj){if(!obj){obj={};}
60021 var group=this.readers[node.namespaceURI?this.namespaceAlias[node.namespaceURI]:this.defaultPrefix];if(group){var local=node.localName||node.nodeName.split(":").pop();var reader=group[local]||group["*"];if(reader){reader.apply(this,[node,obj]);}}
60022 return obj;},readChildNodes:function(node,obj){if(!obj){obj={};}
60023 var children=node.childNodes;var child;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){this.readNode(child,obj);}}
60024 return obj;},writeNode:function(name,obj,parent){var prefix,local;var split=name.indexOf(":");if(split>0){prefix=name.substring(0,split);local=name.substring(split+1);}else{if(parent){prefix=this.namespaceAlias[parent.namespaceURI];}else{prefix=this.defaultPrefix;}
60025 local=name;}
60026 var child=this.writers[prefix][local].apply(this,[obj]);if(parent){parent.appendChild(child);}
60027 return child;},getChildEl:function(node,name,uri){return node&&this.getThisOrNextEl(node.firstChild,name,uri);},getNextEl:function(node,name,uri){return node&&this.getThisOrNextEl(node.nextSibling,name,uri);},getThisOrNextEl:function(node,name,uri){outer:for(var sibling=node;sibling;sibling=sibling.nextSibling){switch(sibling.nodeType){case 1:if((!name||name===(sibling.localName||sibling.nodeName.split(":").pop()))&&(!uri||uri===sibling.namespaceURI)){break outer;}
60028 sibling=null;break outer;case 3:if(/^\s*$/.test(sibling.nodeValue)){break;}
60029 case 4:case 6:case 12:case 10:case 11:sibling=null;break outer;}}
60030 return sibling||null;},lookupNamespaceURI:function(node,prefix){var uri=null;if(node){if(node.lookupNamespaceURI){uri=node.lookupNamespaceURI(prefix);}else{outer:switch(node.nodeType){case 1:if(node.namespaceURI!==null&&node.prefix===prefix){uri=node.namespaceURI;break outer;}
60031 var len=node.attributes.length;if(len){var attr;for(var i=0;i<len;++i){attr=node.attributes[i];if(attr.prefix==="xmlns"&&attr.name==="xmlns:"+prefix){uri=attr.value||null;break outer;}else if(attr.name==="xmlns"&&prefix===null){uri=attr.value||null;break outer;}}}
60032 uri=this.lookupNamespaceURI(node.parentNode,prefix);break outer;case 2:uri=this.lookupNamespaceURI(node.ownerElement,prefix);break outer;case 9:uri=this.lookupNamespaceURI(node.documentElement,prefix);break outer;case 6:case 12:case 10:case 11:break outer;default:uri=this.lookupNamespaceURI(node.parentNode,prefix);break outer;}}}
60033 return uri;},CLASS_NAME:"OpenLayers.Format.XML"});OpenLayers.Format.XML.CONTENT_TYPE={EMPTY:0,SIMPLE:1,COMPLEX:2,MIXED:3};OpenLayers.Format.XML.lookupNamespaceURI=OpenLayers.Function.bind(OpenLayers.Format.XML.prototype.lookupNamespaceURI,OpenLayers.Format.XML.prototype);OpenLayers.Handler=OpenLayers.Class({id:null,control:null,map:null,keyMask:null,active:false,evt:null,initialize:function(control,callbacks,options){OpenLayers.Util.extend(this,options);this.control=control;this.callbacks=callbacks;var map=this.map||control.map;if(map){this.setMap(map);}
60034 this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},setMap:function(map){this.map=map;},checkModifiers:function(evt){if(this.keyMask==null){return true;}
60035 var keyModifiers=(evt.shiftKey?OpenLayers.Handler.MOD_SHIFT:0)|(evt.ctrlKey?OpenLayers.Handler.MOD_CTRL:0)|(evt.altKey?OpenLayers.Handler.MOD_ALT:0);return(keyModifiers==this.keyMask);},activate:function(){if(this.active){return false;}
60036 var events=OpenLayers.Events.prototype.BROWSER_EVENTS;for(var i=0,len=events.length;i<len;i++){if(this[events[i]]){this.register(events[i],this[events[i]]);}}
60037 this.active=true;return true;},deactivate:function(){if(!this.active){return false;}
60038 var events=OpenLayers.Events.prototype.BROWSER_EVENTS;for(var i=0,len=events.length;i<len;i++){if(this[events[i]]){this.unregister(events[i],this[events[i]]);}}
60039 this.active=false;return true;},callback:function(name,args){if(name&&this.callbacks[name]){this.callbacks[name].apply(this.control,args);}},register:function(name,method){this.map.events.registerPriority(name,this,method);this.map.events.registerPriority(name,this,this.setEvent);},unregister:function(name,method){this.map.events.unregister(name,this,method);this.map.events.unregister(name,this,this.setEvent);},setEvent:function(evt){this.evt=evt;return true;},destroy:function(){this.deactivate();this.control=this.map=null;},CLASS_NAME:"OpenLayers.Handler"});OpenLayers.Handler.MOD_NONE=0;OpenLayers.Handler.MOD_SHIFT=1;OpenLayers.Handler.MOD_CTRL=2;OpenLayers.Handler.MOD_ALT=4;OpenLayers.Map=OpenLayers.Class({Z_INDEX_BASE:{BaseLayer:100,Overlay:325,Feature:725,Popup:750,Control:1000},EVENT_TYPES:["preaddlayer","addlayer","removelayer","changelayer","movestart","move","moveend","zoomend","popupopen","popupclose","addmarker","removemarker","clearmarkers","mouseover","mouseout","mousemove","dragstart","drag","dragend","changebaselayer"],id:null,fractionalZoom:false,events:null,allOverlays:false,div:null,dragging:false,size:null,viewPortDiv:null,layerContainerOrigin:null,layerContainerDiv:null,layers:null,controls:null,popups:null,baseLayer:null,center:null,resolution:null,zoom:0,panRatio:1.5,viewRequestID:0,tileSize:null,projection:"EPSG:4326",units:'degrees',resolutions:null,maxResolution:1.40625,minResolution:null,maxScale:null,minScale:null,maxExtent:null,minExtent:null,restrictedExtent:null,numZoomLevels:16,theme:null,displayProjection:null,fallThrough:true,panTween:null,eventListeners:null,panMethod:OpenLayers.Easing.Expo.easeOut,panDuration:50,paddingForPopups:null,initialize:function(div,options){if(arguments.length===1&&typeof div==="object"){options=div;div=options&&options.div;}
60040 this.tileSize=new OpenLayers.Size(OpenLayers.Map.TILE_WIDTH,OpenLayers.Map.TILE_HEIGHT);this.maxExtent=new OpenLayers.Bounds(-180,-90,180,90);this.paddingForPopups=new OpenLayers.Bounds(15,15,15,15);this.theme=OpenLayers._getScriptLocation()?OpenLayers._getScriptLocation()+'theme/default/style.css':null;OpenLayers.Util.extend(this,options);this.layers=[];this.id=OpenLayers.Util.createUniqueID("OpenLayers.Map_");this.div=OpenLayers.Util.getElement(div);if(!this.div){this.div=document.createElement("div");this.div.style.height="1px";this.div.style.width="1px";}
60041 OpenLayers.Element.addClass(this.div,'olMap');var id=this.id+"_OpenLayers_ViewPort";this.viewPortDiv=OpenLayers.Util.createDiv(id,null,null,null,"relative",null,"hidden");this.viewPortDiv.style.width="100%";this.viewPortDiv.style.height="100%";this.viewPortDiv.className="olMapViewport";this.div.appendChild(this.viewPortDiv);id=this.id+"_OpenLayers_Container";this.layerContainerDiv=OpenLayers.Util.createDiv(id);this.layerContainerDiv.style.zIndex=this.Z_INDEX_BASE['Popup']-1;this.viewPortDiv.appendChild(this.layerContainerDiv);this.events=new OpenLayers.Events(this,this.div,this.EVENT_TYPES,this.fallThrough,{includeXY:true});this.updateSize();if(this.eventListeners instanceof Object){this.events.on(this.eventListeners);}
60042 this.events.register("movestart",this,this.updateSize);if(OpenLayers.String.contains(navigator.appName,"Microsoft")){this.events.register("resize",this,this.updateSize);}else{this.updateSizeDestroy=OpenLayers.Function.bind(this.updateSize,this);OpenLayers.Event.observe(window,'resize',this.updateSizeDestroy);}
60043 if(this.theme){var addNode=true;var nodes=document.getElementsByTagName('link');for(var i=0,len=nodes.length;i<len;++i){if(OpenLayers.Util.isEquivalentUrl(nodes.item(i).href,this.theme)){addNode=false;break;}}
60044 if(addNode){var cssNode=document.createElement('link');cssNode.setAttribute('rel','stylesheet');cssNode.setAttribute('type','text/css');cssNode.setAttribute('href',this.theme);document.getElementsByTagName('head')[0].appendChild(cssNode);}}
60045 if(this.controls==null){if(OpenLayers.Control!=null){this.controls=[new OpenLayers.Control.Navigation(),new OpenLayers.Control.PanZoom(),new OpenLayers.Control.ArgParser(),new OpenLayers.Control.Attribution()];}else{this.controls=[];}}
60046 for(var i=0,len=this.controls.length;i<len;i++){this.addControlToMap(this.controls[i]);}
60047 this.popups=[];this.unloadDestroy=OpenLayers.Function.bind(this.destroy,this);OpenLayers.Event.observe(window,'unload',this.unloadDestroy);if(options&&options.layers){this.addLayers(options.layers);if(options.center){this.setCenter(options.center,options.zoom);}}},render:function(div){this.div=OpenLayers.Util.getElement(div);OpenLayers.Element.addClass(this.div,'olMap');this.events.attachToElement(this.div);this.viewPortDiv.parentNode.removeChild(this.viewPortDiv);this.div.appendChild(this.viewPortDiv);this.updateSize();},unloadDestroy:null,updateSizeDestroy:null,destroy:function(){if(!this.unloadDestroy){return false;}
60048 if(this.panTween){this.panTween.stop();this.panTween=null;}
60049 OpenLayers.Event.stopObserving(window,'unload',this.unloadDestroy);this.unloadDestroy=null;if(this.updateSizeDestroy){OpenLayers.Event.stopObserving(window,'resize',this.updateSizeDestroy);}else{this.events.unregister("resize",this,this.updateSize);}
60050 this.paddingForPopups=null;if(this.controls!=null){for(var i=this.controls.length-1;i>=0;--i){this.controls[i].destroy();}
60051 this.controls=null;}
60052 if(this.layers!=null){for(var i=this.layers.length-1;i>=0;--i){this.layers[i].destroy(false);}
60053 this.layers=null;}
60054 if(this.viewPortDiv){this.div.removeChild(this.viewPortDiv);}
60055 this.viewPortDiv=null;if(this.eventListeners){this.events.un(this.eventListeners);this.eventListeners=null;}
60056 this.events.destroy();this.events=null;},setOptions:function(options){OpenLayers.Util.extend(this,options);},getTileSize:function(){return this.tileSize;},getBy:function(array,property,match){var test=(typeof match.test=="function");var found=OpenLayers.Array.filter(this[array],function(item){return item[property]==match||(test&&match.test(item[property]));});return found;},getLayersBy:function(property,match){return this.getBy("layers",property,match);},getLayersByName:function(match){return this.getLayersBy("name",match);},getLayersByClass:function(match){return this.getLayersBy("CLASS_NAME",match);},getControlsBy:function(property,match){return this.getBy("controls",property,match);},getControlsByClass:function(match){return this.getControlsBy("CLASS_NAME",match);},getLayer:function(id){var foundLayer=null;for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer.id==id){foundLayer=layer;break;}}
60057 return foundLayer;},setLayerZIndex:function(layer,zIdx){layer.setZIndex(this.Z_INDEX_BASE[layer.isBaseLayer?'BaseLayer':'Overlay']
60058 +zIdx*5);},resetLayersZIndex:function(){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];this.setLayerZIndex(layer,i);}},addLayer:function(layer){for(var i=0,len=this.layers.length;i<len;i++){if(this.layers[i]==layer){var msg=OpenLayers.i18n('layerAlreadyAdded',{'layerName':layer.name});OpenLayers.Console.warn(msg);return false;}}
60059 if(this.allOverlays){layer.isBaseLayer=false;}
60060 if(this.events.triggerEvent("preaddlayer",{layer:layer})===false){return;}
60061 layer.div.className="olLayerDiv";layer.div.style.overflow="";this.setLayerZIndex(layer,this.layers.length);if(layer.isFixed){this.viewPortDiv.appendChild(layer.div);}else{this.layerContainerDiv.appendChild(layer.div);}
60062 this.layers.push(layer);layer.setMap(this);if(layer.isBaseLayer||(this.allOverlays&&!this.baseLayer)){if(this.baseLayer==null){this.setBaseLayer(layer);}else{layer.setVisibility(false);}}else{layer.redraw();}
60063 this.events.triggerEvent("addlayer",{layer:layer});layer.afterAdd();},addLayers:function(layers){for(var i=0,len=layers.length;i<len;i++){this.addLayer(layers[i]);}},removeLayer:function(layer,setNewBaseLayer){if(setNewBaseLayer==null){setNewBaseLayer=true;}
60064 if(layer.isFixed){this.viewPortDiv.removeChild(layer.div);}else{this.layerContainerDiv.removeChild(layer.div);}
60065 OpenLayers.Util.removeItem(this.layers,layer);layer.removeMap(this);layer.map=null;if(this.baseLayer==layer){this.baseLayer=null;if(setNewBaseLayer){for(var i=0,len=this.layers.length;i<len;i++){var iLayer=this.layers[i];if(iLayer.isBaseLayer||this.allOverlays){this.setBaseLayer(iLayer);break;}}}}
60066 this.resetLayersZIndex();this.events.triggerEvent("removelayer",{layer:layer});},getNumLayers:function(){return this.layers.length;},getLayerIndex:function(layer){return OpenLayers.Util.indexOf(this.layers,layer);},setLayerIndex:function(layer,idx){var base=this.getLayerIndex(layer);if(idx<0){idx=0;}else if(idx>this.layers.length){idx=this.layers.length;}
60067 if(base!=idx){this.layers.splice(base,1);this.layers.splice(idx,0,layer);for(var i=0,len=this.layers.length;i<len;i++){this.setLayerZIndex(this.layers[i],i);}
60068 this.events.triggerEvent("changelayer",{layer:layer,property:"order"});if(this.allOverlays){if(idx===0){this.setBaseLayer(layer);}else if(this.baseLayer!==this.layers[0]){this.setBaseLayer(this.layers[0]);}}}},raiseLayer:function(layer,delta){var idx=this.getLayerIndex(layer)+delta;this.setLayerIndex(layer,idx);},setBaseLayer:function(newBaseLayer){if(newBaseLayer!=this.baseLayer){if(OpenLayers.Util.indexOf(this.layers,newBaseLayer)!=-1){var center=this.getCenter();var newResolution=OpenLayers.Util.getResolutionFromScale(this.getScale(),newBaseLayer.units);if(this.baseLayer!=null&&!this.allOverlays){this.baseLayer.setVisibility(false);}
60069 this.baseLayer=newBaseLayer;this.viewRequestID++;if(!this.allOverlays||this.baseLayer.visibility){this.baseLayer.setVisibility(true);}
60070 if(center!=null){var newZoom=this.getZoomForResolution(newResolution||this.resolution,true);this.setCenter(center,newZoom,false,true);}
60071 this.events.triggerEvent("changebaselayer",{layer:this.baseLayer});}}},addControl:function(control,px){this.controls.push(control);this.addControlToMap(control,px);},addControls:function(controls,pixels){var pxs=(arguments.length===1)?[]:pixels;for(var i=0,len=controls.length;i<len;i++){var ctrl=controls[i];var px=(pxs[i])?pxs[i]:null;this.addControl(ctrl,px);}},addControlToMap:function(control,px){control.outsideViewport=(control.div!=null);if(this.displayProjection&&!control.displayProjection){control.displayProjection=this.displayProjection;}
60072 control.setMap(this);var div=control.draw(px);if(div){if(!control.outsideViewport){div.style.zIndex=this.Z_INDEX_BASE['Control']+
60073 this.controls.length;this.viewPortDiv.appendChild(div);}}
60074 if(control.autoActivate){control.activate();}},getControl:function(id){var returnControl=null;for(var i=0,len=this.controls.length;i<len;i++){var control=this.controls[i];if(control.id==id){returnControl=control;break;}}
60075 return returnControl;},removeControl:function(control){if((control)&&(control==this.getControl(control.id))){if(control.div&&(control.div.parentNode==this.viewPortDiv)){this.viewPortDiv.removeChild(control.div);}
60076 OpenLayers.Util.removeItem(this.controls,control);}},addPopup:function(popup,exclusive){if(exclusive){for(var i=this.popups.length-1;i>=0;--i){this.removePopup(this.popups[i]);}}
60077 popup.map=this;this.popups.push(popup);var popupDiv=popup.draw();if(popupDiv){popupDiv.style.zIndex=this.Z_INDEX_BASE['Popup']+
60078 this.popups.length;this.layerContainerDiv.appendChild(popupDiv);}},removePopup:function(popup){OpenLayers.Util.removeItem(this.popups,popup);if(popup.div){try{this.layerContainerDiv.removeChild(popup.div);}
60079 catch(e){}}
60080 popup.map=null;},getSize:function(){var size=null;if(this.size!=null){size=this.size.clone();}
60081 return size;},updateSize:function(){var newSize=this.getCurrentSize();if(newSize&&!isNaN(newSize.h)&&!isNaN(newSize.w)){this.events.clearMouseCache();var oldSize=this.getSize();if(oldSize==null){this.size=oldSize=newSize;}
60082 if(!newSize.equals(oldSize)){this.size=newSize;for(var i=0,len=this.layers.length;i<len;i++){this.layers[i].onMapResize();}
60083 var center=this.getCenter();if(this.baseLayer!=null&&center!=null){var zoom=this.getZoom();this.zoom=null;this.setCenter(center,zoom);}}}},getCurrentSize:function(){var size=new OpenLayers.Size(this.div.clientWidth,this.div.clientHeight);if(size.w==0&&size.h==0||isNaN(size.w)&&isNaN(size.h)){size.w=this.div.offsetWidth;size.h=this.div.offsetHeight;}
60084 if(size.w==0&&size.h==0||isNaN(size.w)&&isNaN(size.h)){size.w=parseInt(this.div.style.width);size.h=parseInt(this.div.style.height);}
60085 return size;},calculateBounds:function(center,resolution){var extent=null;if(center==null){center=this.getCenter();}
60086 if(resolution==null){resolution=this.getResolution();}
60087 if((center!=null)&&(resolution!=null)){var size=this.getSize();var w_deg=size.w*resolution;var h_deg=size.h*resolution;extent=new OpenLayers.Bounds(center.lon-w_deg/2,center.lat-h_deg/2,center.lon+w_deg/2,center.lat+h_deg/2);}
60088 return extent;},getCenter:function(){var center=null;if(this.center){center=this.center.clone();}
60089 return center;},getZoom:function(){return this.zoom;},pan:function(dx,dy,options){options=OpenLayers.Util.applyDefaults(options,{animate:true,dragging:false});var centerPx=this.getViewPortPxFromLonLat(this.getCenter());var newCenterPx=centerPx.add(dx,dy);if(!options.dragging||!newCenterPx.equals(centerPx)){var newCenterLonLat=this.getLonLatFromViewPortPx(newCenterPx);if(options.animate){this.panTo(newCenterLonLat);}else{this.setCenter(newCenterLonLat,null,options.dragging);}}},panTo:function(lonlat){if(this.panMethod&&this.getExtent().scale(this.panRatio).containsLonLat(lonlat)){if(!this.panTween){this.panTween=new OpenLayers.Tween(this.panMethod);}
60090 var center=this.getCenter();if(lonlat.lon==center.lon&&lonlat.lat==center.lat){return;}
60091 var from={lon:center.lon,lat:center.lat};var to={lon:lonlat.lon,lat:lonlat.lat};this.panTween.start(from,to,this.panDuration,{callbacks:{start:OpenLayers.Function.bind(function(lonlat){this.events.triggerEvent("movestart");},this),eachStep:OpenLayers.Function.bind(function(lonlat){lonlat=new OpenLayers.LonLat(lonlat.lon,lonlat.lat);this.moveTo(lonlat,this.zoom,{'dragging':true,'noEvent':true});},this),done:OpenLayers.Function.bind(function(lonlat){lonlat=new OpenLayers.LonLat(lonlat.lon,lonlat.lat);this.moveTo(lonlat,this.zoom,{'noEvent':true});this.events.triggerEvent("moveend");},this)}});}else{this.setCenter(lonlat);}},setCenter:function(lonlat,zoom,dragging,forceZoomChange){this.moveTo(lonlat,zoom,{'dragging':dragging,'forceZoomChange':forceZoomChange,'caller':'setCenter'});},moveTo:function(lonlat,zoom,options){if(!options){options={};}
60092 if(zoom!=null){zoom=parseFloat(zoom);if(!this.fractionalZoom){zoom=Math.round(zoom);}}
60093 var dragging=options.dragging;var forceZoomChange=options.forceZoomChange;var noEvent=options.noEvent;if(this.panTween&&options.caller=="setCenter"){this.panTween.stop();}
60094 if(!this.center&&!this.isValidLonLat(lonlat)){lonlat=this.maxExtent.getCenterLonLat();}
60095 if(this.restrictedExtent!=null){if(lonlat==null){lonlat=this.getCenter();}
60096 if(zoom==null){zoom=this.getZoom();}
60097 var resolution=this.getResolutionForZoom(zoom);var extent=this.calculateBounds(lonlat,resolution);if(!this.restrictedExtent.containsBounds(extent)){var maxCenter=this.restrictedExtent.getCenterLonLat();if(extent.getWidth()>this.restrictedExtent.getWidth()){lonlat=new OpenLayers.LonLat(maxCenter.lon,lonlat.lat);}else if(extent.left<this.restrictedExtent.left){lonlat=lonlat.add(this.restrictedExtent.left-
60098 extent.left,0);}else if(extent.right>this.restrictedExtent.right){lonlat=lonlat.add(this.restrictedExtent.right-
60099 extent.right,0);}
60100 if(extent.getHeight()>this.restrictedExtent.getHeight()){lonlat=new OpenLayers.LonLat(lonlat.lon,maxCenter.lat);}else if(extent.bottom<this.restrictedExtent.bottom){lonlat=lonlat.add(0,this.restrictedExtent.bottom-
60101 extent.bottom);}
60102 else if(extent.top>this.restrictedExtent.top){lonlat=lonlat.add(0,this.restrictedExtent.top-
60103 extent.top);}}}
60104 var zoomChanged=forceZoomChange||((this.isValidZoomLevel(zoom))&&(zoom!=this.getZoom()));var centerChanged=(this.isValidLonLat(lonlat))&&(!lonlat.equals(this.center));if(zoomChanged||centerChanged||!dragging){if(!this.dragging&&!noEvent){this.events.triggerEvent("movestart");}
60105 if(centerChanged){if((!zoomChanged)&&(this.center)){this.centerLayerContainer(lonlat);}
60106 this.center=lonlat.clone();}
60107 if((zoomChanged)||(this.layerContainerOrigin==null)){this.layerContainerOrigin=this.center.clone();this.layerContainerDiv.style.left="0px";this.layerContainerDiv.style.top="0px";}
60108 if(zoomChanged){this.zoom=zoom;this.resolution=this.getResolutionForZoom(zoom);this.viewRequestID++;}
60109 var bounds=this.getExtent();if(this.baseLayer.visibility){this.baseLayer.moveTo(bounds,zoomChanged,dragging);if(dragging){this.baseLayer.events.triggerEvent("move");}else{this.baseLayer.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});}}
60110 bounds=this.baseLayer.getExtent();for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer!==this.baseLayer&&!layer.isBaseLayer){var inRange=layer.calculateInRange();if(layer.inRange!=inRange){layer.inRange=inRange;if(!inRange){layer.display(false);}
60111 this.events.triggerEvent("changelayer",{layer:layer,property:"visibility"});}
60112 if(inRange&&layer.visibility){layer.moveTo(bounds,zoomChanged,dragging);if(dragging){layer.events.triggerEvent("move");}else{layer.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});}}}}
60113 if(zoomChanged){for(var i=0,len=this.popups.length;i<len;i++){this.popups[i].updatePosition();}}
60114 this.events.triggerEvent("move");if(zoomChanged){this.events.triggerEvent("zoomend");}}
60115 if(!dragging&&!noEvent){this.events.triggerEvent("moveend");}
60116 this.dragging=!!dragging;},centerLayerContainer:function(lonlat){var originPx=this.getViewPortPxFromLonLat(this.layerContainerOrigin);var newPx=this.getViewPortPxFromLonLat(lonlat);if((originPx!=null)&&(newPx!=null)){this.layerContainerDiv.style.left=Math.round(originPx.x-newPx.x)+"px";this.layerContainerDiv.style.top=Math.round(originPx.y-newPx.y)+"px";}},isValidZoomLevel:function(zoomLevel){return((zoomLevel!=null)&&(zoomLevel>=0)&&(zoomLevel<this.getNumZoomLevels()));},isValidLonLat:function(lonlat){var valid=false;if(lonlat!=null){var maxExtent=this.getMaxExtent();valid=maxExtent.containsLonLat(lonlat);}
60117 return valid;},getProjection:function(){var projection=this.getProjectionObject();return projection?projection.getCode():null;},getProjectionObject:function(){var projection=null;if(this.baseLayer!=null){projection=this.baseLayer.projection;}
60118 return projection;},getMaxResolution:function(){var maxResolution=null;if(this.baseLayer!=null){maxResolution=this.baseLayer.maxResolution;}
60119 return maxResolution;},getMaxExtent:function(options){var maxExtent=null;if(options&&options.restricted&&this.restrictedExtent){maxExtent=this.restrictedExtent;}else if(this.baseLayer!=null){maxExtent=this.baseLayer.maxExtent;}
60120 return maxExtent;},getNumZoomLevels:function(){var numZoomLevels=null;if(this.baseLayer!=null){numZoomLevels=this.baseLayer.numZoomLevels;}
60121 return numZoomLevels;},getExtent:function(){var extent=null;if(this.baseLayer!=null){extent=this.baseLayer.getExtent();}
60122 return extent;},getResolution:function(){var resolution=null;if(this.baseLayer!=null){resolution=this.baseLayer.getResolution();}else if(this.allOverlays===true&&this.layers.length>0){resolution=this.layers[0].getResolution();}
60123 return resolution;},getUnits:function(){var units=null;if(this.baseLayer!=null){units=this.baseLayer.units;}
60124 return units;},getScale:function(){var scale=null;if(this.baseLayer!=null){var res=this.getResolution();var units=this.baseLayer.units;scale=OpenLayers.Util.getScaleFromResolution(res,units);}
60125 return scale;},getZoomForExtent:function(bounds,closest){var zoom=null;if(this.baseLayer!=null){zoom=this.baseLayer.getZoomForExtent(bounds,closest);}
60126 return zoom;},getResolutionForZoom:function(zoom){var resolution=null;if(this.baseLayer){resolution=this.baseLayer.getResolutionForZoom(zoom);}
60127 return resolution;},getZoomForResolution:function(resolution,closest){var zoom=null;if(this.baseLayer!=null){zoom=this.baseLayer.getZoomForResolution(resolution,closest);}
60128 return zoom;},zoomTo:function(zoom){if(this.isValidZoomLevel(zoom)){this.setCenter(null,zoom);}},zoomIn:function(){this.zoomTo(this.getZoom()+1);},zoomOut:function(){this.zoomTo(this.getZoom()-1);},zoomToExtent:function(bounds,closest){var center=bounds.getCenterLonLat();if(this.baseLayer.wrapDateLine){var maxExtent=this.getMaxExtent();bounds=bounds.clone();while(bounds.right<bounds.left){bounds.right+=maxExtent.getWidth();}
60129 center=bounds.getCenterLonLat().wrapDateLine(maxExtent);}
60130 this.setCenter(center,this.getZoomForExtent(bounds,closest));},zoomToMaxExtent:function(options){var restricted=(options)?options.restricted:true;var maxExtent=this.getMaxExtent({'restricted':restricted});this.zoomToExtent(maxExtent);},zoomToScale:function(scale,closest){var res=OpenLayers.Util.getResolutionFromScale(scale,this.baseLayer.units);var size=this.getSize();var w_deg=size.w*res;var h_deg=size.h*res;var center=this.getCenter();var extent=new OpenLayers.Bounds(center.lon-w_deg/2,center.lat-h_deg/2,center.lon+w_deg/2,center.lat+h_deg/2);this.zoomToExtent(extent,closest);},getLonLatFromViewPortPx:function(viewPortPx){var lonlat=null;if(this.baseLayer!=null){lonlat=this.baseLayer.getLonLatFromViewPortPx(viewPortPx);}
60131 return lonlat;},getViewPortPxFromLonLat:function(lonlat){var px=null;if(this.baseLayer!=null){px=this.baseLayer.getViewPortPxFromLonLat(lonlat);}
60132 return px;},getLonLatFromPixel:function(px){return this.getLonLatFromViewPortPx(px);},getPixelFromLonLat:function(lonlat){var px=this.getViewPortPxFromLonLat(lonlat);px.x=Math.round(px.x);px.y=Math.round(px.y);return px;},getGeodesicPixelSize:function(px){var lonlat=px?this.getLonLatFromPixel(px):(this.getCenter()||new OpenLayers.LonLat(0,0));var res=this.getResolution();var left=lonlat.add(-res/2,0);var right=lonlat.add(res/2,0);var bottom=lonlat.add(0,-res/2);var top=lonlat.add(0,res/2);var dest=new OpenLayers.Projection("EPSG:4326");var source=this.getProjectionObject()||dest;if(!source.equals(dest)){left.transform(source,dest);right.transform(source,dest);bottom.transform(source,dest);top.transform(source,dest);}
60133 return new OpenLayers.Size(OpenLayers.Util.distVincenty(left,right),OpenLayers.Util.distVincenty(bottom,top));},getViewPortPxFromLayerPx:function(layerPx){var viewPortPx=null;if(layerPx!=null){var dX=parseInt(this.layerContainerDiv.style.left);var dY=parseInt(this.layerContainerDiv.style.top);viewPortPx=layerPx.add(dX,dY);}
60134 return viewPortPx;},getLayerPxFromViewPortPx:function(viewPortPx){var layerPx=null;if(viewPortPx!=null){var dX=-parseInt(this.layerContainerDiv.style.left);var dY=-parseInt(this.layerContainerDiv.style.top);layerPx=viewPortPx.add(dX,dY);if(isNaN(layerPx.x)||isNaN(layerPx.y)){layerPx=null;}}
60135 return layerPx;},getLonLatFromLayerPx:function(px){px=this.getViewPortPxFromLayerPx(px);return this.getLonLatFromViewPortPx(px);},getLayerPxFromLonLat:function(lonlat){var px=this.getPixelFromLonLat(lonlat);return this.getLayerPxFromViewPortPx(px);},CLASS_NAME:"OpenLayers.Map"});OpenLayers.Map.TILE_WIDTH=256;OpenLayers.Map.TILE_HEIGHT=256;OpenLayers.Marker=OpenLayers.Class({icon:null,lonlat:null,events:null,map:null,initialize:function(lonlat,icon){this.lonlat=lonlat;var newIcon=(icon)?icon:OpenLayers.Marker.defaultIcon();if(this.icon==null){this.icon=newIcon;}else{this.icon.url=newIcon.url;this.icon.size=newIcon.size;this.icon.offset=newIcon.offset;this.icon.calculateOffset=newIcon.calculateOffset;}
60136 this.events=new OpenLayers.Events(this,this.icon.imageDiv,null);},destroy:function(){this.erase();this.map=null;this.events.destroy();this.events=null;if(this.icon!=null){this.icon.destroy();this.icon=null;}},draw:function(px){return this.icon.draw(px);},erase:function(){if(this.icon!=null){this.icon.erase();}},moveTo:function(px){if((px!=null)&&(this.icon!=null)){this.icon.moveTo(px);}
60137 this.lonlat=this.map.getLonLatFromLayerPx(px);},isDrawn:function(){var isDrawn=(this.icon&&this.icon.isDrawn());return isDrawn;},onScreen:function(){var onScreen=false;if(this.map){var screenBounds=this.map.getExtent();onScreen=screenBounds.containsLonLat(this.lonlat);}
60138 return onScreen;},inflate:function(inflate){if(this.icon){var newSize=new OpenLayers.Size(this.icon.size.w*inflate,this.icon.size.h*inflate);this.icon.setSize(newSize);}},setOpacity:function(opacity){this.icon.setOpacity(opacity);},setUrl:function(url){this.icon.setUrl(url);},display:function(display){this.icon.display(display);},CLASS_NAME:"OpenLayers.Marker"});OpenLayers.Marker.defaultIcon=function(){var url=OpenLayers.Util.getImagesLocation()+"marker.png";var size=new OpenLayers.Size(21,25);var calculateOffset=function(size){return new OpenLayers.Pixel(-(size.w/2),-size.h);};return new OpenLayers.Icon(url,size,null,calculateOffset);};OpenLayers.Popup.FramedCloud=OpenLayers.Class(OpenLayers.Popup.Framed,{contentDisplayClass:"olFramedCloudPopupContent",autoSize:true,panMapIfOutOfView:true,imageSize:new OpenLayers.Size(1276,736),isAlphaImage:false,fixedRelativePosition:false,positionBlocks:{"tl":{'offset':new OpenLayers.Pixel(44,0),'padding':new OpenLayers.Bounds(8,40,8,9),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,51,22,0),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,50,0,0),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',19),anchor:new OpenLayers.Bounds(0,32,22,null),position:new OpenLayers.Pixel(0,-631)},{size:new OpenLayers.Size(22,18),anchor:new OpenLayers.Bounds(null,32,0,null),position:new OpenLayers.Pixel(-1238,-632)},{size:new OpenLayers.Size(81,35),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(0,-688)}]},"tr":{'offset':new OpenLayers.Pixel(-45,0),'padding':new OpenLayers.Bounds(8,40,8,9),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,51,22,0),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,50,0,0),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',19),anchor:new OpenLayers.Bounds(0,32,22,null),position:new OpenLayers.Pixel(0,-631)},{size:new OpenLayers.Size(22,19),anchor:new OpenLayers.Bounds(null,32,0,null),position:new OpenLayers.Pixel(-1238,-631)},{size:new OpenLayers.Size(81,35),anchor:new OpenLayers.Bounds(0,0,null,null),position:new OpenLayers.Pixel(-215,-687)}]},"bl":{'offset':new OpenLayers.Pixel(45,0),'padding':new OpenLayers.Bounds(8,9,8,40),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,21,22,32),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,21,0,32),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',21),anchor:new OpenLayers.Bounds(0,0,22,null),position:new OpenLayers.Pixel(0,-629)},{size:new OpenLayers.Size(22,21),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(-1238,-629)},{size:new OpenLayers.Size(81,33),anchor:new OpenLayers.Bounds(null,null,0,0),position:new OpenLayers.Pixel(-101,-674)}]},"br":{'offset':new OpenLayers.Pixel(-44,0),'padding':new OpenLayers.Bounds(8,9,8,40),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,21,22,32),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,21,0,32),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',21),anchor:new OpenLayers.Bounds(0,0,22,null),position:new OpenLayers.Pixel(0,-629)},{size:new OpenLayers.Size(22,21),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(-1238,-629)},{size:new OpenLayers.Size(81,33),anchor:new OpenLayers.Bounds(0,null,null,0),position:new OpenLayers.Pixel(-311,-674)}]}},minSize:new OpenLayers.Size(105,10),maxSize:new OpenLayers.Size(1200,660),initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){this.imageSrc=OpenLayers.Util.getImagesLocation()+'cloud-popup-relative.png';OpenLayers.Popup.Framed.prototype.initialize.apply(this,arguments);this.contentDiv.className=this.contentDisplayClass;},destroy:function(){OpenLayers.Popup.Framed.prototype.destroy.apply(this,arguments);},CLASS_NAME:"OpenLayers.Popup.FramedCloud"});OpenLayers.Request={DEFAULT_CONFIG:{method:"GET",url:window.location.href,async:true,user:undefined,password:undefined,params:null,proxy:OpenLayers.ProxyHost,headers:{},data:null,callback:function(){},success:null,failure:null,scope:null},events:new OpenLayers.Events(this,null,["complete","success","failure"]),issue:function(config){var defaultConfig=OpenLayers.Util.extend(this.DEFAULT_CONFIG,{proxy:OpenLayers.ProxyHost});config=OpenLayers.Util.applyDefaults(config,defaultConfig);var request=new OpenLayers.Request.XMLHttpRequest();var url=config.url;if(config.params){var paramString=OpenLayers.Util.getParameterString(config.params);if(paramString.length>0){var separator=(url.indexOf('?')>-1)?'&':'?';url+=separator+paramString;}}
60139 if(config.proxy&&(url.indexOf("http")==0)){if(typeof config.proxy=="function"){url=config.proxy(url);}else{url=config.proxy+encodeURIComponent(url);}}
60140 request.open(config.method,url,config.async,config.user,config.password);for(var header in config.headers){request.setRequestHeader(header,config.headers[header]);}
60141 var events=this.events;var self=this;request.onreadystatechange=function(){if(request.readyState==OpenLayers.Request.XMLHttpRequest.DONE){var proceed=events.triggerEvent("complete",{request:request,config:config,requestUrl:url});if(proceed!==false){self.runCallbacks({request:request,config:config,requestUrl:url});}}};if(config.async===false){request.send(config.data);}else{window.setTimeout(function(){if(request._aborted!==true){request.send(config.data);}},0);}
60142 return request;},runCallbacks:function(options){var request=options.request;var config=options.config;var complete=(config.scope)?OpenLayers.Function.bind(config.callback,config.scope):config.callback;var success;if(config.success){success=(config.scope)?OpenLayers.Function.bind(config.success,config.scope):config.success;}
60143 var failure;if(config.failure){failure=(config.scope)?OpenLayers.Function.bind(config.failure,config.scope):config.failure;}
60144 complete(request);if(!request.status||(request.status>=200&&request.status<300)){this.events.triggerEvent("success",options);if(success){success(request);}}
60145 if(request.status&&(request.status<200||request.status>=300)){this.events.triggerEvent("failure",options);if(failure){failure(request);}}},GET:function(config){config=OpenLayers.Util.extend(config,{method:"GET"});return OpenLayers.Request.issue(config);},POST:function(config){config=OpenLayers.Util.extend(config,{method:"POST"});config.headers=config.headers?config.headers:{};if(!("CONTENT-TYPE"in OpenLayers.Util.upperCaseObject(config.headers))){config.headers["Content-Type"]="application/xml";}
60146 return OpenLayers.Request.issue(config);},PUT:function(config){config=OpenLayers.Util.extend(config,{method:"PUT"});config.headers=config.headers?config.headers:{};if(!("CONTENT-TYPE"in OpenLayers.Util.upperCaseObject(config.headers))){config.headers["Content-Type"]="application/xml";}
60147 return OpenLayers.Request.issue(config);},DELETE:function(config){config=OpenLayers.Util.extend(config,{method:"DELETE"});return OpenLayers.Request.issue(config);},HEAD:function(config){config=OpenLayers.Util.extend(config,{method:"HEAD"});return OpenLayers.Request.issue(config);},OPTIONS:function(config){config=OpenLayers.Util.extend(config,{method:"OPTIONS"});return OpenLayers.Request.issue(config);}};OpenLayers.Tile.Image=OpenLayers.Class(OpenLayers.Tile,{url:null,imgDiv:null,frame:null,layerAlphaHack:null,isBackBuffer:false,lastRatio:1,isFirstDraw:true,backBufferTile:null,initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.prototype.initialize.apply(this,arguments);this.url=url;this.frame=document.createElement('div');this.frame.style.overflow='hidden';this.frame.style.position='absolute';this.layerAlphaHack=this.layer.alpha&&OpenLayers.Util.alphaHack();},destroy:function(){if(this.imgDiv!=null){if(this.layerAlphaHack){OpenLayers.Event.stopObservingElement(this.imgDiv.childNodes[0]);}
60148 OpenLayers.Event.stopObservingElement(this.imgDiv);if(this.imgDiv.parentNode==this.frame){this.frame.removeChild(this.imgDiv);this.imgDiv.map=null;}
60149 this.imgDiv.urls=null;this.imgDiv.src=OpenLayers.Util.getImagesLocation()+"blank.gif";}
60150 this.imgDiv=null;if((this.frame!=null)&&(this.frame.parentNode==this.layer.div)){this.layer.div.removeChild(this.frame);}
60151 this.frame=null;if(this.backBufferTile){this.backBufferTile.destroy();this.backBufferTile=null;}
60152 this.layer.events.unregister("loadend",this,this.resetBackBuffer);OpenLayers.Tile.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile.Image(this.layer,this.position,this.bounds,this.url,this.size);}
60153 obj=OpenLayers.Tile.prototype.clone.apply(this,[obj]);obj.imgDiv=null;return obj;},draw:function(){if(this.layer!=this.layer.map.baseLayer&&this.layer.reproject){this.bounds=this.getBoundsFromBaseLayer(this.position);}
60154 var drawTile=OpenLayers.Tile.prototype.draw.apply(this,arguments);if((OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,this.layer.transitionEffect)!=-1)||this.layer.singleTile){if(drawTile){if(!this.backBufferTile){this.backBufferTile=this.clone();this.backBufferTile.hide();this.backBufferTile.isBackBuffer=true;this.events.register('loadend',this,this.resetBackBuffer);this.layer.events.register("loadend",this,this.resetBackBuffer);}
60155 this.startTransition();}else{if(this.backBufferTile){this.backBufferTile.clear();}}}else{if(drawTile&&this.isFirstDraw){this.events.register('loadend',this,this.showTile);this.isFirstDraw=false;}}
60156 if(!drawTile){return false;}
60157 if(this.isLoading){this.events.triggerEvent("reload");}else{this.isLoading=true;this.events.triggerEvent("loadstart");}
60158 return this.renderTile();},resetBackBuffer:function(){this.showTile();if(this.backBufferTile&&(this.isFirstDraw||!this.layer.numLoadingTiles)){this.isFirstDraw=false;var maxExtent=this.layer.maxExtent;var withinMaxExtent=(maxExtent&&this.bounds.intersectsBounds(maxExtent,false));if(withinMaxExtent){this.backBufferTile.position=this.position;this.backBufferTile.bounds=this.bounds;this.backBufferTile.size=this.size;this.backBufferTile.imageSize=this.layer.getImageSize(this.bounds)||this.size;this.backBufferTile.imageOffset=this.layer.imageOffset;this.backBufferTile.resolution=this.layer.getResolution();this.backBufferTile.renderTile();}
60159 this.backBufferTile.hide();}},renderTile:function(){if(this.imgDiv==null){this.initImgDiv();}
60160 this.imgDiv.viewRequestID=this.layer.map.viewRequestID;if(this.layer.async){this.layer.getURLasync(this.bounds,this,"url",this.positionImage);}else{if(this.layer.url instanceof Array){this.imgDiv.urls=this.layer.url.slice();}
60161 this.url=this.layer.getURL(this.bounds);this.positionImage();}
60162 return true;},positionImage:function(){if(this.layer===null){return;}
60163 OpenLayers.Util.modifyDOMElement(this.frame,null,this.position,this.size);var imageSize=this.layer.getImageSize(this.bounds);if(this.layerAlphaHack){OpenLayers.Util.modifyAlphaImageDiv(this.imgDiv,null,null,imageSize,this.url);}else{OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,imageSize);this.imgDiv.src=this.url;}},clear:function(){if(this.imgDiv){this.hide();if(OpenLayers.Tile.Image.useBlankTile){this.imgDiv.src=OpenLayers.Util.getImagesLocation()+"blank.gif";}}},initImgDiv:function(){var offset=this.layer.imageOffset;var size=this.layer.getImageSize(this.bounds);if(this.layerAlphaHack){this.imgDiv=OpenLayers.Util.createAlphaImageDiv(null,offset,size,null,"relative",null,null,null,true);}else{this.imgDiv=OpenLayers.Util.createImage(null,offset,size,null,"relative",null,null,true);}
60164 this.imgDiv.className='olTileImage';this.frame.style.zIndex=this.isBackBuffer?0:1;this.frame.appendChild(this.imgDiv);this.layer.div.appendChild(this.frame);if(this.layer.opacity!=null){OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,null,null,null,null,this.layer.opacity);}
60165 this.imgDiv.map=this.layer.map;var onload=function(){if(this.isLoading){this.isLoading=false;this.events.triggerEvent("loadend");}};if(this.layerAlphaHack){OpenLayers.Event.observe(this.imgDiv.childNodes[0],'load',OpenLayers.Function.bind(onload,this));}else{OpenLayers.Event.observe(this.imgDiv,'load',OpenLayers.Function.bind(onload,this));}
60166 var onerror=function(){if(this.imgDiv._attempts>OpenLayers.IMAGE_RELOAD_ATTEMPTS){onload.call(this);}};OpenLayers.Event.observe(this.imgDiv,"error",OpenLayers.Function.bind(onerror,this));},checkImgURL:function(){if(this.layer){var loaded=this.layerAlphaHack?this.imgDiv.firstChild.src:this.imgDiv.src;if(!OpenLayers.Util.isEquivalentUrl(loaded,this.url)){this.hide();}}},startTransition:function(){if(!this.backBufferTile||!this.backBufferTile.imgDiv){return;}
60167 var ratio=1;if(this.backBufferTile.resolution){ratio=this.backBufferTile.resolution/this.layer.getResolution();}
60168 if(ratio!=this.lastRatio){if(this.layer.transitionEffect=='resize'){var upperLeft=new OpenLayers.LonLat(this.backBufferTile.bounds.left,this.backBufferTile.bounds.top);var size=new OpenLayers.Size(this.backBufferTile.size.w*ratio,this.backBufferTile.size.h*ratio);var px=this.layer.map.getLayerPxFromLonLat(upperLeft);OpenLayers.Util.modifyDOMElement(this.backBufferTile.frame,null,px,size);var imageSize=this.backBufferTile.imageSize;imageSize=new OpenLayers.Size(imageSize.w*ratio,imageSize.h*ratio);var imageOffset=this.backBufferTile.imageOffset;if(imageOffset){imageOffset=new OpenLayers.Pixel(imageOffset.x*ratio,imageOffset.y*ratio);}
60169 OpenLayers.Util.modifyDOMElement(this.backBufferTile.imgDiv,null,imageOffset,imageSize);this.backBufferTile.show();}}else{if(this.layer.singleTile){this.backBufferTile.show();}else{this.backBufferTile.hide();}}
60170 this.lastRatio=ratio;},show:function(){this.frame.style.display='';if(OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,this.layer.transitionEffect)!=-1){if(navigator.userAgent.toLowerCase().indexOf("gecko")!=-1){this.frame.scrollLeft=this.frame.scrollLeft;}}},hide:function(){this.frame.style.display='none';},CLASS_NAME:"OpenLayers.Tile.Image"});OpenLayers.Tile.Image.useBlankTile=(OpenLayers.Util.getBrowserName()=="safari"||OpenLayers.Util.getBrowserName()=="opera");OpenLayers.Control.OverviewMap=OpenLayers.Class(OpenLayers.Control,{element:null,ovmap:null,size:new OpenLayers.Size(180,90),layers:null,minRectSize:15,minRectDisplayClass:"RectReplacement",minRatio:8,maxRatio:32,mapOptions:null,autoPan:false,handlers:null,resolutionFactor:1,maximized:false,initialize:function(options){this.layers=[];this.handlers={};OpenLayers.Control.prototype.initialize.apply(this,[options]);},destroy:function(){if(!this.mapDiv){return;}
60171 if(this.handlers.click){this.handlers.click.destroy();}
60172 if(this.handlers.drag){this.handlers.drag.destroy();}
60173 this.mapDiv.removeChild(this.extentRectangle);this.extentRectangle=null;if(this.rectEvents){this.rectEvents.destroy();this.rectEvents=null;}
60174 if(this.ovmap){this.ovmap.destroy();this.ovmap=null;}
60175 this.element.removeChild(this.mapDiv);this.mapDiv=null;this.div.removeChild(this.element);this.element=null;if(this.maximizeDiv){OpenLayers.Event.stopObservingElement(this.maximizeDiv);this.div.removeChild(this.maximizeDiv);this.maximizeDiv=null;}
60176 if(this.minimizeDiv){OpenLayers.Event.stopObservingElement(this.minimizeDiv);this.div.removeChild(this.minimizeDiv);this.minimizeDiv=null;}
60177 this.map.events.un({"moveend":this.update,"changebaselayer":this.baseLayerDraw,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!(this.layers.length>0)){if(this.map.baseLayer){var layer=this.map.baseLayer.clone();this.layers=[layer];}else{this.map.events.register("changebaselayer",this,this.baseLayerDraw);return this.div;}}
60178 this.element=document.createElement('div');this.element.className=this.displayClass+'Element';this.element.style.display='none';this.mapDiv=document.createElement('div');this.mapDiv.style.width=this.size.w+'px';this.mapDiv.style.height=this.size.h+'px';this.mapDiv.style.position='relative';this.mapDiv.style.overflow='hidden';this.mapDiv.id=OpenLayers.Util.createUniqueID('overviewMap');this.extentRectangle=document.createElement('div');this.extentRectangle.style.position='absolute';this.extentRectangle.style.zIndex=1000;this.extentRectangle.className=this.displayClass+'ExtentRectangle';this.mapDiv.appendChild(this.extentRectangle);this.element.appendChild(this.mapDiv);this.div.appendChild(this.element);if(!this.outsideViewport){this.div.className+=" "+this.displayClass+'Container';var imgLocation=OpenLayers.Util.getImagesLocation();var img=imgLocation+'layer-switcher-maximize.png';this.maximizeDiv=OpenLayers.Util.createAlphaImageDiv(this.displayClass+'MaximizeButton',null,new OpenLayers.Size(18,18),img,'absolute');this.maximizeDiv.style.display='none';this.maximizeDiv.className=this.displayClass+'MaximizeButton';OpenLayers.Event.observe(this.maximizeDiv,'click',OpenLayers.Function.bindAsEventListener(this.maximizeControl,this));this.div.appendChild(this.maximizeDiv);var img=imgLocation+'layer-switcher-minimize.png';this.minimizeDiv=OpenLayers.Util.createAlphaImageDiv('OpenLayers_Control_minimizeDiv',null,new OpenLayers.Size(18,18),img,'absolute');this.minimizeDiv.style.display='none';this.minimizeDiv.className=this.displayClass+'MinimizeButton';OpenLayers.Event.observe(this.minimizeDiv,'click',OpenLayers.Function.bindAsEventListener(this.minimizeControl,this));this.div.appendChild(this.minimizeDiv);var eventsToStop=['dblclick','mousedown'];for(var i=0,len=eventsToStop.length;i<len;i++){OpenLayers.Event.observe(this.maximizeDiv,eventsToStop[i],OpenLayers.Event.stop);OpenLayers.Event.observe(this.minimizeDiv,eventsToStop[i],OpenLayers.Event.stop);}
60179 this.minimizeControl();}else{this.element.style.display='';}
60180 if(this.map.getExtent()){this.update();}
60181 this.map.events.register('moveend',this,this.update);if(this.maximized){this.maximizeControl();}
60182 return this.div;},baseLayerDraw:function(){this.draw();this.map.events.unregister("changebaselayer",this,this.baseLayerDraw);},rectDrag:function(px){var deltaX=this.handlers.drag.last.x-px.x;var deltaY=this.handlers.drag.last.y-px.y;if(deltaX!=0||deltaY!=0){var rectTop=this.rectPxBounds.top;var rectLeft=this.rectPxBounds.left;var rectHeight=Math.abs(this.rectPxBounds.getHeight());var rectWidth=this.rectPxBounds.getWidth();var newTop=Math.max(0,(rectTop-deltaY));newTop=Math.min(newTop,this.ovmap.size.h-this.hComp-rectHeight);var newLeft=Math.max(0,(rectLeft-deltaX));newLeft=Math.min(newLeft,this.ovmap.size.w-this.wComp-rectWidth);this.setRectPxBounds(new OpenLayers.Bounds(newLeft,newTop+rectHeight,newLeft+rectWidth,newTop));}},mapDivClick:function(evt){var pxCenter=this.rectPxBounds.getCenterPixel();var deltaX=evt.xy.x-pxCenter.x;var deltaY=evt.xy.y-pxCenter.y;var top=this.rectPxBounds.top;var left=this.rectPxBounds.left;var height=Math.abs(this.rectPxBounds.getHeight());var width=this.rectPxBounds.getWidth();var newTop=Math.max(0,(top+deltaY));newTop=Math.min(newTop,this.ovmap.size.h-height);var newLeft=Math.max(0,(left+deltaX));newLeft=Math.min(newLeft,this.ovmap.size.w-width);this.setRectPxBounds(new OpenLayers.Bounds(newLeft,newTop+height,newLeft+width,newTop));this.updateMapToRect();},maximizeControl:function(e){this.element.style.display='';this.showToggle(false);if(e!=null){OpenLayers.Event.stop(e);}},minimizeControl:function(e){this.element.style.display='none';this.showToggle(true);if(e!=null){OpenLayers.Event.stop(e);}},showToggle:function(minimize){this.maximizeDiv.style.display=minimize?'':'none';this.minimizeDiv.style.display=minimize?'none':'';},update:function(){if(this.ovmap==null){this.createMap();}
60183 if(this.autoPan||!this.isSuitableOverview()){this.updateOverview();}
60184 this.updateRectToMap();},isSuitableOverview:function(){var mapExtent=this.map.getExtent();var maxExtent=this.map.maxExtent;var testExtent=new OpenLayers.Bounds(Math.max(mapExtent.left,maxExtent.left),Math.max(mapExtent.bottom,maxExtent.bottom),Math.min(mapExtent.right,maxExtent.right),Math.min(mapExtent.top,maxExtent.top));if(this.ovmap.getProjection()!=this.map.getProjection()){testExtent=testExtent.transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}
60185 var resRatio=this.ovmap.getResolution()/this.map.getResolution();return((resRatio>this.minRatio)&&(resRatio<=this.maxRatio)&&(this.ovmap.getExtent().containsBounds(testExtent)));},updateOverview:function(){var mapRes=this.map.getResolution();var targetRes=this.ovmap.getResolution();var resRatio=targetRes/mapRes;if(resRatio>this.maxRatio){targetRes=this.minRatio*mapRes;}else if(resRatio<=this.minRatio){targetRes=this.maxRatio*mapRes;}
60186 var center;if(this.ovmap.getProjection()!=this.map.getProjection()){center=this.map.center.clone();center.transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}else{center=this.map.center;}
60187 this.ovmap.setCenter(center,this.ovmap.getZoomForResolution(targetRes*this.resolutionFactor));this.updateRectToMap();},createMap:function(){var options=OpenLayers.Util.extend({controls:[],maxResolution:'auto',fallThrough:false},this.mapOptions);this.ovmap=new OpenLayers.Map(this.mapDiv,options);OpenLayers.Event.stopObserving(window,'unload',this.ovmap.unloadDestroy);this.ovmap.addLayers(this.layers);this.ovmap.zoomToMaxExtent();this.wComp=parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-left-width'))+
60188 parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-right-width'));this.wComp=(this.wComp)?this.wComp:2;this.hComp=parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-top-width'))+
60189 parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-bottom-width'));this.hComp=(this.hComp)?this.hComp:2;this.handlers.drag=new OpenLayers.Handler.Drag(this,{move:this.rectDrag,done:this.updateMapToRect},{map:this.ovmap});this.handlers.click=new OpenLayers.Handler.Click(this,{"click":this.mapDivClick},{"single":true,"double":false,"stopSingle":true,"stopDouble":true,"pixelTolerance":1,map:this.ovmap});this.handlers.click.activate();this.rectEvents=new OpenLayers.Events(this,this.extentRectangle,null,true);this.rectEvents.register("mouseover",this,function(e){if(!this.handlers.drag.active&&!this.map.dragging){this.handlers.drag.activate();}});this.rectEvents.register("mouseout",this,function(e){if(!this.handlers.drag.dragging){this.handlers.drag.deactivate();}});if(this.ovmap.getProjection()!=this.map.getProjection()){var sourceUnits=this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units;var targetUnits=this.ovmap.getProjectionObject().getUnits()||this.ovmap.units||this.ovmap.baseLayer.units;this.resolutionFactor=sourceUnits&&targetUnits?OpenLayers.INCHES_PER_UNIT[sourceUnits]/OpenLayers.INCHES_PER_UNIT[targetUnits]:1;}},updateRectToMap:function(){var bounds;if(this.ovmap.getProjection()!=this.map.getProjection()){bounds=this.map.getExtent().transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}else{bounds=this.map.getExtent();}
60190 var pxBounds=this.getRectBoundsFromMapBounds(bounds);if(pxBounds){this.setRectPxBounds(pxBounds);}},updateMapToRect:function(){var lonLatBounds=this.getMapBoundsFromRectBounds(this.rectPxBounds);if(this.ovmap.getProjection()!=this.map.getProjection()){lonLatBounds=lonLatBounds.transform(this.ovmap.getProjectionObject(),this.map.getProjectionObject());}
60191 this.map.panTo(lonLatBounds.getCenterLonLat());},setRectPxBounds:function(pxBounds){var top=Math.max(pxBounds.top,0);var left=Math.max(pxBounds.left,0);var bottom=Math.min(pxBounds.top+Math.abs(pxBounds.getHeight()),this.ovmap.size.h-this.hComp);var right=Math.min(pxBounds.left+pxBounds.getWidth(),this.ovmap.size.w-this.wComp);var width=Math.max(right-left,0);var height=Math.max(bottom-top,0);if(width<this.minRectSize||height<this.minRectSize){this.extentRectangle.className=this.displayClass+
60192 this.minRectDisplayClass;var rLeft=left+(width/2)-(this.minRectSize/2);var rTop=top+(height/2)-(this.minRectSize/2);this.extentRectangle.style.top=Math.round(rTop)+'px';this.extentRectangle.style.left=Math.round(rLeft)+'px';this.extentRectangle.style.height=this.minRectSize+'px';this.extentRectangle.style.width=this.minRectSize+'px';}else{this.extentRectangle.className=this.displayClass+'ExtentRectangle';this.extentRectangle.style.top=Math.round(top)+'px';this.extentRectangle.style.left=Math.round(left)+'px';this.extentRectangle.style.height=Math.round(height)+'px';this.extentRectangle.style.width=Math.round(width)+'px';}
60193 this.rectPxBounds=new OpenLayers.Bounds(Math.round(left),Math.round(bottom),Math.round(right),Math.round(top));},getRectBoundsFromMapBounds:function(lonLatBounds){var leftBottomLonLat=new OpenLayers.LonLat(lonLatBounds.left,lonLatBounds.bottom);var rightTopLonLat=new OpenLayers.LonLat(lonLatBounds.right,lonLatBounds.top);var leftBottomPx=this.getOverviewPxFromLonLat(leftBottomLonLat);var rightTopPx=this.getOverviewPxFromLonLat(rightTopLonLat);var bounds=null;if(leftBottomPx&&rightTopPx){bounds=new OpenLayers.Bounds(leftBottomPx.x,leftBottomPx.y,rightTopPx.x,rightTopPx.y);}
60194 return bounds;},getMapBoundsFromRectBounds:function(pxBounds){var leftBottomPx=new OpenLayers.Pixel(pxBounds.left,pxBounds.bottom);var rightTopPx=new OpenLayers.Pixel(pxBounds.right,pxBounds.top);var leftBottomLonLat=this.getLonLatFromOverviewPx(leftBottomPx);var rightTopLonLat=this.getLonLatFromOverviewPx(rightTopPx);return new OpenLayers.Bounds(leftBottomLonLat.lon,leftBottomLonLat.lat,rightTopLonLat.lon,rightTopLonLat.lat);},getLonLatFromOverviewPx:function(overviewMapPx){var size=this.ovmap.size;var res=this.ovmap.getResolution();var center=this.ovmap.getExtent().getCenterLonLat();var delta_x=overviewMapPx.x-(size.w/2);var delta_y=overviewMapPx.y-(size.h/2);return new OpenLayers.LonLat(center.lon+delta_x*res,center.lat-delta_y*res);},getOverviewPxFromLonLat:function(lonlat){var res=this.ovmap.getResolution();var extent=this.ovmap.getExtent();var px=null;if(extent){px=new OpenLayers.Pixel(Math.round(1/res*(lonlat.lon-extent.left)),Math.round(1/res*(extent.top-lonlat.lat)));}
60195 return px;},CLASS_NAME:'OpenLayers.Control.OverviewMap'});OpenLayers.Feature=OpenLayers.Class({layer:null,id:null,lonlat:null,data:null,marker:null,popupClass:OpenLayers.Popup.AnchoredBubble,popup:null,initialize:function(layer,lonlat,data){this.layer=layer;this.lonlat=lonlat;this.data=(data!=null)?data:{};this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){if((this.layer!=null)&&(this.layer.map!=null)){if(this.popup!=null){this.layer.map.removePopup(this.popup);}}
60196 if(this.layer!=null&&this.marker!=null){this.layer.removeMarker(this.marker);}
60197 this.layer=null;this.id=null;this.lonlat=null;this.data=null;if(this.marker!=null){this.destroyMarker(this.marker);this.marker=null;}
60198 if(this.popup!=null){this.destroyPopup(this.popup);this.popup=null;}},onScreen:function(){var onScreen=false;if((this.layer!=null)&&(this.layer.map!=null)){var screenBounds=this.layer.map.getExtent();onScreen=screenBounds.containsLonLat(this.lonlat);}
60199 return onScreen;},createMarker:function(){if(this.lonlat!=null){this.marker=new OpenLayers.Marker(this.lonlat,this.data.icon);}
60200 return this.marker;},destroyMarker:function(){this.marker.destroy();},createPopup:function(closeBox){if(this.lonlat!=null){var id=this.id+"_popup";var anchor=(this.marker)?this.marker.icon:null;if(!this.popup){this.popup=new this.popupClass(id,this.lonlat,this.data.popupSize,this.data.popupContentHTML,anchor,closeBox);}
60201 if(this.data.overflow!=null){this.popup.contentDiv.style.overflow=this.data.overflow;}
60202 this.popup.feature=this;}
60203 return this.popup;},destroyPopup:function(){if(this.popup){this.popup.feature=null;this.popup.destroy();this.popup=null;}},CLASS_NAME:"OpenLayers.Feature"});OpenLayers.Format.CSWGetDomain.v2_0_2=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",csw:"http://www.opengis.net/cat/csw/2.0.2"},defaultPrefix:"csw",version:"2.0.2",schemaLocation:"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd",PropertyName:null,ParameterName:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60204 if(data&&data.nodeType==9){data=data.documentElement;}
60205 var obj={};this.readNode(data,obj);return obj;},readers:{"csw":{"GetDomainResponse":function(node,obj){this.readChildNodes(node,obj);},"DomainValues":function(node,obj){if(!(obj.DomainValues instanceof Array)){obj.DomainValues=[];}
60206 var attrs=node.attributes;var domainValue={};for(var i=0,len=attrs.length;i<len;++i){domainValue[attrs[i].name]=attrs[i].nodeValue;}
60207 this.readChildNodes(node,domainValue);obj.DomainValues.push(domainValue);},"PropertyName":function(node,obj){obj.PropertyName=this.getChildValue(node);},"ParameterName":function(node,obj){obj.ParameterName=this.getChildValue(node);},"ListOfValues":function(node,obj){if(!(obj.ListOfValues instanceof Array)){obj.ListOfValues=[];}
60208 this.readChildNodes(node,obj.ListOfValues);},"Value":function(node,obj){var attrs=node.attributes;var value={}
60209 for(var i=0,len=attrs.length;i<len;++i){value[attrs[i].name]=attrs[i].nodeValue;}
60210 value.value=this.getChildValue(node);obj.push({Value:value});},"ConceptualScheme":function(node,obj){obj.ConceptualScheme={};this.readChildNodes(node,obj.ConceptualScheme);},"Name":function(node,obj){obj.Name=this.getChildValue(node);},"Document":function(node,obj){obj.Document=this.getChildValue(node);},"Authority":function(node,obj){obj.Authority=this.getChildValue(node);},"RangeOfValues":function(node,obj){obj.RangeOfValues={};this.readChildNodes(node,obj.RangeOfValues);},"MinValue":function(node,obj){var attrs=node.attributes;var value={}
60211 for(var i=0,len=attrs.length;i<len;++i){value[attrs[i].name]=attrs[i].nodeValue;}
60212 value.value=this.getChildValue(node);obj.MinValue=value;},"MaxValue":function(node,obj){var attrs=node.attributes;var value={}
60213 for(var i=0,len=attrs.length;i<len;++i){value[attrs[i].name]=attrs[i].nodeValue;}
60214 value.value=this.getChildValue(node);obj.MaxValue=value;}}},write:function(options){var node=this.writeNode("csw:GetDomain",options);return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},writers:{"csw":{"GetDomain":function(options){var node=this.createElementNSPlus("csw:GetDomain",{attributes:{service:"CSW",version:this.version}});if(options.PropertyName||this.PropertyName){this.writeNode("csw:PropertyName",options.PropertyName||this.PropertyName,node);}else if(options.ParameterName||this.ParameterName){this.writeNode("csw:ParameterName",options.ParameterName||this.ParameterName,node);}
60215 this.readChildNodes(node,options);return node;},"PropertyName":function(value){var node=this.createElementNSPlus("csw:PropertyName",{value:value});return node;},"ParameterName":function(value){var node=this.createElementNSPlus("csw:ParameterName",{value:value});return node;}}},CLASS_NAME:"OpenLayers.Format.CSWGetDomain.v2_0_2"});OpenLayers.Format.Context=OpenLayers.Class({version:null,layerOptions:null,layerParams:null,parser:null,initialize:function(options){OpenLayers.Util.extend(this,options);this.options=options;},read:function(data,options){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60216 var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");}
60217 var parser=this.getParser(version);var context=parser.read(data,options);var map;if(options&&options.map){this.context=context;if(options.map instanceof OpenLayers.Map){map=this.mergeContextToMap(context,options.map);}else{var mapOptions=options.map;if(OpenLayers.Util.isElement(mapOptions)||typeof mapOptions=="string"){mapOptions={div:mapOptions};}
60218 map=this.contextToMap(context,mapOptions);}}else{map=context;}
60219 return map;},getLayerFromContext:function(layerContext){var i,len;var options={queryable:layerContext.queryable,visibility:layerContext.visibility,maxExtent:layerContext.maxExtent,metadata:OpenLayers.Util.applyDefaults(layerContext.metadata,{styles:layerContext.styles}),numZoomLevels:layerContext.numZoomLevels,units:layerContext.units,isBaseLayer:layerContext.isBaseLayer,opacity:layerContext.opacity,displayInLayerSwitcher:layerContext.displayInLayerSwitcher,singleTile:layerContext.singleTile,tileSize:(layerContext.tileSize)?new OpenLayers.Size(layerContext.tileSize.width,layerContext.tileSize.height):undefined,minScale:layerContext.minScale||layerContext.maxScaleDenominator,maxScale:layerContext.maxScale||layerContext.minScaleDenominator};if(this.layerOptions){OpenLayers.Util.applyDefaults(options,this.layerOptions);}
60220 var params={layers:layerContext.name,transparent:layerContext.transparent,version:layerContext.version};if(layerContext.formats&&layerContext.formats.length>0){params.format=layerContext.formats[0].value;for(i=0,len=layerContext.formats.length;i<len;i++){var format=layerContext.formats[i];if(format.current==true){params.format=format.value;break;}}}
60221 if(layerContext.styles&&layerContext.styles.length>0){for(i=0,len=layerContext.styles.length;i<len;i++){var style=layerContext.styles[i];if(style.current==true){if(style.href){params.sld=style.href;}else if(style.body){params.sld_body=style.body;}else{params.styles=style.name;}
60222 break;}}}
60223 if(this.layerParams){OpenLayers.Util.applyDefaults(params,this.layerParams);}
60224 var layer=null;var service=layerContext.service;if(service==OpenLayers.Format.Context.serviceTypes.WFS){options.strategies=[new OpenLayers.Strategy.BBOX()];options.protocol=new OpenLayers.Protocol.WFS({url:layerContext.url,featurePrefix:layerContext.name.split(":")[0],featureType:layerContext.name.split(":").pop()});layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);}else if(service==OpenLayers.Format.Context.serviceTypes.KML){options.strategies=[new OpenLayers.Strategy.Fixed()];options.protocol=new OpenLayers.Protocol.HTTP({url:layerContext.url,format:new OpenLayers.Format.KML()});layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);}else if(service==OpenLayers.Format.Context.serviceTypes.GML){options.strategies=[new OpenLayers.Strategy.Fixed()];options.protocol=new OpenLayers.Protocol.HTTP({url:layerContext.url,format:new OpenLayers.Format.GML()});layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);}else if(layerContext.features){layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);layer.addFeatures(layerContext.features);}else if(layerContext.categoryLayer!==true){layer=new OpenLayers.Layer.WMS(layerContext.title||layerContext.name,layerContext.url,params,options);}
60225 return layer;},getLayersFromContext:function(layersContext){var layers=[];for(var i=0,len=layersContext.length;i<len;i++){var layer=this.getLayerFromContext(layersContext[i]);if(layer!==null){layers.push(layer);}}
60226 return layers;},contextToMap:function(context,options){options=OpenLayers.Util.applyDefaults({maxExtent:context.maxExtent,projection:context.projection},options);var map=new OpenLayers.Map(options);map.addLayers(this.getLayersFromContext(context.layersContext));map.setCenter(context.bounds.getCenterLonLat(),map.getZoomForExtent(context.bounds,true));return map;},mergeContextToMap:function(context,map){map.addLayers(this.getLayersFromContext(context.layersContext));return map;},write:function(obj,options){obj=this.toContext(obj);var version=options&&options.version;var parser=this.getParser(version);var context=parser.write(obj,options);return context;},CLASS_NAME:"OpenLayers.Format.Context"});OpenLayers.Format.Context.serviceTypes={"WMS":"urn:ogc:serviceType:WMS","WFS":"urn:ogc:serviceType:WFS","WCS":"urn:ogc:serviceType:WCS","GML":"urn:ogc:serviceType:GML","SLD":"urn:ogc:serviceType:SLD","FES":"urn:ogc:serviceType:FES","KML":"urn:ogc:serviceType:KML"};if(!OpenLayers.Format.OWSCommon){OpenLayers.Format.OWSCommon={};}
60227 OpenLayers.Format.OWSCommon.v1=OpenLayers.Class(OpenLayers.Format.XML,{regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},readers:{"ows":{"ServiceIdentification":function(node,obj){obj.serviceIdentification={};this.readChildNodes(node,obj.serviceIdentification);},"Title":function(node,obj){obj.title=this.getChildValue(node);},"Abstract":function(node,serviceIdentification){serviceIdentification["abstract"]=this.getChildValue(node);},"Keywords":function(node,serviceIdentification){serviceIdentification.keywords={};this.readChildNodes(node,serviceIdentification.keywords);},"Keyword":function(node,keywords){keywords[this.getChildValue(node)]=true;},"ServiceType":function(node,serviceIdentification){serviceIdentification.serviceType={codeSpace:node.getAttribute('codeSpace'),value:this.getChildValue(node)};},"ServiceTypeVersion":function(node,serviceIdentification){serviceIdentification.serviceTypeVersion=this.getChildValue(node);},"Fees":function(node,serviceIdentification){serviceIdentification.fees=this.getChildValue(node);},"AccessConstraints":function(node,serviceIdentification){serviceIdentification.accessConstraints=this.getChildValue(node);},"ServiceProvider":function(node,obj){obj.serviceProvider={};this.readChildNodes(node,obj.serviceProvider);},"ProviderName":function(node,serviceProvider){serviceProvider.providerName=this.getChildValue(node);},"ProviderSite":function(node,serviceProvider){serviceProvider.providerSite=this.getAttributeNS(node,this.namespaces.xlink,"href");},"ServiceContact":function(node,serviceProvider){serviceProvider.serviceContact={};this.readChildNodes(node,serviceProvider.serviceContact);},"IndividualName":function(node,serviceContact){serviceContact.individualName=this.getChildValue(node);},"PositionName":function(node,serviceContact){serviceContact.positionName=this.getChildValue(node);},"ContactInfo":function(node,serviceContact){serviceContact.contactInfo={};this.readChildNodes(node,serviceContact.contactInfo);},"Phone":function(node,contactInfo){contactInfo.phone={};this.readChildNodes(node,contactInfo.phone);},"Voice":function(node,phone){phone.voice=this.getChildValue(node);},"Address":function(node,contactInfo){contactInfo.address={};this.readChildNodes(node,contactInfo.address);},"DeliveryPoint":function(node,address){address.deliveryPoint=this.getChildValue(node);},"City":function(node,address){address.city=this.getChildValue(node);},"AdministrativeArea":function(node,address){address.administrativeArea=this.getChildValue(node);},"PostalCode":function(node,address){address.postalCode=this.getChildValue(node);},"Country":function(node,address){address.country=this.getChildValue(node);},"ElectronicMailAddress":function(node,address){address.electronicMailAddress=this.getChildValue(node);},"Role":function(node,serviceContact){serviceContact.role=this.getChildValue(node);},"OperationsMetadata":function(node,obj){obj.operationsMetadata={};this.readChildNodes(node,obj.operationsMetadata);},"Operation":function(node,operationsMetadata){var name=node.getAttribute("name");operationsMetadata[name]={};this.readChildNodes(node,operationsMetadata[name]);},"DCP":function(node,operation){operation.dcp={};this.readChildNodes(node,operation.dcp);},"HTTP":function(node,dcp){dcp.http={};this.readChildNodes(node,dcp.http);},"Get":function(node,http){http.get=this.getAttributeNS(node,this.namespaces.xlink,"href");},"Post":function(node,http){http.post=this.getAttributeNS(node,this.namespaces.xlink,"href");},"Parameter":function(node,operation){if(!operation.parameters){operation.parameters={};}
60228 var name=node.getAttribute("name");operation.parameters[name]={};this.readChildNodes(node,operation.parameters[name]);},"Value":function(node,allowedValues){allowedValues[this.getChildValue(node)]=true;},"OutputFormat":function(node,obj){obj.formats.push({value:this.getChildValue(node)});this.readChildNodes(node,obj);},"WGS84BoundingBox":function(node,obj){var boundingBox={};boundingBox.crs=node.getAttribute("crs");if(obj.BoundingBox){obj.BoundingBox.push(boundingBox);}else{obj.projection=boundingBox.crs;boundingBox=obj;}
60229 this.readChildNodes(node,boundingBox);},"BoundingBox":function(node,obj){this.readers['ows']['WGS84BoundingBox'].apply(this,[node,obj]);},"LowerCorner":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");str=str.replace(this.regExes.trimComma,",");var pointList=str.split(this.regExes.splitSpace);obj.left=pointList[0];obj.bottom=pointList[1];},"UpperCorner":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");str=str.replace(this.regExes.trimComma,",");var pointList=str.split(this.regExes.splitSpace);obj.right=pointList[0];obj.top=pointList[1];obj.bounds=new OpenLayers.Bounds(obj.left,obj.bottom,obj.right,obj.top);delete obj.left;delete obj.bottom;delete obj.right;delete obj.top;}}},writers:{"ows":{"BoundingBox":function(options){var node=this.createElementNSPlus("ows:BoundingBox",{attributes:{crs:options.projection}});this.writeNode("ows:LowerCorner",options,node);this.writeNode("ows:UpperCorner",options,node);return node;},"LowerCorner":function(options){var node=this.createElementNSPlus("ows:LowerCorner",{value:options.bounds.left+" "+options.bounds.bottom});return node;},"UpperCorner":function(options){var node=this.createElementNSPlus("ows:UpperCorner",{value:options.bounds.right+" "+options.bounds.top});return node;},"Title":function(title){var node=this.createElementNSPlus("ows:Title",{value:title});return node;},"OutputFormat":function(format){var node=this.createElementNSPlus("ows:OutputFormat",{value:format});return node;}}},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1"});OpenLayers.Format.SOSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60230 var root=data.documentElement;var version=this.version||root.getAttribute("version")||this.defaultVersion;if(!this.parser||this.parser.version!==version){var constr=OpenLayers.Format.SOSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw"Can't find a SOS capabilities parser for version "+version;}
60231 var parser=new constr(this.options);}
60232 var capabilities=parser.read(data);capabilities.version=version;return capabilities;},CLASS_NAME:"OpenLayers.Format.SOSCapabilities"});OpenLayers.Format.WFSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.1.0",version:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60233 var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");if(!version){version=this.defaultVersion;}}
60234 var constr=OpenLayers.Format.WFSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw"Can't find a WFS capabilities parser for version "+version;}
60235 var parser=new constr(this.options);var capabilities=parser.read(data);capabilities.version=version;return capabilities;},CLASS_NAME:"OpenLayers.Format.WFSCapabilities"});OpenLayers.Format.WFSDescribeFeatureType=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xsd:"http://www.w3.org/2001/XMLSchema"},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},readers:{"xsd":{"schema":function(node,obj){var complexTypes=[];var customTypes={};var schema={complexTypes:complexTypes,customTypes:customTypes};this.readChildNodes(node,schema);var attributes=node.attributes;var attr,name;for(var i=0,len=attributes.length;i<len;++i){attr=attributes[i];name=attr.name;if(name.indexOf("xmlns")==0){this.setNamespace(name.split(":")[1]||"",attr.value);}else{obj[name]=attr.value;}}
60236 obj.featureTypes=complexTypes;obj.targetPrefix=this.namespaceAlias[obj.targetNamespace];var complexType,customType;for(var i=0,len=complexTypes.length;i<len;++i){complexType=complexTypes[i];customType=customTypes[complexType.typeName];if(customTypes[complexType.typeName]){complexType.typeName=customType.name;}}},"complexType":function(node,obj){var complexType={"typeName":node.getAttribute("name")};this.readChildNodes(node,complexType);obj.complexTypes.push(complexType);},"complexContent":function(node,obj){this.readChildNodes(node,obj);},"extension":function(node,obj){this.readChildNodes(node,obj);},"sequence":function(node,obj){var sequence={elements:[]};this.readChildNodes(node,sequence);obj.properties=sequence.elements;},"element":function(node,obj){if(obj.elements){var element={};var attributes=node.attributes;var attr;for(var i=0,len=attributes.length;i<len;++i){attr=attributes[i];element[attr.name]=attr.value;}
60237 var type=element.type;if(!type){type={};this.readChildNodes(node,type);element.restriction=type;element.type=type.base;}
60238 var fullType=type.base||type;element.localType=fullType.split(":").pop();obj.elements.push(element);}
60239 if(obj.complexTypes){var type=node.getAttribute("type");var localType=type.split(":").pop();obj.customTypes[localType]={"name":node.getAttribute("name"),"type":type};}},"simpleType":function(node,obj){this.readChildNodes(node,obj);},"restriction":function(node,obj){obj.base=node.getAttribute("base");this.readRestriction(node,obj);}}},readRestriction:function(node,obj){var children=node.childNodes;var child,nodeName,value;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){nodeName=child.nodeName.split(":").pop();value=child.getAttribute("value");if(!obj[nodeName]){obj[nodeName]=value;}else{if(typeof obj[nodeName]=="string"){obj[nodeName]=[obj[nodeName]];}
60240 obj[nodeName].push(value);}}}},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60241 if(data&&data.nodeType==9){data=data.documentElement;}
60242 var schema={};this.readNode(data,schema);return schema;},CLASS_NAME:"OpenLayers.Format.WFSDescribeFeatureType"});OpenLayers.Format.WFST.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",wfs:"http://www.opengis.net/wfs",gml:"http://www.opengis.net/gml",ogc:"http://www.opengis.net/ogc"},defaultPrefix:"wfs",version:null,schemaLocations:null,srsName:null,extractAttributes:true,xy:true,stateName:null,initialize:function(options){this.stateName={};this.stateName[OpenLayers.State.INSERT]="wfs:Insert";this.stateName[OpenLayers.State.UPDATE]="wfs:Update";this.stateName[OpenLayers.State.DELETE]="wfs:Delete";OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},getSrsName:function(feature,options){var srsName=options&&options.srsName;if(!srsName){if(feature&&feature.layer){srsName=feature.layer.projection.getCode();}else{srsName=this.srsName;}}
60243 return srsName;},read:function(data,options){options=options||{};OpenLayers.Util.applyDefaults(options,{output:"features"});if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60244 if(data&&data.nodeType==9){data=data.documentElement;}
60245 var obj={};if(data){this.readNode(data,obj);}
60246 if(obj.features&&options.output==="features"){obj=obj.features;}
60247 return obj;},readers:{"wfs":{"FeatureCollection":function(node,obj){obj.features=[];this.readChildNodes(node,obj);}}},write:function(features){var node=this.writeNode("wfs:Transaction",features);var value=this.schemaLocationAttr();if(value){this.setAttributeNS(node,this.namespaces["xsi"],"xsi:schemaLocation",value)}
60248 return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},writers:{"wfs":{"GetFeature":function(options){var node=this.createElementNSPlus("wfs:GetFeature",{attributes:{service:"WFS",version:this.version,outputFormat:options&&options.outputFormat,maxFeatures:options&&options.maxFeatures,"xsi:schemaLocation":this.schemaLocationAttr(options)}});if(typeof this.featureType=="string"){this.writeNode("Query",options,node);}else{for(var i=0,len=this.featureType.length;i<len;i++){options.featureType=this.featureType[i];this.writeNode("Query",options,node);}}
60249 return node;},"Transaction":function(features){var node=this.createElementNSPlus("wfs:Transaction",{attributes:{service:"WFS",version:this.version}});if(features){var name,feature;for(var i=0,len=features.length;i<len;++i){feature=features[i];name=this.stateName[feature.state];if(name){this.writeNode(name,feature,node);}}}
60250 return node;},"Insert":function(feature){var node=this.createElementNSPlus("wfs:Insert");this.srsName=this.getSrsName(feature);this.writeNode("feature:_typeName",feature,node);return node;},"Update":function(feature){var node=this.createElementNSPlus("wfs:Update",{attributes:{typeName:(this.featureNS?this.featurePrefix+":":"")+
60251 this.featureType}});if(this.featureNS){node.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);}
60252 if(this.geometryName!==null){this.writeNode("Property",{name:this.geometryName,value:feature},node);}
60253 for(var key in feature.attributes){if(feature.attributes[key]!==undefined){this.writeNode("Property",{name:key,value:feature.attributes[key]},node);}}
60254 this.writeNode("ogc:Filter",new OpenLayers.Filter.FeatureId({fids:[feature.fid]}),node);return node;},"Property":function(obj){var node=this.createElementNSPlus("wfs:Property");this.writeNode("Name",obj.name,node);if(obj.value!==null){this.writeNode("Value",obj.value,node);}
60255 return node;},"Name":function(name){return this.createElementNSPlus("wfs:Name",{value:name});},"Value":function(obj){var node;if(obj instanceof OpenLayers.Feature.Vector){node=this.createElementNSPlus("wfs:Value");this.srsName=this.getSrsName(obj);var geom=this.writeNode("feature:_geometry",obj.geometry).firstChild;node.appendChild(geom);}else{node=this.createElementNSPlus("wfs:Value",{value:obj});}
60256 return node;},"Delete":function(feature){var node=this.createElementNSPlus("wfs:Delete",{attributes:{typeName:(this.featureNS?this.featurePrefix+":":"")+
60257 this.featureType}});if(this.featureNS){node.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);}
60258 this.writeNode("ogc:Filter",new OpenLayers.Filter.FeatureId({fids:[feature.fid]}),node);return node;}}},schemaLocationAttr:function(options){options=OpenLayers.Util.extend({featurePrefix:this.featurePrefix,schema:this.schema},options);var schemaLocations=OpenLayers.Util.extend({},this.schemaLocations);if(options.schema){schemaLocations[options.featurePrefix]=options.schema;}
60259 var parts=[];var uri;for(var key in schemaLocations){uri=this.namespaces[key];if(uri){parts.push(uri+" "+schemaLocations[key]);}}
60260 var value=parts.join(" ")||undefined;return value;},setFilterProperty:function(filter){if(filter.filters){for(var i=0,len=filter.filters.length;i<len;++i){this.setFilterProperty(filter.filters[i]);}}else{if(filter instanceof OpenLayers.Filter.Spatial){filter.property=this.geometryName;}}},CLASS_NAME:"OpenLayers.Format.WFST.v1"});OpenLayers.Format.WMSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.1.1",version:null,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60261 var root=data.documentElement;var version=this.version||root.getAttribute("version")||this.defaultVersion;if(!this.parser||this.parser.version!==version){var constr=OpenLayers.Format.WMSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw"Can't find a WMS capabilities parser for version "+version;}
60262 this.parser=new constr(this.options);}
60263 var capabilities=this.parser.read(data);capabilities.version=version;return capabilities;},CLASS_NAME:"OpenLayers.Format.WMSCapabilities"});OpenLayers.Format.WMSDescribeLayer=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.1.1",version:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60264 var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");if(!version){version=this.defaultVersion;}}
60265 if(version=="1.1.1"||version=="1.1.0"){version="1.1";}
60266 var constructor=OpenLayers.Format.WMSDescribeLayer["v"+version.replace(/\./g,"_")];if(!constructor){throw"Can't find a WMS DescribeLayer parser for version "+
60267 version;}
60268 var parser=new constructor(this.options);var describelayer=parser.read(data);describelayer.version=version;return describelayer;},CLASS_NAME:"OpenLayers.Format.WMSDescribeLayer"});OpenLayers.Format.WMSGetFeatureInfo=OpenLayers.Class(OpenLayers.Format.XML,{layerIdentifier:'_layer',featureIdentifier:'_feature',regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},gmlFormat:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,arguments);OpenLayers.Util.extend(this,options);this.options=options;},read:function(data){var result;if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60269 var root=data.documentElement;if(root){var scope=this;var read=this["read_"+root.nodeName];if(read){result=read.call(this,root);}else{result=new OpenLayers.Format.GML((this.options?this.options:{})).read(data);}}else{result=data;}
60270 return result;},read_msGMLOutput:function(data){var response=[];var layerNodes=this.getSiblingNodesByTagCriteria(data,this.layerIdentifier);if(layerNodes){for(var i=0,len=layerNodes.length;i<len;++i){var node=layerNodes[i];var layerName=node.nodeName;if(node.prefix){layerName=layerName.split(':')[1];}
60271 var layerName=layerName.replace(this.layerIdentifier,'');var featureNodes=this.getSiblingNodesByTagCriteria(node,this.featureIdentifier);if(featureNodes){for(var j=0;j<featureNodes.length;j++){var featureNode=featureNodes[j];var geomInfo=this.parseGeometry(featureNode);var attributes=this.parseAttributes(featureNode);var feature=new OpenLayers.Feature.Vector(geomInfo.geometry,attributes,null);feature.bounds=geomInfo.bounds;feature.type=layerName;response.push(feature);}}}}
60272 return response;},read_FeatureInfoResponse:function(data){var response=[];var featureNodes=this.getElementsByTagNameNS(data,'*','FIELDS');for(var i=0,len=featureNodes.length;i<len;i++){var featureNode=featureNodes[i];var geom=null;var attributes={};for(var j=0,jlen=featureNode.attributes.length;j<jlen;j++){var attribute=featureNode.attributes[j];attributes[attribute.nodeName]=attribute.nodeValue;}
60273 response.push(new OpenLayers.Feature.Vector(geom,attributes,null));}
60274 return response;},getSiblingNodesByTagCriteria:function(node,criteria){var nodes=[];var children,tagName,n,matchNodes,child;if(node&&node.hasChildNodes()){children=node.childNodes;n=children.length;for(var k=0;k<n;k++){child=children[k];while(child&&child.nodeType!=1){child=child.nextSibling;k++;}
60275 tagName=(child?child.nodeName:'');if(tagName.length>0&&tagName.indexOf(criteria)>-1){nodes.push(child);}else{matchNodes=this.getSiblingNodesByTagCriteria(child,criteria);if(matchNodes.length>0){(nodes.length==0)?nodes=matchNodes:nodes.push(matchNodes);}}}}
60276 return nodes;},parseAttributes:function(node){var attributes={};if(node.nodeType==1){var children=node.childNodes;var n=children.length;for(var i=0;i<n;++i){var child=children[i];if(child.nodeType==1){var grandchildren=child.childNodes;if(grandchildren.length==1){var grandchild=grandchildren[0];if(grandchild.nodeType==3||grandchild.nodeType==4){var name=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;var value=grandchild.nodeValue.replace(this.regExes.trimSpace,"");attributes[name]=value;}}}}}
60277 return attributes;},parseGeometry:function(node){if(!this.gmlFormat){this.gmlFormat=new OpenLayers.Format.GML();}
60278 var feature=this.gmlFormat.parseFeature(node);var geometry,bounds=null;if(feature){geometry=feature.geometry&&feature.geometry.clone();bounds=feature.bounds&&feature.bounds.clone();feature.destroy();}
60279 return{geometry:geometry,bounds:bounds};},CLASS_NAME:"OpenLayers.Format.WMSGetFeatureInfo"});OpenLayers.Format.WMTSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,parser:null,yx:{"urn:ogc:def:crs:EPSG::4326":true},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60280 var root=data.documentElement;var version=this.version||root.getAttribute("version")||this.defaultVersion;if(!this.parser||this.parser.version!==version){var constr=OpenLayers.Format.WMTSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw new Error("Can't find a WMTS capabilities parser for version "+version);}
60281 this.parser=new constr(this.options);}
60282 return this.parser.read(data);},createLayer:function(capabilities,config){var layer;var required={layer:true,matrixSet:true};for(var prop in required){if(!(prop in config)){throw new Error("Missing property '"+prop+"' in layer configuration.");}}
60283 var contents=capabilities.contents;var matrixSet=contents.tileMatrixSets[config.matrixSet];var layers=contents.layers;var layerDef;for(var i=0,ii=contents.layers.length;i<ii;++i){if(contents.layers[i].identifier===config.layer){layerDef=contents.layers[i];break;}}
60284 if(layerDef&&matrixSet){var style;for(var i=0,ii=layerDef.styles.length;i<ii;++i){style=layerDef.styles[i];if(style.isDefault){break;}}
60285 layer=new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults(config,{url:capabilities.operationsMetadata.GetTile.dcp.http.get,name:layerDef.title,style:style,matrixIds:matrixSet.matrixIds}));}
60286 return layer;},CLASS_NAME:"OpenLayers.Format.WMTSCapabilities"});OpenLayers.Handler.Click=OpenLayers.Class(OpenLayers.Handler,{delay:300,single:true,'double':false,pixelTolerance:0,stopSingle:false,stopDouble:false,timerId:null,down:null,rightclickTimerId:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);if(this.pixelTolerance!=null){this.mousedown=function(evt){this.down=evt.xy;return true;};}},mousedown:null,mouseup:function(evt){var propagate=true;if(this.checkModifiers(evt)&&this.control.handleRightClicks&&OpenLayers.Event.isRightClick(evt)){propagate=this.rightclick(evt);}
60287 return propagate;},rightclick:function(evt){if(this.passesTolerance(evt)){if(this.rightclickTimerId!=null){this.clearTimer();this.callback('dblrightclick',[evt]);return!this.stopDouble;}else{var clickEvent=this['double']?OpenLayers.Util.extend({},evt):this.callback('rightclick',[evt]);var delayedRightCall=OpenLayers.Function.bind(this.delayedRightCall,this,clickEvent);this.rightclickTimerId=window.setTimeout(delayedRightCall,this.delay);}}
60288 return!this.stopSingle;},delayedRightCall:function(evt){this.rightclickTimerId=null;if(evt){this.callback('rightclick',[evt]);}
60289 return!this.stopSingle;},dblclick:function(evt){if(this.passesTolerance(evt)){if(this["double"]){this.callback('dblclick',[evt]);}
60290 this.clearTimer();}
60291 return!this.stopDouble;},click:function(evt){if(this.passesTolerance(evt)){if(this.timerId!=null){this.clearTimer();}else{var clickEvent=this.single?OpenLayers.Util.extend({},evt):null;this.timerId=window.setTimeout(OpenLayers.Function.bind(this.delayedCall,this,clickEvent),this.delay);}}
60292 return!this.stopSingle;},passesTolerance:function(evt){var passes=true;if(this.pixelTolerance!=null&&this.down){var dpx=Math.sqrt(Math.pow(this.down.x-evt.xy.x,2)+
60293 Math.pow(this.down.y-evt.xy.y,2));if(dpx>this.pixelTolerance){passes=false;}}
60294 return passes;},clearTimer:function(){if(this.timerId!=null){window.clearTimeout(this.timerId);this.timerId=null;}
60295 if(this.rightclickTimerId!=null){window.clearTimeout(this.rightclickTimerId);this.rightclickTimerId=null;}},delayedCall:function(evt){this.timerId=null;if(evt){this.callback('click',[evt]);}},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.clearTimer();this.down=null;deactivated=true;}
60296 return deactivated;},CLASS_NAME:"OpenLayers.Handler.Click"});OpenLayers.Handler.Drag=OpenLayers.Class(OpenLayers.Handler,{started:false,stopDown:true,dragging:false,last:null,start:null,oldOnselectstart:null,interval:0,timeoutId:null,documentDrag:false,documentEvents:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);},down:function(evt){},move:function(evt){},up:function(evt){},out:function(evt){},mousedown:function(evt){var propagate=true;this.dragging=false;if(this.checkModifiers(evt)&&OpenLayers.Event.isLeftClick(evt)){this.started=true;this.start=evt.xy;this.last=evt.xy;OpenLayers.Element.addClass(this.map.viewPortDiv,"olDragDown");this.down(evt);this.callback("down",[evt.xy]);OpenLayers.Event.stop(evt);if(!this.oldOnselectstart){this.oldOnselectstart=(document.onselectstart)?document.onselectstart:OpenLayers.Function.True;}
60297 document.onselectstart=OpenLayers.Function.False;propagate=!this.stopDown;}else{this.started=false;this.start=null;this.last=null;}
60298 return propagate;},mousemove:function(evt){if(this.started&&!this.timeoutId&&(evt.xy.x!=this.last.x||evt.xy.y!=this.last.y)){if(this.documentDrag===true&&this.documentEvents){if(evt.element===document){this.adjustXY(evt);this.setEvent(evt);}else{this.destroyDocumentEvents();}}
60299 if(this.interval>0){this.timeoutId=setTimeout(OpenLayers.Function.bind(this.removeTimeout,this),this.interval);}
60300 this.dragging=true;this.move(evt);this.callback("move",[evt.xy]);if(!this.oldOnselectstart){this.oldOnselectstart=document.onselectstart;document.onselectstart=OpenLayers.Function.False;}
60301 this.last=this.evt.xy;}
60302 return true;},removeTimeout:function(){this.timeoutId=null;},mouseup:function(evt){if(this.started){if(this.documentDrag===true&&this.documentEvents){this.adjustXY(evt);this.destroyDocumentEvents();}
60303 var dragged=(this.start!=this.last);this.started=false;this.dragging=false;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");this.up(evt);this.callback("up",[evt.xy]);if(dragged){this.callback("done",[evt.xy]);}
60304 document.onselectstart=this.oldOnselectstart;}
60305 return true;},mouseout:function(evt){if(this.started&&OpenLayers.Util.mouseLeft(evt,this.map.div)){if(this.documentDrag===true){this.documentEvents=new OpenLayers.Events(this,document,null,null,{includeXY:true});this.documentEvents.on({mousemove:this.mousemove,mouseup:this.mouseup});OpenLayers.Element.addClass(document.body,"olDragDown");}else{var dragged=(this.start!=this.last);this.started=false;this.dragging=false;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");this.out(evt);this.callback("out",[]);if(dragged){this.callback("done",[evt.xy]);}
60306 if(document.onselectstart){document.onselectstart=this.oldOnselectstart;}}}
60307 return true;},click:function(evt){return(this.start==this.last);},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.dragging=false;activated=true;}
60308 return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.started=false;this.dragging=false;this.start=null;this.last=null;deactivated=true;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");}
60309 return deactivated;},adjustXY:function(evt){var pos=OpenLayers.Util.pagePosition(this.map.div);evt.xy.x-=pos[0];evt.xy.y-=pos[1];},destroyDocumentEvents:function(){OpenLayers.Element.removeClass(document.body,"olDragDown");this.documentEvents.destroy();this.documentEvents=null;},CLASS_NAME:"OpenLayers.Handler.Drag"});OpenLayers.Handler.Feature=OpenLayers.Class(OpenLayers.Handler,{EVENTMAP:{'click':{'in':'click','out':'clickout'},'mousemove':{'in':'over','out':'out'},'dblclick':{'in':'dblclick','out':null},'mousedown':{'in':null,'out':null},'mouseup':{'in':null,'out':null}},feature:null,lastFeature:null,down:null,up:null,clickTolerance:4,geometryTypes:null,stopClick:true,stopDown:true,stopUp:false,initialize:function(control,layer,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,[control,callbacks,options]);this.layer=layer;},mousedown:function(evt){this.down=evt.xy;return this.handle(evt)?!this.stopDown:true;},mouseup:function(evt){this.up=evt.xy;return this.handle(evt)?!this.stopUp:true;},click:function(evt){return this.handle(evt)?!this.stopClick:true;},mousemove:function(evt){if(!this.callbacks['over']&&!this.callbacks['out']){return true;}
60310 this.handle(evt);return true;},dblclick:function(evt){return!this.handle(evt);},geometryTypeMatches:function(feature){return this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)>-1;},handle:function(evt){if(this.feature&&!this.feature.layer){this.feature=null;}
60311 var type=evt.type;var handled=false;var previouslyIn=!!(this.feature);var click=(type=="click"||type=="dblclick");this.feature=this.layer.getFeatureFromEvent(evt);if(this.feature&&!this.feature.layer){this.feature=null;}
60312 if(this.lastFeature&&!this.lastFeature.layer){this.lastFeature=null;}
60313 if(this.feature){var inNew=(this.feature!=this.lastFeature);if(this.geometryTypeMatches(this.feature)){if(previouslyIn&&inNew){if(this.lastFeature){this.triggerCallback(type,'out',[this.lastFeature]);}
60314 this.triggerCallback(type,'in',[this.feature]);}else if(!previouslyIn||click){this.triggerCallback(type,'in',[this.feature]);}
60315 this.lastFeature=this.feature;handled=true;}else{if(this.lastFeature&&(previouslyIn&&inNew||click)){this.triggerCallback(type,'out',[this.lastFeature]);}
60316 this.feature=null;}}else{if(this.lastFeature&&(previouslyIn||click)){this.triggerCallback(type,'out',[this.lastFeature]);}}
60317 return handled;},triggerCallback:function(type,mode,args){var key=this.EVENTMAP[type][mode];if(key){if(type=='click'&&this.up&&this.down){var dpx=Math.sqrt(Math.pow(this.up.x-this.down.x,2)+
60318 Math.pow(this.up.y-this.down.y,2));if(dpx<=this.clickTolerance){this.callback(key,args);}}else{this.callback(key,args);}}},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.moveLayerToTop();this.map.events.on({"removelayer":this.handleMapEvents,"changelayer":this.handleMapEvents,scope:this});activated=true;}
60319 return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.moveLayerBack();this.feature=null;this.lastFeature=null;this.down=null;this.up=null;this.map.events.un({"removelayer":this.handleMapEvents,"changelayer":this.handleMapEvents,scope:this});deactivated=true;}
60320 return deactivated;},handleMapEvents:function(evt){if(!evt.property||evt.property=="order"){this.moveLayerToTop();}},moveLayerToTop:function(){var index=Math.max(this.map.Z_INDEX_BASE['Feature']-1,this.layer.getZIndex())+1;this.layer.setZIndex(index);},moveLayerBack:function(){var index=this.layer.getZIndex()-1;if(index>=this.map.Z_INDEX_BASE['Feature']){this.layer.setZIndex(index);}else{this.map.setLayerZIndex(this.layer,this.map.getLayerIndex(this.layer));}},CLASS_NAME:"OpenLayers.Handler.Feature"});OpenLayers.Handler.Hover=OpenLayers.Class(OpenLayers.Handler,{delay:500,pixelTolerance:null,stopMove:false,px:null,timerId:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);},mousemove:function(evt){if(this.passesTolerance(evt.xy)){this.clearTimer();this.callback('move',[evt]);this.px=evt.xy;evt=OpenLayers.Util.extend({},evt);this.timerId=window.setTimeout(OpenLayers.Function.bind(this.delayedCall,this,evt),this.delay);}
60321 return!this.stopMove;},mouseout:function(evt){if(OpenLayers.Util.mouseLeft(evt,this.map.div)){this.clearTimer();this.callback('move',[evt]);}
60322 return true;},passesTolerance:function(px){var passes=true;if(this.pixelTolerance&&this.px){var dpx=Math.sqrt(Math.pow(this.px.x-px.x,2)+
60323 Math.pow(this.px.y-px.y,2));if(dpx<this.pixelTolerance){passes=false;}}
60324 return passes;},clearTimer:function(){if(this.timerId!=null){window.clearTimeout(this.timerId);this.timerId=null;}},delayedCall:function(evt){this.callback('pause',[evt]);},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.clearTimer();deactivated=true;}
60325 return deactivated;},CLASS_NAME:"OpenLayers.Handler.Hover"});OpenLayers.Handler.Keyboard=OpenLayers.Class(OpenLayers.Handler,{KEY_EVENTS:["keydown","keyup"],eventListener:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);this.eventListener=OpenLayers.Function.bindAsEventListener(this.handleKeyEvent,this);},destroy:function(){this.deactivate();this.eventListener=null;OpenLayers.Handler.prototype.destroy.apply(this,arguments);},activate:function(){if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){for(var i=0,len=this.KEY_EVENTS.length;i<len;i++){OpenLayers.Event.observe(document,this.KEY_EVENTS[i],this.eventListener);}
60326 return true;}else{return false;}},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){for(var i=0,len=this.KEY_EVENTS.length;i<len;i++){OpenLayers.Event.stopObserving(document,this.KEY_EVENTS[i],this.eventListener);}
60327 deactivated=true;}
60328 return deactivated;},handleKeyEvent:function(evt){if(this.checkModifiers(evt)){this.callback(evt.type,[evt]);}},CLASS_NAME:"OpenLayers.Handler.Keyboard"});OpenLayers.Handler.MouseWheel=OpenLayers.Class(OpenLayers.Handler,{wheelListener:null,mousePosition:null,interval:0,delta:0,cumulative:true,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);this.wheelListener=OpenLayers.Function.bindAsEventListener(this.onWheelEvent,this);},destroy:function(){OpenLayers.Handler.prototype.destroy.apply(this,arguments);this.wheelListener=null;},onWheelEvent:function(e){if(!this.map||!this.checkModifiers(e)){return;}
60329 var overScrollableDiv=false;var overLayerDiv=false;var overMapDiv=false;var elem=OpenLayers.Event.element(e);while((elem!=null)&&!overMapDiv&&!overScrollableDiv){if(!overScrollableDiv){try{if(elem.currentStyle){overflow=elem.currentStyle["overflow"];}else{var style=document.defaultView.getComputedStyle(elem,null);var overflow=style.getPropertyValue("overflow");}
60330 overScrollableDiv=(overflow&&(overflow=="auto")||(overflow=="scroll"));}catch(err){}}
60331 if(!overLayerDiv){for(var i=0,len=this.map.layers.length;i<len;i++){if(elem==this.map.layers[i].div||elem==this.map.layers[i].pane){overLayerDiv=true;break;}}}
60332 overMapDiv=(elem==this.map.div);elem=elem.parentNode;}
60333 if(!overScrollableDiv&&overMapDiv){if(overLayerDiv){var delta=0;if(!e){e=window.event;}
60334 if(e.wheelDelta){delta=e.wheelDelta/120;if(window.opera&&window.opera.version()<9.2){delta=-delta;}}else if(e.detail){delta=-e.detail/3;}
60335 this.delta=this.delta+delta;if(this.interval){window.clearTimeout(this._timeoutId);this._timeoutId=window.setTimeout(OpenLayers.Function.bind(function(){this.wheelZoom(e);},this),this.interval);}else{this.wheelZoom(e);}}
60336 OpenLayers.Event.stop(e);}},wheelZoom:function(e){var delta=this.delta;this.delta=0;if(delta){if(this.mousePosition){e.xy=this.mousePosition;}
60337 if(!e.xy){e.xy=this.map.getPixelFromLonLat(this.map.getCenter());}
60338 if(delta<0){this.callback("down",[e,this.cumulative?delta:-1]);}else{this.callback("up",[e,this.cumulative?delta:1]);}}},mousemove:function(evt){this.mousePosition=evt.xy;},activate:function(evt){if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){var wheelListener=this.wheelListener;OpenLayers.Event.observe(window,"DOMMouseScroll",wheelListener);OpenLayers.Event.observe(window,"mousewheel",wheelListener);OpenLayers.Event.observe(document,"mousewheel",wheelListener);return true;}else{return false;}},deactivate:function(evt){if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){var wheelListener=this.wheelListener;OpenLayers.Event.stopObserving(window,"DOMMouseScroll",wheelListener);OpenLayers.Event.stopObserving(window,"mousewheel",wheelListener);OpenLayers.Event.stopObserving(document,"mousewheel",wheelListener);return true;}else{return false;}},CLASS_NAME:"OpenLayers.Handler.MouseWheel"});OpenLayers.Layer=OpenLayers.Class({id:null,name:null,div:null,opacity:null,alwaysInRange:null,EVENT_TYPES:["loadstart","loadend","loadcancel","visibilitychanged","move","moveend"],RESOLUTION_PROPERTIES:['scales','resolutions','maxScale','minScale','maxResolution','minResolution','numZoomLevels','maxZoomLevel'],events:null,map:null,isBaseLayer:false,alpha:false,displayInLayerSwitcher:true,visibility:true,attribution:null,inRange:false,imageSize:null,imageOffset:null,options:null,eventListeners:null,gutter:0,projection:null,units:null,scales:null,resolutions:null,maxExtent:null,minExtent:null,maxResolution:null,minResolution:null,numZoomLevels:null,minScale:null,maxScale:null,displayOutsideMaxExtent:false,wrapDateLine:false,transitionEffect:null,SUPPORTED_TRANSITIONS:['resize'],metadata:{},initialize:function(name,options){this.addOptions(options);this.name=name;if(this.id==null){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");this.div=OpenLayers.Util.createDiv(this.id);this.div.style.width="100%";this.div.style.height="100%";this.div.dir="ltr";this.events=new OpenLayers.Events(this,this.div,this.EVENT_TYPES);if(this.eventListeners instanceof Object){this.events.on(this.eventListeners);}}
60339 if(this.wrapDateLine){this.displayOutsideMaxExtent=true;}},destroy:function(setNewBaseLayer){if(setNewBaseLayer==null){setNewBaseLayer=true;}
60340 if(this.map!=null){this.map.removeLayer(this,setNewBaseLayer);}
60341 this.projection=null;this.map=null;this.name=null;this.div=null;this.options=null;if(this.events){if(this.eventListeners){this.events.un(this.eventListeners);}
60342 this.events.destroy();}
60343 this.eventListeners=null;this.events=null;},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer(this.name,this.getOptions());}
60344 OpenLayers.Util.applyDefaults(obj,this);obj.map=null;return obj;},getOptions:function(){var options={};for(var o in this.options){options[o]=this[o];}
60345 return options;},setName:function(newName){if(newName!=this.name){this.name=newName;if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"name"});}}},addOptions:function(newOptions){if(this.options==null){this.options={};}
60346 OpenLayers.Util.extend(this.options,newOptions);OpenLayers.Util.extend(this,newOptions);if(typeof this.projection=="string"){this.projection=new OpenLayers.Projection(this.projection);}
60347 if(this.projection&&this.projection.getUnits()){this.units=this.projection.getUnits();}
60348 if(this.map){var properties=this.RESOLUTION_PROPERTIES.concat(["projection","units","minExtent","maxExtent"]);for(var o in newOptions){if(newOptions.hasOwnProperty(o)&&OpenLayers.Util.indexOf(properties,o)>=0){this.initResolutions();break;}}}},onMapResize:function(){},redraw:function(){var redrawn=false;if(this.map){this.inRange=this.calculateInRange();var extent=this.getExtent();if(extent&&this.inRange&&this.visibility){var zoomChanged=true;this.moveTo(extent,zoomChanged,false);this.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});redrawn=true;}}
60349 return redrawn;},moveTo:function(bounds,zoomChanged,dragging){var display=this.visibility;if(!this.isBaseLayer){display=display&&this.inRange;}
60350 this.display(display);},setMap:function(map){if(this.map==null){this.map=map;this.maxExtent=this.maxExtent||this.map.maxExtent;this.minExtent=this.minExtent||this.map.minExtent;this.projection=this.projection||this.map.projection;if(typeof this.projection=="string"){this.projection=new OpenLayers.Projection(this.projection);}
60351 this.units=this.projection.getUnits()||this.units||this.map.units;this.initResolutions();if(!this.isBaseLayer){this.inRange=this.calculateInRange();var show=((this.visibility)&&(this.inRange));this.div.style.display=show?"":"none";}
60352 this.setTileSize();}},afterAdd:function(){},removeMap:function(map){},getImageSize:function(bounds){return(this.imageSize||this.tileSize);},setTileSize:function(size){var tileSize=(size)?size:((this.tileSize)?this.tileSize:this.map.getTileSize());this.tileSize=tileSize;if(this.gutter){this.imageOffset=new OpenLayers.Pixel(-this.gutter,-this.gutter);this.imageSize=new OpenLayers.Size(tileSize.w+(2*this.gutter),tileSize.h+(2*this.gutter));}},getVisibility:function(){return this.visibility;},setVisibility:function(visibility){if(visibility!=this.visibility){this.visibility=visibility;this.display(visibility);this.redraw();if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"visibility"});}
60353 this.events.triggerEvent("visibilitychanged");}},display:function(display){if(display!=(this.div.style.display!="none")){this.div.style.display=(display&&this.calculateInRange())?"block":"none";}},calculateInRange:function(){var inRange=false;if(this.alwaysInRange){inRange=true;}else{if(this.map){var resolution=this.map.getResolution();inRange=((resolution>=this.minResolution)&&(resolution<=this.maxResolution));}}
60354 return inRange;},setIsBaseLayer:function(isBaseLayer){if(isBaseLayer!=this.isBaseLayer){this.isBaseLayer=isBaseLayer;if(this.map!=null){this.map.events.triggerEvent("changebaselayer",{layer:this});}}},initResolutions:function(){var i,len;var props={},alwaysInRange=true;for(i=0,len=this.RESOLUTION_PROPERTIES.length;i<len;i++){var p=this.RESOLUTION_PROPERTIES[i];props[p]=this.options[p];if(alwaysInRange&&this.options[p]){alwaysInRange=false;}}
60355 if(this.alwaysInRange==null){this.alwaysInRange=alwaysInRange;}
60356 if(props.resolutions==null){props.resolutions=this.resolutionsFromScales(props.scales);}
60357 if(props.resolutions==null){props.resolutions=this.calculateResolutions(props);}
60358 if(props.resolutions==null){for(i=0,len=this.RESOLUTION_PROPERTIES.length;i<len;i++){var p=this.RESOLUTION_PROPERTIES[i];props[p]=this.options[p]!=null?this.options[p]:this.map[p];}
60359 if(props.resolutions==null){props.resolutions=this.resolutionsFromScales(props.scales);}
60360 if(props.resolutions==null){props.resolutions=this.calculateResolutions(props);}}
60361 var maxResolution;if(this.options.maxResolution&&this.options.maxResolution!=="auto"){maxResolution=this.options.maxResolution;}
60362 if(this.options.minScale){maxResolution=OpenLayers.Util.getResolutionFromScale(this.options.minScale,this.units);}
60363 var minResolution;if(this.options.minResolution&&this.options.minResolution!=="auto"){minResolution=this.options.minResolution;}
60364 if(this.options.maxScale){minResolution=OpenLayers.Util.getResolutionFromScale(this.options.maxScale,this.units);}
60365 if(props.resolutions){props.resolutions.sort(function(a,b){return(b-a);});if(!maxResolution){maxResolution=props.resolutions[0];}
60366 if(!minResolution){var lastIdx=props.resolutions.length-1;minResolution=props.resolutions[lastIdx];}}
60367 this.resolutions=props.resolutions;if(this.resolutions){len=this.resolutions.length;this.scales=new Array(len);for(i=0;i<len;i++){this.scales[i]=OpenLayers.Util.getScaleFromResolution(this.resolutions[i],this.units);}
60368 this.numZoomLevels=len;}
60369 this.minResolution=minResolution;if(minResolution){this.maxScale=OpenLayers.Util.getScaleFromResolution(minResolution,this.units);}
60370 this.maxResolution=maxResolution;if(maxResolution){this.minScale=OpenLayers.Util.getScaleFromResolution(maxResolution,this.units);}},resolutionsFromScales:function(scales){if(scales==null){return;}
60371 var resolutions,i,len;len=scales.length;resolutions=new Array(len);for(i=0;i<len;i++){resolutions[i]=OpenLayers.Util.getResolutionFromScale(scales[i],this.units);}
60372 return resolutions;},calculateResolutions:function(props){var maxResolution=props.maxResolution;if(props.minScale!=null){maxResolution=OpenLayers.Util.getResolutionFromScale(props.minScale,this.units);}else if(maxResolution=="auto"&&this.maxExtent!=null){var viewSize=this.map.getSize();var wRes=this.maxExtent.getWidth()/viewSize.w;var hRes=this.maxExtent.getHeight()/viewSize.h;maxResolution=Math.max(wRes,hRes);}
60373 var minResolution=props.minResolution;if(props.maxScale!=null){minResolution=OpenLayers.Util.getResolutionFromScale(props.maxScale,this.units);}else if(props.minResolution=="auto"&&this.minExtent!=null){var viewSize=this.map.getSize();var wRes=this.minExtent.getWidth()/viewSize.w;var hRes=this.minExtent.getHeight()/viewSize.h;minResolution=Math.max(wRes,hRes);}
60374 var maxZoomLevel=props.maxZoomLevel;var numZoomLevels=props.numZoomLevels;if(typeof minResolution==="number"&&typeof maxResolution==="number"&&numZoomLevels===undefined){var ratio=maxResolution/minResolution;numZoomLevels=Math.floor(Math.log(ratio)/Math.log(2))+1;}else if(numZoomLevels===undefined&&maxZoomLevel!=null){numZoomLevels=maxZoomLevel+1;}
60375 if(typeof numZoomLevels!=="number"||numZoomLevels<=0||(typeof maxResolution!=="number"&&typeof minResolution!=="number")){return;}
60376 var resolutions=new Array(numZoomLevels);var base=2;if(typeof minResolution=="number"&&typeof maxResolution=="number"){base=Math.pow((maxResolution/minResolution),(1/(numZoomLevels-1)));}
60377 var i;if(typeof maxResolution==="number"){for(i=0;i<numZoomLevels;i++){resolutions[i]=maxResolution/Math.pow(base,i);}}else{for(i=0;i<numZoomLevels;i++){resolutions[numZoomLevels-1-i]=minResolution*Math.pow(base,i);}}
60378 return resolutions;},getResolution:function(){var zoom=this.map.getZoom();return this.getResolutionForZoom(zoom);},getExtent:function(){return this.map.calculateBounds();},getZoomForExtent:function(extent,closest){var viewSize=this.map.getSize();var idealResolution=Math.max(extent.getWidth()/viewSize.w,extent.getHeight()/viewSize.h);return this.getZoomForResolution(idealResolution,closest);},getDataExtent:function(){},getResolutionForZoom:function(zoom){zoom=Math.max(0,Math.min(zoom,this.resolutions.length-1));var resolution;if(this.map.fractionalZoom){var low=Math.floor(zoom);var high=Math.ceil(zoom);resolution=this.resolutions[low]-
60379 ((zoom-low)*(this.resolutions[low]-this.resolutions[high]));}else{resolution=this.resolutions[Math.round(zoom)];}
60380 return resolution;},getZoomForResolution:function(resolution,closest){var zoom;if(this.map.fractionalZoom){var lowZoom=0;var highZoom=this.resolutions.length-1;var highRes=this.resolutions[lowZoom];var lowRes=this.resolutions[highZoom];var res;for(var i=0,len=this.resolutions.length;i<len;++i){res=this.resolutions[i];if(res>=resolution){highRes=res;lowZoom=i;}
60381 if(res<=resolution){lowRes=res;highZoom=i;break;}}
60382 var dRes=highRes-lowRes;if(dRes>0){zoom=lowZoom+((highRes-resolution)/dRes);}else{zoom=lowZoom;}}else{var diff;var minDiff=Number.POSITIVE_INFINITY;for(var i=0,len=this.resolutions.length;i<len;i++){if(closest){diff=Math.abs(this.resolutions[i]-resolution);if(diff>minDiff){break;}
60383 minDiff=diff;}else{if(this.resolutions[i]<resolution){break;}}}
60384 zoom=Math.max(0,i-1);}
60385 return zoom;},getLonLatFromViewPortPx:function(viewPortPx){var lonlat=null;if(viewPortPx!=null){var size=this.map.getSize();var center=this.map.getCenter();if(center){var res=this.map.getResolution();var delta_x=viewPortPx.x-(size.w/2);var delta_y=viewPortPx.y-(size.h/2);lonlat=new OpenLayers.LonLat(center.lon+delta_x*res,center.lat-delta_y*res);if(this.wrapDateLine){lonlat=lonlat.wrapDateLine(this.maxExtent);}}}
60386 return lonlat;},getViewPortPxFromLonLat:function(lonlat){var px=null;if(lonlat!=null){var resolution=this.map.getResolution();var extent=this.map.getExtent();px=new OpenLayers.Pixel((1/resolution*(lonlat.lon-extent.left)),(1/resolution*(extent.top-lonlat.lat)));}
60387 return px;},setOpacity:function(opacity){if(opacity!=this.opacity){this.opacity=opacity;for(var i=0,len=this.div.childNodes.length;i<len;++i){var element=this.div.childNodes[i].firstChild;OpenLayers.Util.modifyDOMElement(element,null,null,null,null,null,null,opacity);}
60388 if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"opacity"});}}},getZIndex:function(){return this.div.style.zIndex;},setZIndex:function(zIndex){this.div.style.zIndex=zIndex;},adjustBounds:function(bounds){if(this.gutter){var mapGutter=this.gutter*this.map.getResolution();bounds=new OpenLayers.Bounds(bounds.left-mapGutter,bounds.bottom-mapGutter,bounds.right+mapGutter,bounds.top+mapGutter);}
60389 if(this.wrapDateLine){var wrappingOptions={'rightTolerance':this.getResolution()};bounds=bounds.wrapDateLine(this.maxExtent,wrappingOptions);}
60390 return bounds;},CLASS_NAME:"OpenLayers.Layer"});OpenLayers.Marker.Box=OpenLayers.Class(OpenLayers.Marker,{bounds:null,div:null,initialize:function(bounds,borderColor,borderWidth){this.bounds=bounds;this.div=OpenLayers.Util.createDiv();this.div.style.overflow='hidden';this.events=new OpenLayers.Events(this,this.div,null);this.setBorder(borderColor,borderWidth);},destroy:function(){this.bounds=null;this.div=null;OpenLayers.Marker.prototype.destroy.apply(this,arguments);},setBorder:function(color,width){if(!color){color="red";}
60391 if(!width){width=2;}
60392 this.div.style.border=width+"px solid "+color;},draw:function(px,sz){OpenLayers.Util.modifyDOMElement(this.div,null,px,sz);return this.div;},onScreen:function(){var onScreen=false;if(this.map){var screenBounds=this.map.getExtent();onScreen=screenBounds.containsBounds(this.bounds,true,true);}
60393 return onScreen;},display:function(display){this.div.style.display=(display)?"":"none";},CLASS_NAME:"OpenLayers.Marker.Box"});(function(){var oXMLHttpRequest=window.XMLHttpRequest;var bGecko=!!window.controllers,bIE=window.document.all&&!window.opera,bIE7=bIE&&window.navigator.userAgent.match(/MSIE ([\.0-9]+)/)&&RegExp.$1==7;function cXMLHttpRequest(){this._object=oXMLHttpRequest&&!bIE7?new oXMLHttpRequest:new window.ActiveXObject("Microsoft.XMLHTTP");this._listeners=[];};if(bGecko&&oXMLHttpRequest.wrapped)
60394 cXMLHttpRequest.wrapped=oXMLHttpRequest.wrapped;cXMLHttpRequest.UNSENT=0;cXMLHttpRequest.OPENED=1;cXMLHttpRequest.HEADERS_RECEIVED=2;cXMLHttpRequest.LOADING=3;cXMLHttpRequest.DONE=4;cXMLHttpRequest.prototype.readyState=cXMLHttpRequest.UNSENT;cXMLHttpRequest.prototype.responseText='';cXMLHttpRequest.prototype.responseXML=null;cXMLHttpRequest.prototype.status=0;cXMLHttpRequest.prototype.statusText='';cXMLHttpRequest.prototype.onreadystatechange=null;cXMLHttpRequest.onreadystatechange=null;cXMLHttpRequest.onopen=null;cXMLHttpRequest.onsend=null;cXMLHttpRequest.onabort=null;cXMLHttpRequest.prototype.open=function(sMethod,sUrl,bAsync,sUser,sPassword){delete this._headers;if(arguments.length<3)
60395 bAsync=true;this._async=bAsync;var oRequest=this,nState=this.readyState,fOnUnload;if(bIE&&bAsync){fOnUnload=function(){if(nState!=cXMLHttpRequest.DONE){fCleanTransport(oRequest);oRequest.abort();}};window.attachEvent("onunload",fOnUnload);}
60396 if(cXMLHttpRequest.onopen)
60397 cXMLHttpRequest.onopen.apply(this,arguments);if(arguments.length>4)
60398 this._object.open(sMethod,sUrl,bAsync,sUser,sPassword);else
60399 if(arguments.length>3)
60400 this._object.open(sMethod,sUrl,bAsync,sUser);else
60401 this._object.open(sMethod,sUrl,bAsync);if(!bGecko&&!bIE){this.readyState=cXMLHttpRequest.OPENED;fReadyStateChange(this);}
60402 this._object.onreadystatechange=function(){if(bGecko&&!bAsync)
60403 return;oRequest.readyState=oRequest._object.readyState;fSynchronizeValues(oRequest);if(oRequest._aborted){oRequest.readyState=cXMLHttpRequest.UNSENT;return;}
60404 if(oRequest.readyState==cXMLHttpRequest.DONE){fCleanTransport(oRequest);if(bIE&&bAsync)
60405 window.detachEvent("onunload",fOnUnload);}
60406 if(nState!=oRequest.readyState)
60407 fReadyStateChange(oRequest);nState=oRequest.readyState;}};cXMLHttpRequest.prototype.send=function(vData){if(cXMLHttpRequest.onsend)
60408 cXMLHttpRequest.onsend.apply(this,arguments);if(vData&&vData.nodeType){vData=window.XMLSerializer?new window.XMLSerializer().serializeToString(vData):vData.xml;if(!this._headers["Content-Type"])
60409 this._object.setRequestHeader("Content-Type","application/xml");}
60410 this._object.send(vData);if(bGecko&&!this._async){this.readyState=cXMLHttpRequest.OPENED;fSynchronizeValues(this);while(this.readyState<cXMLHttpRequest.DONE){this.readyState++;fReadyStateChange(this);if(this._aborted)
60411 return;}}};cXMLHttpRequest.prototype.abort=function(){if(cXMLHttpRequest.onabort)
60412 cXMLHttpRequest.onabort.apply(this,arguments);if(this.readyState>cXMLHttpRequest.UNSENT)
60413 this._aborted=true;this._object.abort();fCleanTransport(this);};cXMLHttpRequest.prototype.getAllResponseHeaders=function(){return this._object.getAllResponseHeaders();};cXMLHttpRequest.prototype.getResponseHeader=function(sName){return this._object.getResponseHeader(sName);};cXMLHttpRequest.prototype.setRequestHeader=function(sName,sValue){if(!this._headers)
60414 this._headers={};this._headers[sName]=sValue;return this._object.setRequestHeader(sName,sValue);};cXMLHttpRequest.prototype.addEventListener=function(sName,fHandler,bUseCapture){for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++)
60415 if(oListener[0]==sName&&oListener[1]==fHandler&&oListener[2]==bUseCapture)
60416 return;this._listeners.push([sName,fHandler,bUseCapture]);};cXMLHttpRequest.prototype.removeEventListener=function(sName,fHandler,bUseCapture){for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++)
60417 if(oListener[0]==sName&&oListener[1]==fHandler&&oListener[2]==bUseCapture)
60418 break;if(oListener)
60419 this._listeners.splice(nIndex,1);};cXMLHttpRequest.prototype.dispatchEvent=function(oEvent){var oEventPseudo={'type':oEvent.type,'target':this,'currentTarget':this,'eventPhase':2,'bubbles':oEvent.bubbles,'cancelable':oEvent.cancelable,'timeStamp':oEvent.timeStamp,'stopPropagation':function(){},'preventDefault':function(){},'initEvent':function(){}};if(oEventPseudo.type=="readystatechange"&&this.onreadystatechange)
60420 (this.onreadystatechange.handleEvent||this.onreadystatechange).apply(this,[oEventPseudo]);for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++)
60421 if(oListener[0]==oEventPseudo.type&&!oListener[2])
60422 (oListener[1].handleEvent||oListener[1]).apply(this,[oEventPseudo]);};cXMLHttpRequest.prototype.toString=function(){return'['+"object"+' '+"XMLHttpRequest"+']';};cXMLHttpRequest.toString=function(){return'['+"XMLHttpRequest"+']';};function fReadyStateChange(oRequest){if(cXMLHttpRequest.onreadystatechange)
60423 cXMLHttpRequest.onreadystatechange.apply(oRequest);oRequest.dispatchEvent({'type':"readystatechange",'bubbles':false,'cancelable':false,'timeStamp':new Date+0});};function fGetDocument(oRequest){var oDocument=oRequest.responseXML,sResponse=oRequest.responseText;if(bIE&&sResponse&&oDocument&&!oDocument.documentElement&&oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)){oDocument=new window.ActiveXObject("Microsoft.XMLDOM");oDocument.async=false;oDocument.validateOnParse=false;oDocument.loadXML(sResponse);}
60424 if(oDocument)
60425 if((bIE&&oDocument.parseError!=0)||!oDocument.documentElement||(oDocument.documentElement&&oDocument.documentElement.tagName=="parsererror"))
60426 return null;return oDocument;};function fSynchronizeValues(oRequest){try{oRequest.responseText=oRequest._object.responseText;}catch(e){}
60427 try{oRequest.responseXML=fGetDocument(oRequest._object);}catch(e){}
60428 try{oRequest.status=oRequest._object.status;}catch(e){}
60429 try{oRequest.statusText=oRequest._object.statusText;}catch(e){}};function fCleanTransport(oRequest){oRequest._object.onreadystatechange=new window.Function;};if(!window.Function.prototype.apply){window.Function.prototype.apply=function(oRequest,oArguments){if(!oArguments)
60430 oArguments=[];oRequest.__func=this;oRequest.__func(oArguments[0],oArguments[1],oArguments[2],oArguments[3],oArguments[4]);delete oRequest.__func;};};OpenLayers.Request.XMLHttpRequest=cXMLHttpRequest;})();OpenLayers.Tile.Image.IFrame=OpenLayers.Class(OpenLayers.Tile.Image,{initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.Image.prototype.initialize.apply(this,arguments);this.layerAlphaHack=false;},destroy:function(){if(this.imgDiv!=null){OpenLayers.Event.stopObservingElement(this.imgDiv.firstChild);}
60431 OpenLayers.Tile.Image.prototype.destroy.apply(this,arguments);},clear:function(){if(this.imgDiv){var iFrame=this.imgDiv.firstChild;OpenLayers.Event.stopObservingElement(iFrame);this.imgDiv.removeChild(iFrame);}},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile.Image.IFrame(this.layer,this.position,this.bounds,this.url,this.size);}
60432 obj=OpenLayers.Tile.Image.prototype.clone.apply(this,[obj]);return obj;},renderTile:function(){if(OpenLayers.Tile.Image.prototype.renderTile.apply(this,arguments)){var form=this.createRequestForm();this.imgDiv.appendChild(form);form.submit();this.imgDiv.removeChild(form);}},initImgDiv:function(){this.imgDiv=this.createImgDiv();OpenLayers.Util.modifyDOMElement(this.imgDiv,this.id,null,this.layer.getImageSize(),"relative");this.imgDiv.className='olTileImage';this.frame.appendChild(this.imgDiv);this.layer.div.appendChild(this.frame);if(this.layer.opacity!=null){OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,null,null,null,null,this.layer.opacity);}
60433 this.imgDiv.map=this.layer.map;},createImgDiv:function(){var eventPane=document.createElement("div");if(OpenLayers.Util.getBrowserName()=="msie"){eventPane.style.backgroundColor='#FFFFFF';eventPane.style.filter='chroma(color=#FFFFFF)';}
60434 OpenLayers.Util.modifyDOMElement(eventPane,null,new OpenLayers.Pixel(0,0),this.layer.getImageSize(),"absolute");var imgDiv=document.createElement("div");imgDiv.appendChild(eventPane);return imgDiv;},createIFrame:function(){var id=this.id+'_iFrame';var iframe;if(OpenLayers.Util.getBrowserName()=="msie"){iframe=document.createElement('<iframe name="'+id+'">');iframe.style.backgroundColor='#FFFFFF';iframe.style.filter='chroma(color=#FFFFFF)';}
60435 else{iframe=document.createElement('iframe');iframe.style.backgroundColor='transparent';iframe.name=id;}
60436 iframe.id=id;iframe.scrolling='no';iframe.marginWidth='0px';iframe.marginHeight='0px';iframe.frameBorder='0';OpenLayers.Util.modifyDOMElement(iframe,id,new OpenLayers.Pixel(0,0),this.layer.getImageSize(),"absolute");var onload=function(){this.show();if(this.isLoading){this.isLoading=false;this.events.triggerEvent("loadend");}};OpenLayers.Event.observe(iframe,'load',OpenLayers.Function.bind(onload,this));return iframe;},createRequestForm:function(){var form=document.createElement('form');form.method='POST';var cacheId=this.layer.params["_OLSALT"];cacheId=(cacheId?cacheId+"_":"")+this.bounds.toBBOX();form.action=OpenLayers.Util.urlAppend(this.layer.url,cacheId);this.imgDiv.insertBefore(this.createIFrame(),this.imgDiv.firstChild);form.target=this.id+'_iFrame';var imageSize=this.layer.getImageSize();var params=OpenLayers.Util.extend({"BBOX":this.encodeBBOX?this.bounds.toBBOX():this.bounds.toArray(),"WIDTH":imageSize.w,"HEIGHT":imageSize.h},this.layer.params);for(var par in params){var field=document.createElement('input');field.type='hidden';field.name=par;field.value=params[par];form.appendChild(field);}
60437 return form;},CLASS_NAME:"OpenLayers.Tile.Image.IFrame"});OpenLayers.ProxyHost="";OpenLayers.nullHandler=function(request){OpenLayers.Console.userError(OpenLayers.i18n("unhandledRequest",{'statusText':request.statusText}));};OpenLayers.loadURL=function(uri,params,caller,onComplete,onFailure){if(typeof params=='string'){params=OpenLayers.Util.getParameters(params);}
60438 var success=(onComplete)?onComplete:OpenLayers.nullHandler;var failure=(onFailure)?onFailure:OpenLayers.nullHandler;return OpenLayers.Request.GET({url:uri,params:params,success:success,failure:failure,scope:caller});};OpenLayers.parseXMLString=function(text){var index=text.indexOf('<');if(index>0){text=text.substring(index);}
60439 var ajaxResponse=OpenLayers.Util.Try(function(){var xmldom=new ActiveXObject('Microsoft.XMLDOM');xmldom.loadXML(text);return xmldom;},function(){return new DOMParser().parseFromString(text,'text/xml');},function(){var req=new XMLHttpRequest();req.open("GET","data:"+"text/xml"+";charset=utf-8,"+encodeURIComponent(text),false);if(req.overrideMimeType){req.overrideMimeType("text/xml");}
60440 req.send(null);return req.responseXML;});return ajaxResponse;};OpenLayers.Ajax={emptyFunction:function(){},getTransport:function(){return OpenLayers.Util.Try(function(){return new XMLHttpRequest();},function(){return new ActiveXObject('Msxml2.XMLHTTP');},function(){return new ActiveXObject('Microsoft.XMLHTTP');})||false;},activeRequestCount:0};OpenLayers.Ajax.Responders={responders:[],register:function(responderToAdd){for(var i=0;i<this.responders.length;i++){if(responderToAdd==this.responders[i]){return;}}
60441 this.responders.push(responderToAdd);},unregister:function(responderToRemove){OpenLayers.Util.removeItem(this.reponders,responderToRemove);},dispatch:function(callback,request,transport){var responder;for(var i=0;i<this.responders.length;i++){responder=this.responders[i];if(responder[callback]&&typeof responder[callback]=='function'){try{responder[callback].apply(responder,[request,transport]);}catch(e){}}}}};OpenLayers.Ajax.Responders.register({onCreate:function(){OpenLayers.Ajax.activeRequestCount++;},onComplete:function(){OpenLayers.Ajax.activeRequestCount--;}});OpenLayers.Ajax.Base=OpenLayers.Class({initialize:function(options){this.options={method:'post',asynchronous:true,contentType:'application/xml',parameters:''};OpenLayers.Util.extend(this.options,options||{});this.options.method=this.options.method.toLowerCase();if(typeof this.options.parameters=='string'){this.options.parameters=OpenLayers.Util.getParameters(this.options.parameters);}}});OpenLayers.Ajax.Request=OpenLayers.Class(OpenLayers.Ajax.Base,{_complete:false,initialize:function(url,options){OpenLayers.Ajax.Base.prototype.initialize.apply(this,[options]);if(OpenLayers.ProxyHost&&OpenLayers.String.startsWith(url,"http")){url=OpenLayers.ProxyHost+encodeURIComponent(url);}
60442 this.transport=OpenLayers.Ajax.getTransport();this.request(url);},request:function(url){this.url=url;this.method=this.options.method;var params=OpenLayers.Util.extend({},this.options.parameters);if(this.method!='get'&&this.method!='post'){params['_method']=this.method;this.method='post';}
60443 this.parameters=params;if(params=OpenLayers.Util.getParameterString(params)){if(this.method=='get'){this.url+=((this.url.indexOf('?')>-1)?'&':'?')+params;}else if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)){params+='&_=';}}
60444 try{var response=new OpenLayers.Ajax.Response(this);if(this.options.onCreate){this.options.onCreate(response);}
60445 OpenLayers.Ajax.Responders.dispatch('onCreate',this,response);this.transport.open(this.method.toUpperCase(),this.url,this.options.asynchronous);if(this.options.asynchronous){window.setTimeout(OpenLayers.Function.bind(this.respondToReadyState,this,1),10);}
60446 this.transport.onreadystatechange=OpenLayers.Function.bind(this.onStateChange,this);this.setRequestHeaders();this.body=this.method=='post'?(this.options.postBody||params):null;this.transport.send(this.body);if(!this.options.asynchronous&&this.transport.overrideMimeType){this.onStateChange();}}catch(e){this.dispatchException(e);}},onStateChange:function(){var readyState=this.transport.readyState;if(readyState>1&&!((readyState==4)&&this._complete)){this.respondToReadyState(this.transport.readyState);}},setRequestHeaders:function(){var headers={'X-Requested-With':'XMLHttpRequest','Accept':'text/javascript, text/html, application/xml, text/xml, */*','OpenLayers':true};if(this.method=='post'){headers['Content-type']=this.options.contentType+
60447 (this.options.encoding?'; charset='+this.options.encoding:'');if(this.transport.overrideMimeType&&(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005){headers['Connection']='close';}}
60448 if(typeof this.options.requestHeaders=='object'){var extras=this.options.requestHeaders;if(typeof extras.push=='function'){for(var i=0,length=extras.length;i<length;i+=2){headers[extras[i]]=extras[i+1];}}else{for(var i in extras){headers[i]=extras[i];}}}
60449 for(var name in headers){this.transport.setRequestHeader(name,headers[name]);}},success:function(){var status=this.getStatus();return!status||(status>=200&&status<300);},getStatus:function(){try{return this.transport.status||0;}catch(e){return 0;}},respondToReadyState:function(readyState){var state=OpenLayers.Ajax.Request.Events[readyState];var response=new OpenLayers.Ajax.Response(this);if(state=='Complete'){try{this._complete=true;(this.options['on'+response.status]||this.options['on'+(this.success()?'Success':'Failure')]||OpenLayers.Ajax.emptyFunction)(response);}catch(e){this.dispatchException(e);}
60450 var contentType=response.getHeader('Content-type');}
60451 try{(this.options['on'+state]||OpenLayers.Ajax.emptyFunction)(response);OpenLayers.Ajax.Responders.dispatch('on'+state,this,response);}catch(e){this.dispatchException(e);}
60452 if(state=='Complete'){this.transport.onreadystatechange=OpenLayers.Ajax.emptyFunction;}},getHeader:function(name){try{return this.transport.getResponseHeader(name);}catch(e){return null;}},dispatchException:function(exception){var handler=this.options.onException;if(handler){handler(this,exception);OpenLayers.Ajax.Responders.dispatch('onException',this,exception);}else{var listener=false;var responders=OpenLayers.Ajax.Responders.responders;for(var i=0;i<responders.length;i++){if(responders[i].onException){listener=true;break;}}
60453 if(listener){OpenLayers.Ajax.Responders.dispatch('onException',this,exception);}else{throw exception;}}}});OpenLayers.Ajax.Request.Events=['Uninitialized','Loading','Loaded','Interactive','Complete'];OpenLayers.Ajax.Response=OpenLayers.Class({status:0,statusText:'',initialize:function(request){this.request=request;var transport=this.transport=request.transport,readyState=this.readyState=transport.readyState;if((readyState>2&&!(!!(window.attachEvent&&!window.opera)))||readyState==4){this.status=this.getStatus();this.statusText=this.getStatusText();this.responseText=transport.responseText==null?'':String(transport.responseText);}
60454 if(readyState==4){var xml=transport.responseXML;this.responseXML=xml===undefined?null:xml;}},getStatus:OpenLayers.Ajax.Request.prototype.getStatus,getStatusText:function(){try{return this.transport.statusText||'';}catch(e){return'';}},getHeader:OpenLayers.Ajax.Request.prototype.getHeader,getResponseHeader:function(name){return this.transport.getResponseHeader(name);}});OpenLayers.Ajax.getElementsByTagNameNS=function(parentnode,nsuri,nsprefix,tagname){var elem=null;if(parentnode.getElementsByTagNameNS){elem=parentnode.getElementsByTagNameNS(nsuri,tagname);}else{elem=parentnode.getElementsByTagName(nsprefix+':'+tagname);}
60455 return elem;};OpenLayers.Ajax.serializeXMLToString=function(xmldom){var serializer=new XMLSerializer();var data=serializer.serializeToString(xmldom);return data;};OpenLayers.Control.DragFeature=OpenLayers.Class(OpenLayers.Control,{geometryTypes:null,onStart:function(feature,pixel){},onDrag:function(feature,pixel){},onComplete:function(feature,pixel){},documentDrag:false,layer:null,feature:null,dragCallbacks:{},featureCallbacks:{},lastPixel:null,initialize:function(layer,options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.layer=layer;this.handlers={drag:new OpenLayers.Handler.Drag(this,OpenLayers.Util.extend({down:this.downFeature,move:this.moveFeature,up:this.upFeature,out:this.cancel,done:this.doneDragging},this.dragCallbacks),{documentDrag:this.documentDrag}),feature:new OpenLayers.Handler.Feature(this,this.layer,OpenLayers.Util.extend({over:this.overFeature,out:this.outFeature},this.featureCallbacks),{geometryTypes:this.geometryTypes})};},destroy:function(){this.layer=null;OpenLayers.Control.prototype.destroy.apply(this,[]);},activate:function(){return(this.handlers.feature.activate()&&OpenLayers.Control.prototype.activate.apply(this,arguments));},deactivate:function(){this.handlers.drag.deactivate();this.handlers.feature.deactivate();this.feature=null;this.dragging=false;this.lastPixel=null;OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass+"Over");return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},overFeature:function(feature){if(!this.handlers.drag.dragging){this.feature=feature;this.handlers.drag.activate();this.over=true;OpenLayers.Element.addClass(this.map.viewPortDiv,this.displayClass+"Over");}else{if(this.feature.id==feature.id){this.over=true;}else{this.over=false;}}},downFeature:function(pixel){this.lastPixel=pixel;this.onStart(this.feature,pixel);},moveFeature:function(pixel){var res=this.map.getResolution();this.feature.geometry.move(res*(pixel.x-this.lastPixel.x),res*(this.lastPixel.y-pixel.y));this.layer.drawFeature(this.feature);this.lastPixel=pixel;this.onDrag(this.feature,pixel);},upFeature:function(pixel){if(!this.over){this.handlers.drag.deactivate();}},doneDragging:function(pixel){this.onComplete(this.feature,pixel);},outFeature:function(feature){if(!this.handlers.drag.dragging){this.over=false;this.handlers.drag.deactivate();OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass+"Over");this.feature=null;}else{if(this.feature.id==feature.id){this.over=false;}}},cancel:function(){this.handlers.drag.deactivate();this.over=false;},setMap:function(map){this.handlers.drag.setMap(map);this.handlers.feature.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.DragFeature"});OpenLayers.Control.DragPan=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOOL,panned:false,interval:25,documentDrag:false,draw:function(){this.handler=new OpenLayers.Handler.Drag(this,{"move":this.panMap,"done":this.panMapDone},{interval:this.interval,documentDrag:this.documentDrag});},panMap:function(xy){this.panned=true;this.map.pan(this.handler.last.x-xy.x,this.handler.last.y-xy.y,{dragging:this.handler.dragging,animate:false});},panMapDone:function(xy){if(this.panned){this.panMap(xy);this.panned=false;}},CLASS_NAME:"OpenLayers.Control.DragPan"});OpenLayers.Control.KeyboardDefaults=OpenLayers.Class(OpenLayers.Control,{autoActivate:true,slideFactor:75,initialize:function(){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){if(this.handler){this.handler.destroy();}
60456 this.handler=null;OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){this.handler=new OpenLayers.Handler.Keyboard(this,{"keydown":this.defaultKeyPress});},defaultKeyPress:function(evt){switch(evt.keyCode){case OpenLayers.Event.KEY_LEFT:this.map.pan(-this.slideFactor,0);break;case OpenLayers.Event.KEY_RIGHT:this.map.pan(this.slideFactor,0);break;case OpenLayers.Event.KEY_UP:this.map.pan(0,-this.slideFactor);break;case OpenLayers.Event.KEY_DOWN:this.map.pan(0,this.slideFactor);break;case 33:var size=this.map.getSize();this.map.pan(0,-0.75*size.h);break;case 34:var size=this.map.getSize();this.map.pan(0,0.75*size.h);break;case 35:var size=this.map.getSize();this.map.pan(0.75*size.w,0);break;case 36:var size=this.map.getSize();this.map.pan(-0.75*size.w,0);break;case 43:case 61:case 187:case 107:this.map.zoomIn();break;case 45:case 109:case 189:case 95:this.map.zoomOut();break;}},CLASS_NAME:"OpenLayers.Control.KeyboardDefaults"});OpenLayers.Control.WMSGetFeatureInfo=OpenLayers.Class(OpenLayers.Control,{hover:false,drillDown:false,maxFeatures:10,clickCallback:"click",layers:null,queryVisible:false,url:null,layerUrls:null,infoFormat:'text/html',vendorParams:{},format:null,formatOptions:null,handlerOptions:null,handler:null,hoverRequest:null,EVENT_TYPES:["beforegetfeatureinfo","nogetfeatureinfo","getfeatureinfo"],initialize:function(options){this.EVENT_TYPES=OpenLayers.Control.WMSGetFeatureInfo.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);options=options||{};options.handlerOptions=options.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[options]);if(!this.format){this.format=new OpenLayers.Format.WMSGetFeatureInfo(options.formatOptions);}
60457 if(this.drillDown===true){this.hover=false;}
60458 if(this.hover){this.handler=new OpenLayers.Handler.Hover(this,{'move':this.cancelHover,'pause':this.getInfoForHover},OpenLayers.Util.extend(this.handlerOptions.hover||{},{'delay':250}));}else{var callbacks={};callbacks[this.clickCallback]=this.getInfoForClick;this.handler=new OpenLayers.Handler.Click(this,callbacks,this.handlerOptions.click||{});}},activate:function(){if(!this.active){this.handler.activate();}
60459 return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},getInfoForClick:function(evt){this.events.triggerEvent("beforegetfeatureinfo",{xy:evt.xy});OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");this.request(evt.xy,{});},getInfoForHover:function(evt){this.events.triggerEvent("beforegetfeatureinfo",{xy:evt.xy});this.request(evt.xy,{hover:true});},cancelHover:function(){if(this.hoverRequest){this.hoverRequest.abort();this.hoverRequest=null;}},findLayers:function(){var candidates=this.layers||this.map.layers;var layers=[];var layer,url;for(var i=0,len=candidates.length;i<len;++i){layer=candidates[i];if(layer instanceof OpenLayers.Layer.WMS&&(!this.queryVisible||layer.getVisibility())){url=layer.url instanceof Array?layer.url[0]:layer.url;if(this.drillDown===false&&!this.url){this.url=url;}
60460 if(this.drillDown===true||this.urlMatches(url)){layers.push(layer);}}}
60461 return layers;},urlMatches:function(url){var matches=OpenLayers.Util.isEquivalentUrl(this.url,url);if(!matches&&this.layerUrls){for(var i=0,len=this.layerUrls.length;i<len;++i){if(OpenLayers.Util.isEquivalentUrl(this.layerUrls[i],url)){matches=true;break;}}}
60462 return matches;},buildWMSOptions:function(url,layers,clickPosition,format){var layerNames=[],styleNames=[];for(var i=0,len=layers.length;i<len;i++){layerNames=layerNames.concat(layers[i].params.LAYERS);styleNames=styleNames.concat(this.getStyleNames(layers[i]));}
60463 var params=OpenLayers.Util.extend({service:"WMS",version:layers[0].params.VERSION,request:"GetFeatureInfo",layers:layerNames,query_layers:layerNames,styles:styleNames,bbox:this.map.getExtent().toBBOX(null,layers[0].reverseAxisOrder()),feature_count:this.maxFeatures,height:this.map.getSize().h,width:this.map.getSize().w,format:format,info_format:this.infoFormat},(parseFloat(layers[0].params.VERSION)>=1.3)?{crs:this.map.getProjection(),i:clickPosition.x,j:clickPosition.y}:{srs:this.map.getProjection(),x:clickPosition.x,y:clickPosition.y});OpenLayers.Util.applyDefaults(params,this.vendorParams);return{url:url,params:OpenLayers.Util.upperCaseObject(params),callback:function(request){this.handleResponse(clickPosition,request);},scope:this};},getStyleNames:function(layer){var styleNames;if(layer.params.STYLES){styleNames=layer.params.STYLES;}else{if(layer.params.LAYERS instanceof Array){styleNames=new Array(layer.params.LAYERS.length);}else{styleNames=layer.params.LAYERS.replace(/[^,]/g,"");}}
60464 return styleNames;},request:function(clickPosition,options){var layers=this.findLayers();if(layers.length==0){this.events.triggerEvent("nogetfeatureinfo");OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");return;}
60465 options=options||{};if(this.drillDown===false){var wmsOptions=this.buildWMSOptions(this.url,layers,clickPosition,layers[0].params.FORMAT);var request=OpenLayers.Request.GET(wmsOptions);if(options.hover===true){this.hoverRequest=request;}}else{this._requestCount=0;this._numRequests=0;this.features=[];var services={},url;for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];var service,found=false;url=layer.url instanceof Array?layer.url[0]:layer.url;if(url in services){services[url].push(layer);}else{this._numRequests++;services[url]=[layer];}}
60466 var layers;for(var url in services){layers=services[url];var wmsOptions=this.buildWMSOptions(url,layers,clickPosition,layers[0].params.FORMAT);OpenLayers.Request.GET(wmsOptions);}}},triggerGetFeatureInfo:function(request,xy,features){this.events.triggerEvent("getfeatureinfo",{text:request.responseText,features:features,request:request,xy:xy});OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");},handleResponse:function(xy,request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
60467 var features=this.format.read(doc);if(this.drillDown===false){this.triggerGetFeatureInfo(request,xy,features);}else{this._requestCount++;this._features=(this._features||[]).concat(features);if(this._requestCount===this._numRequests){this.triggerGetFeatureInfo(request,xy,this._features.concat());delete this._features;delete this._requestCount;delete this._numRequests;}}},CLASS_NAME:"OpenLayers.Control.WMSGetFeatureInfo"});OpenLayers.Control.WMTSGetFeatureInfo=OpenLayers.Class(OpenLayers.Control,{hover:false,requestEncoding:"KVP",drillDown:false,maxFeatures:10,clickCallback:"click",layers:null,queryVisible:true,infoFormat:'text/html',vendorParams:{},format:null,formatOptions:null,handlerOptions:null,handler:null,hoverRequest:null,EVENT_TYPES:["beforegetfeatureinfo","getfeatureinfo","exception"],pending:0,initialize:function(options){this.EVENT_TYPES=OpenLayers.Control.WMTSGetFeatureInfo.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);options=options||{};options.handlerOptions=options.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[options]);if(!this.format){this.format=new OpenLayers.Format.WMSGetFeatureInfo(options.formatOptions);}
60468 if(this.drillDown===true){this.hover=false;}
60469 if(this.hover){this.handler=new OpenLayers.Handler.Hover(this,{move:this.cancelHover,pause:this.getInfoForHover},OpenLayers.Util.extend(this.handlerOptions.hover||{},{delay:250}));}else{var callbacks={};callbacks[this.clickCallback]=this.getInfoForClick;this.handler=new OpenLayers.Handler.Click(this,callbacks,this.handlerOptions.click||{});}},activate:function(){if(!this.active){this.handler.activate();}
60470 return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},getInfoForClick:function(evt){this.request(evt.xy,{});},getInfoForHover:function(evt){this.request(evt.xy,{hover:true});},cancelHover:function(){if(this.hoverRequest){--this.pending;if(this.pending<=0){OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");this.pending=0;}
60471 this.hoverRequest.abort();this.hoverRequest=null;}},findLayers:function(){var candidates=this.layers||this.map.layers;var layers=[];var layer;for(var i=candidates.length-1;i>=0;--i){layer=candidates[i];if(layer instanceof OpenLayers.Layer.WMTS&&layer.requestEncoding===this.requestEncoding&&(!this.queryVisible||layer.getVisibility())){layers.push(layer);if(!this.drillDown||this.hover){break;}}}
60472 return layers;},buildRequestOptions:function(layer,xy){var loc=this.map.getLonLatFromPixel(xy);var getTileUrl=layer.getURL(new OpenLayers.Bounds(loc.lon,loc.lat,loc.lon,loc.lat));var params=OpenLayers.Util.getParameters(getTileUrl);var tileInfo=layer.getTileInfo(loc);OpenLayers.Util.extend(params,{service:"WMTS",version:layer.version,request:"GetFeatureInfo",infoFormat:this.infoFormat,i:tileInfo.i,j:tileInfo.j});OpenLayers.Util.applyDefaults(params,this.vendorParams);return{url:layer.url instanceof Array?layer.url[0]:layer.url,params:OpenLayers.Util.upperCaseObject(params),callback:function(request){this.handleResponse(xy,request,layer);},scope:this};},request:function(xy,options){options=options||{};var layers=this.findLayers();if(layers.length>0){var issue,layer;for(var i=0,len=layers.length;i<len;i++){layer=layers[i];issue=this.events.triggerEvent("beforegetfeatureinfo",{xy:xy,layer:layer});if(issue!==false){++this.pending;var requestOptions=this.buildRequestOptions(layer,xy);var request=OpenLayers.Request.GET(requestOptions);if(options.hover===true){this.hoverRequest=request;}}}
60473 if(this.pending>0){OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");}}},handleResponse:function(xy,request,layer){--this.pending;if(this.pending<=0){OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");this.pending=0;}
60474 if(request.status&&(request.status<200||request.status>=300)){this.events.triggerEvent("exception",{xy:xy,request:request,layer:layer});}else{var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
60475 var features,except;try{features=this.format.read(doc);}catch(error){except=true;this.events.triggerEvent("exception",{xy:xy,request:request,error:error,layer:layer});}
60476 if(!except){this.events.triggerEvent("getfeatureinfo",{text:request.responseText,features:features,request:request,xy:xy,layer:layer});}}},setMap:function(map){this.handler.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.WMTSGetFeatureInfo"});OpenLayers.State={UNKNOWN:'Unknown',INSERT:'Insert',UPDATE:'Update',DELETE:'Delete'};OpenLayers.Feature.Vector=OpenLayers.Class(OpenLayers.Feature,{fid:null,geometry:null,attributes:null,bounds:null,state:null,style:null,url:null,renderIntent:"default",initialize:function(geometry,attributes,style){OpenLayers.Feature.prototype.initialize.apply(this,[null,null,attributes]);this.lonlat=null;this.geometry=geometry?geometry:null;this.state=null;this.attributes={};if(attributes){this.attributes=OpenLayers.Util.extend(this.attributes,attributes);}
60477 this.style=style?style:null;},destroy:function(){if(this.layer){this.layer.removeFeatures(this);this.layer=null;}
60478 this.geometry=null;OpenLayers.Feature.prototype.destroy.apply(this,arguments);},clone:function(){return new OpenLayers.Feature.Vector(this.geometry?this.geometry.clone():null,this.attributes,this.style);},onScreen:function(boundsOnly){var onScreen=false;if(this.layer&&this.layer.map){var screenBounds=this.layer.map.getExtent();if(boundsOnly){var featureBounds=this.geometry.getBounds();onScreen=screenBounds.intersectsBounds(featureBounds);}else{var screenPoly=screenBounds.toGeometry();onScreen=screenPoly.intersects(this.geometry);}}
60479 return onScreen;},getVisibility:function(){return!(this.style&&this.style.display=='none'||!this.layer||this.layer&&this.layer.styleMap&&this.layer.styleMap.createSymbolizer(this,this.renderIntent).display=='none'||this.layer&&!this.layer.getVisibility());},createMarker:function(){return null;},destroyMarker:function(){},createPopup:function(){return null;},atPoint:function(lonlat,toleranceLon,toleranceLat){var atPoint=false;if(this.geometry){atPoint=this.geometry.atPoint(lonlat,toleranceLon,toleranceLat);}
60480 return atPoint;},destroyPopup:function(){},move:function(location){if(!this.layer||!this.geometry.move){return;}
60481 var pixel;if(location.CLASS_NAME=="OpenLayers.LonLat"){pixel=this.layer.getViewPortPxFromLonLat(location);}else{pixel=location;}
60482 var lastPixel=this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());var res=this.layer.map.getResolution();this.geometry.move(res*(pixel.x-lastPixel.x),res*(lastPixel.y-pixel.y));this.layer.drawFeature(this);return lastPixel;},toState:function(state){if(state==OpenLayers.State.UPDATE){switch(this.state){case OpenLayers.State.UNKNOWN:case OpenLayers.State.DELETE:this.state=state;break;case OpenLayers.State.UPDATE:case OpenLayers.State.INSERT:break;}}else if(state==OpenLayers.State.INSERT){switch(this.state){case OpenLayers.State.UNKNOWN:break;default:this.state=state;break;}}else if(state==OpenLayers.State.DELETE){switch(this.state){case OpenLayers.State.INSERT:break;case OpenLayers.State.DELETE:break;case OpenLayers.State.UNKNOWN:case OpenLayers.State.UPDATE:this.state=state;break;}}else if(state==OpenLayers.State.UNKNOWN){this.state=state;}},CLASS_NAME:"OpenLayers.Feature.Vector"});OpenLayers.Feature.Vector.style={'default':{fillColor:"#ee9900",fillOpacity:0.4,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"#ee9900",strokeOpacity:1,strokeWidth:1,strokeLinecap:"round",strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"inherit"},'select':{fillColor:"blue",fillOpacity:0.4,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"blue",strokeOpacity:1,strokeWidth:2,strokeLinecap:"round",strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"pointer"},'temporary':{fillColor:"#66cccc",fillOpacity:0.2,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"#66cccc",strokeOpacity:1,strokeLinecap:"round",strokeWidth:2,strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"inherit"},'delete':{display:"none"}};OpenLayers.Feature.WFS=OpenLayers.Class(OpenLayers.Feature,{initialize:function(layer,xmlNode){var newArguments=arguments;var data=this.processXMLNode(xmlNode);newArguments=new Array(layer,data.lonlat,data);OpenLayers.Feature.prototype.initialize.apply(this,newArguments);this.createMarker();this.layer.addMarker(this.marker);},destroy:function(){if(this.marker!=null){this.layer.removeMarker(this.marker);}
60483 OpenLayers.Feature.prototype.destroy.apply(this,arguments);},processXMLNode:function(xmlNode){var point=OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,"http://www.opengis.net/gml","gml","Point");var text=OpenLayers.Util.getXmlNodeValue(OpenLayers.Ajax.getElementsByTagNameNS(point[0],"http://www.opengis.net/gml","gml","coordinates")[0]);var floats=text.split(",");return{lonlat:new OpenLayers.LonLat(parseFloat(floats[0]),parseFloat(floats[1])),id:null};},CLASS_NAME:"OpenLayers.Feature.WFS"});OpenLayers.Format.OWSCommon.v1_0_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1,{namespaces:{ows:"http://www.opengis.net/ows/1.0",xlink:"http://www.w3.org/1999/xlink"},readers:{"ows":OpenLayers.Format.OWSCommon.v1.prototype.readers["ows"]},writers:{"ows":OpenLayers.Format.OWSCommon.v1.prototype.writers["ows"]},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1_1_0"});OpenLayers.Format.OWSCommon.v1_1_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1,{namespaces:{ows:"http://www.opengis.net/ows/1.1",xlink:"http://www.w3.org/1999/xlink"},readers:{"ows":OpenLayers.Util.applyDefaults({"AllowedValues":function(node,parameter){parameter.allowedValues={};this.readChildNodes(node,parameter.allowedValues);},"AnyValue":function(node,parameter){parameter.anyValue=true;},"Range":function(node,allowedValues){allowedValues.range={};this.readChildNodes(node,allowedValues.range);},"MinimumValue":function(node,range){range.minValue=this.getChildValue(node);},"MaximumValue":function(node,range){range.maxValue=this.getChildValue(node);},"Identifier":function(node,obj){obj.identifier=this.getChildValue(node);},"SupportedCRS":function(node,obj){obj.supportedCRS=this.getChildValue(node);}},OpenLayers.Format.OWSCommon.v1.prototype.readers["ows"])},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1_1_0"});OpenLayers.Format.OWSContext=OpenLayers.Class(OpenLayers.Format.Context,{defaultVersion:"0.3.1",getParser:function(version){var v=version||this.version||this.defaultVersion;if(v==="0.3.0"){v=this.defaultVersion;}
60484 if(!this.parser||this.parser.VERSION!=v){var format=OpenLayers.Format.OWSContext["v"+v.replace(/\./g,"_")];if(!format){throw"Can't find a OWSContext parser for version "+v;}
60485 this.parser=new format(this.options);}
60486 return this.parser;},toContext:function(obj){var context={};if(obj.CLASS_NAME=="OpenLayers.Map"){context.bounds=obj.getExtent();context.maxExtent=obj.maxExtent;context.projection=obj.projection;context.size=obj.getSize();context.layers=obj.layers;}
60487 return context;},CLASS_NAME:"OpenLayers.Format.OWSContext"});OpenLayers.Format.WFSCapabilities.v1=OpenLayers.Class(OpenLayers.Format.WFSCapabilities,{initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60488 var capabilities={};var root=data.documentElement;this.runChildNodes(capabilities,root);return capabilities;},runChildNodes:function(obj,node){var children=node.childNodes;var childNode,processor;for(var i=0;i<children.length;++i){childNode=children[i];if(childNode.nodeType==1){processor=this["read_cap_"+childNode.nodeName];if(processor){processor.apply(this,[obj,childNode]);}}}},read_cap_FeatureTypeList:function(request,node){var featureTypeList={featureTypes:[]};this.runChildNodes(featureTypeList,node);request.featureTypeList=featureTypeList;},read_cap_FeatureType:function(featureTypeList,node,parentLayer){var featureType={};this.runChildNodes(featureType,node);featureTypeList.featureTypes.push(featureType);},read_cap_Name:function(obj,node){var name=this.getChildValue(node);if(name){var parts=name.split(":");obj.name=parts.pop();if(parts.length>0){obj.featureNS=this.lookupNamespaceURI(node,parts[0]);}}},read_cap_Title:function(obj,node){var title=this.getChildValue(node);if(title){obj.title=title;}},read_cap_Abstract:function(obj,node){var abst=this.getChildValue(node);if(abst){obj["abstract"]=abst;}},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1"});OpenLayers.Format.WMC=OpenLayers.Class(OpenLayers.Format.Context,{defaultVersion:"1.1.0",getParser:function(version){var v=version||this.version||this.defaultVersion;if(!this.parser||this.parser.VERSION!=v){var format=OpenLayers.Format.WMC["v"+v.replace(/\./g,"_")];if(!format){throw"Can't find a WMC parser for version "+v;}
60489 this.parser=new format(this.options);}
60490 return this.parser;},layerToContext:function(layer){var parser=this.getParser();var layerContext={queryable:layer.queryable,visibility:layer.visibility,name:layer.params["LAYERS"],title:layer.name,metadataURL:layer.metadataURL,version:layer.params["VERSION"],url:layer.url,maxExtent:layer.maxExtent,transparent:layer.params["TRANSPARENT"],numZoomLevels:layer.numZoomLevels,units:layer.units,isBaseLayer:layer.isBaseLayer,opacity:layer.opacity,displayInLayerSwitcher:layer.displayInLayerSwitcher,singleTile:layer.singleTile,tileSize:(layer.singleTile||!layer.tileSize)?undefined:{width:layer.tileSize.w,height:layer.tileSize.h},minScale:(layer.options.resolutions||layer.options.scales||layer.options.maxResolution||layer.options.minScale)?layer.minScale:undefined,maxScale:(layer.options.resolutions||layer.options.scales||layer.options.minResolution||layer.options.maxScale)?layer.maxScale:undefined,formats:[{value:layer.params["FORMAT"],current:true}],styles:[{href:layer.params["SLD"],body:layer.params["SLD_BODY"],name:layer.params["STYLES"]||parser.defaultStyleName,title:parser.defaultStyleTitle,current:true}]};return layerContext;},toContext:function(obj){var context={};var layers=obj.layers;if(obj.CLASS_NAME=="OpenLayers.Map"){context.bounds=obj.getExtent();context.maxExtent=obj.maxExtent;context.projection=obj.projection;context.size=obj.getSize();}
60491 else{OpenLayers.Util.applyDefaults(context,obj);if(context.layers!=undefined){delete(context.layers);}}
60492 if(context.layersContext==undefined){context.layersContext=[];}
60493 if(layers!=undefined&&layers instanceof Array){for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];if(layer instanceof OpenLayers.Layer.WMS){context.layersContext.push(this.layerToContext(layer));}}}
60494 return context;},CLASS_NAME:"OpenLayers.Format.WMC"});OpenLayers.Format.WMSCapabilities.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{wms:"http://www.opengis.net/wms",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"wms",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60495 if(data&&data.nodeType==9){data=data.documentElement;}
60496 var capabilities={};this.readNode(data,capabilities);this.postProcessLayers(capabilities);return capabilities;},postProcessLayers:function(capabilities){if(capabilities.capability){capabilities.capability.layers=[];var layers=capabilities.capability.nestedLayers;for(var i=0,len=layers.length;i<len;++i){var layer=layers[i];this.processLayer(capabilities.capability,layer);}}},processLayer:function(capability,layer,parentLayer){if(layer.formats===undefined){layer.formats=capability.request.getmap.formats;}
60497 if(parentLayer){layer.styles=layer.styles.concat(parentLayer.styles);var attributes=["queryable","cascaded","fixedWidth","fixedHeight","opaque","noSubsets","llbbox","minScale","maxScale","attribution"];var complexAttr=["srs","bbox","dimensions","authorityURLs"];var key;for(var j=0;j<attributes.length;j++){key=attributes[j];if(key in parentLayer){if(layer[key]==null){layer[key]=parentLayer[key];}
60498 if(layer[key]==null){var intAttr=["cascaded","fixedWidth","fixedHeight"];var boolAttr=["queryable","opaque","noSubsets"];if(OpenLayers.Util.indexOf(intAttr,key)!=-1){layer[key]=0;}
60499 if(OpenLayers.Util.indexOf(boolAttr,key)!=-1){layer[key]=false;}}}}
60500 for(var j=0;j<complexAttr.length;j++){key=complexAttr[j];layer[key]=OpenLayers.Util.extend(layer[key],parentLayer[key]);}}
60501 for(var i=0,len=layer.nestedLayers.length;i<len;i++){var childLayer=layer.nestedLayers[i];this.processLayer(capability,childLayer,layer);}
60502 if(layer.name){capability.layers.push(layer);}},readers:{"wms":{"Service":function(node,obj){obj.service={};this.readChildNodes(node,obj.service);},"Name":function(node,obj){obj.name=this.getChildValue(node);},"Title":function(node,obj){obj.title=this.getChildValue(node);},"Abstract":function(node,obj){obj["abstract"]=this.getChildValue(node);},"BoundingBox":function(node,obj){var bbox={};bbox.bbox=[parseFloat(node.getAttribute("minx")),parseFloat(node.getAttribute("miny")),parseFloat(node.getAttribute("maxx")),parseFloat(node.getAttribute("maxy"))];var res={x:parseFloat(node.getAttribute("resx")),y:parseFloat(node.getAttribute("resy"))};if(!(isNaN(res.x)&&isNaN(res.y))){bbox.res=res;}
60503 return bbox;},"OnlineResource":function(node,obj){obj.href=this.getAttributeNS(node,this.namespaces.xlink,"href");},"ContactInformation":function(node,obj){obj.contactInformation={};this.readChildNodes(node,obj.contactInformation);},"ContactPersonPrimary":function(node,obj){obj.personPrimary={};this.readChildNodes(node,obj.personPrimary);},"ContactPerson":function(node,obj){obj.person=this.getChildValue(node);},"ContactOrganization":function(node,obj){obj.organization=this.getChildValue(node);},"ContactPosition":function(node,obj){obj.position=this.getChildValue(node);},"ContactAddress":function(node,obj){obj.contactAddress={};this.readChildNodes(node,obj.contactAddress);},"AddressType":function(node,obj){obj.type=this.getChildValue(node);},"Address":function(node,obj){obj.address=this.getChildValue(node);},"City":function(node,obj){obj.city=this.getChildValue(node);},"StateOrProvince":function(node,obj){obj.stateOrProvince=this.getChildValue(node);},"PostCode":function(node,obj){obj.postcode=this.getChildValue(node);},"Country":function(node,obj){obj.country=this.getChildValue(node);},"ContactVoiceTelephone":function(node,obj){obj.phone=this.getChildValue(node);},"ContactFacsimileTelephone":function(node,obj){obj.fax=this.getChildValue(node);},"ContactElectronicMailAddress":function(node,obj){obj.email=this.getChildValue(node);},"Fees":function(node,obj){var fees=this.getChildValue(node);if(fees&&fees.toLowerCase()!="none"){obj.fees=fees;}},"AccessConstraints":function(node,obj){var constraints=this.getChildValue(node);if(constraints&&constraints.toLowerCase()!="none"){obj.accessConstraints=constraints;}},"Capability":function(node,obj){obj.capability={nestedLayers:[]};this.readChildNodes(node,obj.capability);},"Request":function(node,obj){obj.request={};this.readChildNodes(node,obj.request);},"GetCapabilities":function(node,obj){obj.getcapabilities={formats:[]};this.readChildNodes(node,obj.getcapabilities);},"Format":function(node,obj){if(obj.formats instanceof Array){obj.formats.push(this.getChildValue(node));}else{obj.format=this.getChildValue(node);}},"DCPType":function(node,obj){this.readChildNodes(node,obj);},"HTTP":function(node,obj){this.readChildNodes(node,obj);},"Get":function(node,obj){this.readChildNodes(node,obj);},"Post":function(node,obj){this.readChildNodes(node,obj);},"GetMap":function(node,obj){obj.getmap={formats:[]};this.readChildNodes(node,obj.getmap);},"GetFeatureInfo":function(node,obj){obj.getfeatureinfo={formats:[]};this.readChildNodes(node,obj.getfeatureinfo);},"Exception":function(node,obj){obj.exception={formats:[]};this.readChildNodes(node,obj.exception);},"Layer":function(node,obj){var attrNode=node.getAttributeNode("queryable");var queryable=(attrNode&&attrNode.specified)?node.getAttribute("queryable"):null;attrNode=node.getAttributeNode("cascaded");var cascaded=(attrNode&&attrNode.specified)?node.getAttribute("cascaded"):null;attrNode=node.getAttributeNode("opaque");var opaque=(attrNode&&attrNode.specified)?node.getAttribute('opaque'):null;var noSubsets=node.getAttribute('noSubsets');var fixedWidth=node.getAttribute('fixedWidth');var fixedHeight=node.getAttribute('fixedHeight');var layer={nestedLayers:[],styles:[],srs:{},metadataURLs:[],bbox:{},dimensions:{},authorityURLs:{},identifiers:{},keywords:[],queryable:(queryable&&queryable!=="")?(queryable==="1"||queryable==="true"):null,cascaded:(cascaded!==null)?parseInt(cascaded):null,opaque:opaque?(opaque==="1"||opaque==="true"):null,noSubsets:(noSubsets!==null)?(noSubsets==="1"||noSubsets==="true"):null,fixedWidth:(fixedWidth!=null)?parseInt(fixedWidth):null,fixedHeight:(fixedHeight!=null)?parseInt(fixedHeight):null};obj.nestedLayers.push(layer);this.readChildNodes(node,layer);if(layer.name){var parts=layer.name.split(":");if(parts.length>0){layer.prefix=parts[0];}}},"Attribution":function(node,obj){obj.attribution={};this.readChildNodes(node,obj.attribution);},"LogoURL":function(node,obj){obj.logo={width:node.getAttribute("width"),height:node.getAttribute("height")};this.readChildNodes(node,obj.logo);},"Style":function(node,obj){var style={};obj.styles.push(style);this.readChildNodes(node,style);},"LegendURL":function(node,obj){var legend={width:node.getAttribute("width"),height:node.getAttribute("height")};obj.legend=legend;this.readChildNodes(node,legend);},"MetadataURL":function(node,obj){var metadataURL={type:node.getAttribute("type")};obj.metadataURLs.push(metadataURL);this.readChildNodes(node,metadataURL);},"DataURL":function(node,obj){obj.dataURL={};this.readChildNodes(node,obj.dataURL);},"FeatureListURL":function(node,obj){obj.featureListURL={};this.readChildNodes(node,obj.featureListURL);},"AuthorityURL":function(node,obj){var name=node.getAttribute("name");var authority={};this.readChildNodes(node,authority);obj.authorityURLs[name]=authority.href;},"Identifier":function(node,obj){var authority=node.getAttribute("authority");obj.identifiers[authority]=this.getChildValue(node);},"KeywordList":function(node,obj){this.readChildNodes(node,obj);},"SRS":function(node,obj){obj.srs[this.getChildValue(node)]=true;}}},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1"});OpenLayers.Format.WMSDescribeLayer.v1_1=OpenLayers.Class(OpenLayers.Format.WMSDescribeLayer,{initialize:function(options){OpenLayers.Format.WMSDescribeLayer.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60504 var root=data.documentElement;var children=root.childNodes;var describelayer=[];var childNode,nodeName;for(var i=0;i<children.length;++i){childNode=children[i];nodeName=childNode.nodeName;if(nodeName=='LayerDescription'){var layerName=childNode.getAttribute('name');var owsType='';var owsURL='';var typeName='';if(childNode.getAttribute('owsType')){owsType=childNode.getAttribute('owsType');owsURL=childNode.getAttribute('owsURL');}else{if(childNode.getAttribute('wfs')!=''){owsType='WFS';owsURL=childNode.getAttribute('wfs');}else if(childNode.getAttribute('wcs')!=''){owsType='WCS';owsURL=childNode.getAttribute('wcs');}}
60505 var query=childNode.getElementsByTagName('Query');if(query.length>0){typeName=query[0].getAttribute('typeName');if(!typeName){typeName=query[0].getAttribute('typename');}}
60506 describelayer.push({layerName:layerName,owsType:owsType,owsURL:owsURL,typeName:typeName});}}
60507 return describelayer;},CLASS_NAME:"OpenLayers.Format.WMSDescribeLayer.v1_1"});OpenLayers.Handler.Box=OpenLayers.Class(OpenLayers.Handler,{dragHandler:null,boxDivClassName:'olHandlerBoxZoomBox',boxCharacteristics:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);var callbacks={"down":this.startBox,"move":this.moveBox,"out":this.removeBox,"up":this.endBox};this.dragHandler=new OpenLayers.Handler.Drag(this,callbacks,{keyMask:this.keyMask});},destroy:function(){if(this.dragHandler){this.dragHandler.destroy();this.dragHandler=null;}
60508 OpenLayers.Handler.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Handler.prototype.setMap.apply(this,arguments);if(this.dragHandler){this.dragHandler.setMap(map);}},startBox:function(xy){this.zoomBox=OpenLayers.Util.createDiv('zoomBox',this.dragHandler.start);this.zoomBox.className=this.boxDivClassName;this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.viewPortDiv.appendChild(this.zoomBox);OpenLayers.Element.addClass(this.map.viewPortDiv,"olDrawBox");},moveBox:function(xy){var startX=this.dragHandler.start.x;var startY=this.dragHandler.start.y;var deltaX=Math.abs(startX-xy.x);var deltaY=Math.abs(startY-xy.y);this.zoomBox.style.width=Math.max(1,deltaX)+"px";this.zoomBox.style.height=Math.max(1,deltaY)+"px";this.zoomBox.style.left=xy.x<startX?xy.x+"px":startX+"px";this.zoomBox.style.top=xy.y<startY?xy.y+"px":startY+"px";var box=this.getBoxCharacteristics();if(box.newBoxModel){if(xy.x>startX){this.zoomBox.style.width=Math.max(1,deltaX-box.xOffset)+"px";}
60509 if(xy.y>startY){this.zoomBox.style.height=Math.max(1,deltaY-box.yOffset)+"px";}}},endBox:function(end){var result;if(Math.abs(this.dragHandler.start.x-end.x)>5||Math.abs(this.dragHandler.start.y-end.y)>5){var start=this.dragHandler.start;var top=Math.min(start.y,end.y);var bottom=Math.max(start.y,end.y);var left=Math.min(start.x,end.x);var right=Math.max(start.x,end.x);result=new OpenLayers.Bounds(left,bottom,right,top);}else{result=this.dragHandler.start.clone();}
60510 this.removeBox();this.callback("done",[result]);},removeBox:function(){this.map.viewPortDiv.removeChild(this.zoomBox);this.zoomBox=null;this.boxCharacteristics=null;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDrawBox");},activate:function(){if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.dragHandler.activate();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.dragHandler.deactivate();return true;}else{return false;}},getBoxCharacteristics:function(){if(!this.boxCharacteristics){var xOffset=parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-left-width"))+parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-right-width"))+1;var yOffset=parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-top-width"))+parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-bottom-width"))+1;var newBoxModel=OpenLayers.Util.getBrowserName()=="msie"?document.compatMode!="BackCompat":true;this.boxCharacteristics={xOffset:xOffset,yOffset:yOffset,newBoxModel:newBoxModel};}
60511 return this.boxCharacteristics;},CLASS_NAME:"OpenLayers.Handler.Box"});OpenLayers.Handler.RegularPolygon=OpenLayers.Class(OpenLayers.Handler.Drag,{sides:4,radius:null,snapAngle:null,snapToggle:'shiftKey',layerOptions:null,persist:false,irregular:false,angle:null,fixedRadius:false,feature:null,layer:null,origin:null,initialize:function(control,callbacks,options){if(!(options&&options.layerOptions&&options.layerOptions.styleMap)){this.style=OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'],{});}
60512 OpenLayers.Handler.prototype.initialize.apply(this,[control,callbacks,options]);this.options=(options)?options:{};},setOptions:function(newOptions){OpenLayers.Util.extend(this.options,newOptions);OpenLayers.Util.extend(this,newOptions);},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){var options=OpenLayers.Util.extend({displayInLayerSwitcher:false,calculateInRange:OpenLayers.Function.True},this.layerOptions);this.layer=new OpenLayers.Layer.Vector(this.CLASS_NAME,options);this.map.addLayer(this.layer);activated=true;}
60513 return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.Drag.prototype.deactivate.apply(this,arguments)){if(this.dragging){this.cancel();}
60514 if(this.layer.map!=null){this.layer.destroy(false);if(this.feature){this.feature.destroy();}}
60515 this.layer=null;this.feature=null;deactivated=true;}
60516 return deactivated;},down:function(evt){this.fixedRadius=!!(this.radius);var maploc=this.map.getLonLatFromPixel(evt.xy);this.origin=new OpenLayers.Geometry.Point(maploc.lon,maploc.lat);if(!this.fixedRadius||this.irregular){this.radius=this.map.getResolution();}
60517 if(this.persist){this.clear();}
60518 this.feature=new OpenLayers.Feature.Vector();this.createGeometry();this.callback("create",[this.origin,this.feature]);this.layer.addFeatures([this.feature],{silent:true});this.layer.drawFeature(this.feature,this.style);},move:function(evt){var maploc=this.map.getLonLatFromPixel(evt.xy);var point=new OpenLayers.Geometry.Point(maploc.lon,maploc.lat);if(this.irregular){var ry=Math.sqrt(2)*Math.abs(point.y-this.origin.y)/2;this.radius=Math.max(this.map.getResolution()/2,ry);}else if(this.fixedRadius){this.origin=point;}else{this.calculateAngle(point,evt);this.radius=Math.max(this.map.getResolution()/2,point.distanceTo(this.origin));}
60519 this.modifyGeometry();if(this.irregular){var dx=point.x-this.origin.x;var dy=point.y-this.origin.y;var ratio;if(dy==0){ratio=dx/(this.radius*Math.sqrt(2));}else{ratio=dx/dy;}
60520 this.feature.geometry.resize(1,this.origin,ratio);this.feature.geometry.move(dx/2,dy/2);}
60521 this.layer.drawFeature(this.feature,this.style);},up:function(evt){this.finalize();if(this.start==this.last){this.callback("done",[evt.xy]);}},out:function(evt){this.finalize();},createGeometry:function(){this.angle=Math.PI*((1/this.sides)-(1/2));if(this.snapAngle){this.angle+=this.snapAngle*(Math.PI/180);}
60522 this.feature.geometry=OpenLayers.Geometry.Polygon.createRegularPolygon(this.origin,this.radius,this.sides,this.snapAngle);},modifyGeometry:function(){var angle,point;var ring=this.feature.geometry.components[0];if(ring.components.length!=(this.sides+1)){this.createGeometry();ring=this.feature.geometry.components[0];}
60523 for(var i=0;i<this.sides;++i){point=ring.components[i];angle=this.angle+(i*2*Math.PI/this.sides);point.x=this.origin.x+(this.radius*Math.cos(angle));point.y=this.origin.y+(this.radius*Math.sin(angle));point.clearBounds();}},calculateAngle:function(point,evt){var alpha=Math.atan2(point.y-this.origin.y,point.x-this.origin.x);if(this.snapAngle&&(this.snapToggle&&!evt[this.snapToggle])){var snapAngleRad=(Math.PI/180)*this.snapAngle;this.angle=Math.round(alpha/snapAngleRad)*snapAngleRad;}else{this.angle=alpha;}},cancel:function(){this.callback("cancel",null);this.finalize();},finalize:function(){this.origin=null;this.radius=this.options.radius;},clear:function(){if(this.layer){this.layer.renderer.clear();this.layer.destroyFeatures();}},callback:function(name,args){if(this.callbacks[name]){this.callbacks[name].apply(this.control,[this.feature.geometry.clone()]);}
60524 if(!this.persist&&(name=="done"||name=="cancel")){this.clear();}},CLASS_NAME:"OpenLayers.Handler.RegularPolygon"});OpenLayers.Layer.EventPane=OpenLayers.Class(OpenLayers.Layer,{smoothDragPan:true,isBaseLayer:true,isFixed:true,pane:null,mapObject:null,initialize:function(name,options){OpenLayers.Layer.prototype.initialize.apply(this,arguments);if(this.pane==null){this.pane=OpenLayers.Util.createDiv(this.div.id+"_EventPane");}},destroy:function(){this.mapObject=null;this.pane=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Layer.prototype.setMap.apply(this,arguments);this.pane.style.zIndex=parseInt(this.div.style.zIndex)+1;this.pane.style.display=this.div.style.display;this.pane.style.width="100%";this.pane.style.height="100%";if(OpenLayers.Util.getBrowserName()=="msie"){this.pane.style.background="url("+OpenLayers.Util.getImagesLocation()+"blank.gif)";}
60525 if(this.isFixed){this.map.viewPortDiv.appendChild(this.pane);}else{this.map.layerContainerDiv.appendChild(this.pane);}
60526 this.loadMapObject();if(this.mapObject==null){this.loadWarningMessage();}},removeMap:function(map){if(this.pane&&this.pane.parentNode){this.pane.parentNode.removeChild(this.pane);}
60527 OpenLayers.Layer.prototype.removeMap.apply(this,arguments);},loadWarningMessage:function(){this.div.style.backgroundColor="darkblue";var viewSize=this.map.getSize();var msgW=Math.min(viewSize.w,300);var msgH=Math.min(viewSize.h,200);var size=new OpenLayers.Size(msgW,msgH);var centerPx=new OpenLayers.Pixel(viewSize.w/2,viewSize.h/2);var topLeft=centerPx.add(-size.w/2,-size.h/2);var div=OpenLayers.Util.createDiv(this.name+"_warning",topLeft,size,null,null,null,"auto");div.style.padding="7px";div.style.backgroundColor="yellow";div.innerHTML=this.getWarningHTML();this.div.appendChild(div);},getWarningHTML:function(){return"";},display:function(display){OpenLayers.Layer.prototype.display.apply(this,arguments);this.pane.style.display=this.div.style.display;},setZIndex:function(zIndex){OpenLayers.Layer.prototype.setZIndex.apply(this,arguments);this.pane.style.zIndex=parseInt(this.div.style.zIndex)+1;},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);if(this.mapObject!=null){var newCenter=this.map.getCenter();var newZoom=this.map.getZoom();if(newCenter!=null){var moOldCenter=this.getMapObjectCenter();var oldCenter=this.getOLLonLatFromMapObjectLonLat(moOldCenter);var moOldZoom=this.getMapObjectZoom();var oldZoom=this.getOLZoomFromMapObjectZoom(moOldZoom);if(!(newCenter.equals(oldCenter))||!(newZoom==oldZoom)){if(dragging&&this.dragPanMapObject&&this.smoothDragPan){var oldPx=this.map.getViewPortPxFromLonLat(oldCenter);var newPx=this.map.getViewPortPxFromLonLat(newCenter);this.dragPanMapObject(newPx.x-oldPx.x,oldPx.y-newPx.y);}else{var center=this.getMapObjectLonLatFromOLLonLat(newCenter);var zoom=this.getMapObjectZoomFromOLZoom(newZoom);this.setMapObjectCenter(center,zoom,dragging);}}}}},getLonLatFromViewPortPx:function(viewPortPx){var lonlat=null;if((this.mapObject!=null)&&(this.getMapObjectCenter()!=null)){var moPixel=this.getMapObjectPixelFromOLPixel(viewPortPx);var moLonLat=this.getMapObjectLonLatFromMapObjectPixel(moPixel);lonlat=this.getOLLonLatFromMapObjectLonLat(moLonLat);}
60528 return lonlat;},getViewPortPxFromLonLat:function(lonlat){var viewPortPx=null;if((this.mapObject!=null)&&(this.getMapObjectCenter()!=null)){var moLonLat=this.getMapObjectLonLatFromOLLonLat(lonlat);var moPixel=this.getMapObjectPixelFromMapObjectLonLat(moLonLat);viewPortPx=this.getOLPixelFromMapObjectPixel(moPixel);}
60529 return viewPortPx;},getOLLonLatFromMapObjectLonLat:function(moLonLat){var olLonLat=null;if(moLonLat!=null){var lon=this.getLongitudeFromMapObjectLonLat(moLonLat);var lat=this.getLatitudeFromMapObjectLonLat(moLonLat);olLonLat=new OpenLayers.LonLat(lon,lat);}
60530 return olLonLat;},getMapObjectLonLatFromOLLonLat:function(olLonLat){var moLatLng=null;if(olLonLat!=null){moLatLng=this.getMapObjectLonLatFromLonLat(olLonLat.lon,olLonLat.lat);}
60531 return moLatLng;},getOLPixelFromMapObjectPixel:function(moPixel){var olPixel=null;if(moPixel!=null){var x=this.getXFromMapObjectPixel(moPixel);var y=this.getYFromMapObjectPixel(moPixel);olPixel=new OpenLayers.Pixel(x,y);}
60532 return olPixel;},getMapObjectPixelFromOLPixel:function(olPixel){var moPixel=null;if(olPixel!=null){moPixel=this.getMapObjectPixelFromXY(olPixel.x,olPixel.y);}
60533 return moPixel;},CLASS_NAME:"OpenLayers.Layer.EventPane"});OpenLayers.Layer.FixedZoomLevels=OpenLayers.Class({initialize:function(){},initResolutions:function(){var props=new Array('minZoomLevel','maxZoomLevel','numZoomLevels');for(var i=0,len=props.length;i<len;i++){var property=props[i];this[property]=(this.options[property]!=null)?this.options[property]:this.map[property];}
60534 if((this.minZoomLevel==null)||(this.minZoomLevel<this.MIN_ZOOM_LEVEL)){this.minZoomLevel=this.MIN_ZOOM_LEVEL;}
60535 var desiredZoomLevels;var limitZoomLevels=this.MAX_ZOOM_LEVEL-this.minZoomLevel+1;if(((this.options.numZoomLevels==null)&&(this.options.maxZoomLevel!=null))||((this.numZoomLevels==null)&&(this.maxZoomLevel!=null))){desiredZoomLevels=this.maxZoomLevel-this.minZoomLevel+1;}else{desiredZoomLevels=this.numZoomLevels;}
60536 if(desiredZoomLevels!=null){this.numZoomLevels=Math.min(desiredZoomLevels,limitZoomLevels);}else{this.numZoomLevels=limitZoomLevels;}
60537 this.maxZoomLevel=this.minZoomLevel+this.numZoomLevels-1;if(this.RESOLUTIONS!=null){var resolutionsIndex=0;this.resolutions=[];for(var i=this.minZoomLevel;i<=this.maxZoomLevel;i++){this.resolutions[resolutionsIndex++]=this.RESOLUTIONS[i];}
60538 this.maxResolution=this.resolutions[0];this.minResolution=this.resolutions[this.resolutions.length-1];}},getResolution:function(){if(this.resolutions!=null){return OpenLayers.Layer.prototype.getResolution.apply(this,arguments);}else{var resolution=null;var viewSize=this.map.getSize();var extent=this.getExtent();if((viewSize!=null)&&(extent!=null)){resolution=Math.max(extent.getWidth()/viewSize.w,extent.getHeight()/viewSize.h);}
60539 return resolution;}},getExtent:function(){var extent=null;var size=this.map.getSize();var tlPx=new OpenLayers.Pixel(0,0);var tlLL=this.getLonLatFromViewPortPx(tlPx);var brPx=new OpenLayers.Pixel(size.w,size.h);var brLL=this.getLonLatFromViewPortPx(brPx);if((tlLL!=null)&&(brLL!=null)){extent=new OpenLayers.Bounds(tlLL.lon,brLL.lat,brLL.lon,tlLL.lat);}
60540 return extent;},getZoomForResolution:function(resolution){if(this.resolutions!=null){return OpenLayers.Layer.prototype.getZoomForResolution.apply(this,arguments);}else{var extent=OpenLayers.Layer.prototype.getExtent.apply(this,[]);return this.getZoomForExtent(extent);}},getOLZoomFromMapObjectZoom:function(moZoom){var zoom=null;if(moZoom!=null){zoom=moZoom-this.minZoomLevel;}
60541 return zoom;},getMapObjectZoomFromOLZoom:function(olZoom){var zoom=null;if(olZoom!=null){zoom=olZoom+this.minZoomLevel;}
60542 return zoom;},CLASS_NAME:"OpenLayers.Layer.FixedZoomLevels"});OpenLayers.Layer.HTTPRequest=OpenLayers.Class(OpenLayers.Layer,{URL_HASH_FACTOR:(Math.sqrt(5)-1)/2,url:null,params:null,reproject:false,initialize:function(name,url,params,options){var newArguments=arguments;newArguments=[name,options];OpenLayers.Layer.prototype.initialize.apply(this,newArguments);this.url=url;this.params=OpenLayers.Util.extend({},params);},destroy:function(){this.url=null;this.params=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.HTTPRequest(this.name,this.url,this.params,this.getOptions());}
60543 obj=OpenLayers.Layer.prototype.clone.apply(this,[obj]);return obj;},setUrl:function(newUrl){this.url=newUrl;},mergeNewParams:function(newParams){this.params=OpenLayers.Util.extend(this.params,newParams);var ret=this.redraw();if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"params"});}
60544 return ret;},redraw:function(force){if(force){return this.mergeNewParams({"_olSalt":Math.random()});}else{return OpenLayers.Layer.prototype.redraw.apply(this,[]);}},selectUrl:function(paramString,urls){var product=1;for(var i=0,len=paramString.length;i<len;i++){product*=paramString.charCodeAt(i)*this.URL_HASH_FACTOR;product-=Math.floor(product);}
60545 return urls[Math.floor(product*urls.length)];},getFullRequestString:function(newParams,altUrl){var url=altUrl||this.url;var allParams=OpenLayers.Util.extend({},this.params);allParams=OpenLayers.Util.extend(allParams,newParams);var paramsString=OpenLayers.Util.getParameterString(allParams);if(url instanceof Array){url=this.selectUrl(paramsString,url);}
60546 var urlParams=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));for(var key in allParams){if(key.toUpperCase()in urlParams){delete allParams[key];}}
60547 paramsString=OpenLayers.Util.getParameterString(allParams);return OpenLayers.Util.urlAppend(url,paramsString);},CLASS_NAME:"OpenLayers.Layer.HTTPRequest"});OpenLayers.Layer.Image=OpenLayers.Class(OpenLayers.Layer,{isBaseLayer:true,url:null,extent:null,size:null,tile:null,aspectRatio:null,initialize:function(name,url,extent,size,options){this.url=url;this.extent=extent;this.maxExtent=extent;this.size=size;OpenLayers.Layer.prototype.initialize.apply(this,[name,options]);this.aspectRatio=(this.extent.getHeight()/this.size.h)/(this.extent.getWidth()/this.size.w);},destroy:function(){if(this.tile){this.removeTileMonitoringHooks(this.tile);this.tile.destroy();this.tile=null;}
60548 OpenLayers.Layer.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Image(this.name,this.url,this.extent,this.size,this.getOptions());}
60549 obj=OpenLayers.Layer.prototype.clone.apply(this,[obj]);return obj;},setMap:function(map){if(this.options.maxResolution==null){this.options.maxResolution=this.aspectRatio*this.extent.getWidth()/this.size.w;}
60550 OpenLayers.Layer.prototype.setMap.apply(this,arguments);},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);var firstRendering=(this.tile==null);if(zoomChanged||firstRendering){this.setTileSize();var ul=new OpenLayers.LonLat(this.extent.left,this.extent.top);var ulPx=this.map.getLayerPxFromLonLat(ul);if(firstRendering){this.tile=new OpenLayers.Tile.Image(this,ulPx,this.extent,null,this.tileSize);this.addTileMonitoringHooks(this.tile);}else{this.tile.size=this.tileSize.clone();this.tile.position=ulPx.clone();}
60551 this.tile.draw();}},setTileSize:function(){var tileWidth=this.extent.getWidth()/this.map.getResolution();var tileHeight=this.extent.getHeight()/this.map.getResolution();this.tileSize=new OpenLayers.Size(tileWidth,tileHeight);},addTileMonitoringHooks:function(tile){tile.onLoadStart=function(){this.events.triggerEvent("loadstart");};tile.events.register("loadstart",this,tile.onLoadStart);tile.onLoadEnd=function(){this.events.triggerEvent("loadend");};tile.events.register("loadend",this,tile.onLoadEnd);tile.events.register("unload",this,tile.onLoadEnd);},removeTileMonitoringHooks:function(tile){tile.unload();tile.events.un({"loadstart":tile.onLoadStart,"loadend":tile.onLoadEnd,"unload":tile.onLoadEnd,scope:this});},setUrl:function(newUrl){this.url=newUrl;this.tile.draw();},getURL:function(bounds){return this.url;},CLASS_NAME:"OpenLayers.Layer.Image"});OpenLayers.Layer.Markers=OpenLayers.Class(OpenLayers.Layer,{isBaseLayer:false,markers:null,drawn:false,initialize:function(name,options){OpenLayers.Layer.prototype.initialize.apply(this,arguments);this.markers=[];},destroy:function(){this.clearMarkers();this.markers=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},setOpacity:function(opacity){if(opacity!=this.opacity){this.opacity=opacity;for(var i=0,len=this.markers.length;i<len;i++){this.markers[i].setOpacity(this.opacity);}}},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);if(zoomChanged||!this.drawn){for(var i=0,len=this.markers.length;i<len;i++){this.drawMarker(this.markers[i]);}
60552 this.drawn=true;}},addMarker:function(marker){this.markers.push(marker);if(this.opacity!=null){marker.setOpacity(this.opacity);}
60553 if(this.map&&this.map.getExtent()){marker.map=this.map;this.drawMarker(marker);}},removeMarker:function(marker){if(this.markers&&this.markers.length){OpenLayers.Util.removeItem(this.markers,marker);marker.erase();}},clearMarkers:function(){if(this.markers!=null){while(this.markers.length>0){this.removeMarker(this.markers[0]);}}},drawMarker:function(marker){var px=this.map.getLayerPxFromLonLat(marker.lonlat);if(px==null){marker.display(false);}else{if(!marker.isDrawn()){var markerImg=marker.draw(px);this.div.appendChild(markerImg);}else if(marker.icon){marker.icon.moveTo(px);}}},getDataExtent:function(){var maxExtent=null;if(this.markers&&(this.markers.length>0)){var maxExtent=new OpenLayers.Bounds();for(var i=0,len=this.markers.length;i<len;i++){var marker=this.markers[i];maxExtent.extend(marker.lonlat);}}
60554 return maxExtent;},CLASS_NAME:"OpenLayers.Layer.Markers"});OpenLayers.Layer.SphericalMercator={getExtent:function(){var extent=null;if(this.sphericalMercator){extent=this.map.calculateBounds();}else{extent=OpenLayers.Layer.FixedZoomLevels.prototype.getExtent.apply(this);}
60555 return extent;},getLonLatFromViewPortPx:function(viewPortPx){return OpenLayers.Layer.prototype.getLonLatFromViewPortPx.apply(this,arguments);},getViewPortPxFromLonLat:function(lonlat){return OpenLayers.Layer.prototype.getViewPortPxFromLonLat.apply(this,arguments);},initMercatorParameters:function(){this.RESOLUTIONS=[];var maxResolution=156543.0339;for(var zoom=0;zoom<=this.MAX_ZOOM_LEVEL;++zoom){this.RESOLUTIONS[zoom]=maxResolution/Math.pow(2,zoom);}
60556 this.units="m";this.projection=this.projection||"EPSG:900913";},forwardMercator:function(lon,lat){var x=lon*20037508.34/180;var y=Math.log(Math.tan((90+lat)*Math.PI/360))/(Math.PI/180);y=y*20037508.34/180;return new OpenLayers.LonLat(x,y);},inverseMercator:function(x,y){var lon=(x/20037508.34)*180;var lat=(y/20037508.34)*180;lat=180/Math.PI*(2*Math.atan(Math.exp(lat*Math.PI/180))-Math.PI/2);return new OpenLayers.LonLat(lon,lat);},projectForward:function(point){var lonlat=OpenLayers.Layer.SphericalMercator.forwardMercator(point.x,point.y);point.x=lonlat.lon;point.y=lonlat.lat;return point;},projectInverse:function(point){var lonlat=OpenLayers.Layer.SphericalMercator.inverseMercator(point.x,point.y);point.x=lonlat.lon;point.y=lonlat.lat;return point;}};OpenLayers.Projection.addTransform("EPSG:4326","EPSG:900913",OpenLayers.Layer.SphericalMercator.projectForward);OpenLayers.Projection.addTransform("EPSG:900913","EPSG:4326",OpenLayers.Layer.SphericalMercator.projectInverse);OpenLayers.Tile.WFS=OpenLayers.Class(OpenLayers.Tile,{features:null,url:null,request:null,initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.prototype.initialize.apply(this,arguments);this.url=url;this.features=[];},destroy:function(){OpenLayers.Tile.prototype.destroy.apply(this,arguments);this.destroyAllFeatures();this.features=null;this.url=null;if(this.request){this.request.abort();this.request=null;}},clear:function(){this.destroyAllFeatures();},draw:function(){if(OpenLayers.Tile.prototype.draw.apply(this,arguments)){if(this.isLoading){this.events.triggerEvent("reload");}else{this.isLoading=true;this.events.triggerEvent("loadstart");}
60557 this.loadFeaturesForRegion(this.requestSuccess);}},loadFeaturesForRegion:function(success,failure){if(this.request){this.request.abort();}
60558 this.request=OpenLayers.Request.GET({url:this.url,success:success,failure:failure,scope:this});},requestSuccess:function(request){if(this.features){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
60559 if(this.layer.vectorMode){this.layer.addFeatures(this.layer.formatObject.read(doc));}else{var xml=new OpenLayers.Format.XML();if(typeof doc=="string"){doc=xml.read(doc);}
60560 var resultFeatures=xml.getElementsByTagNameNS(doc,"http://www.opengis.net/gml","featureMember");this.addResults(resultFeatures);}}
60561 if(this.events){this.events.triggerEvent("loadend");}
60562 this.request=null;},addResults:function(results){for(var i=0;i<results.length;i++){var feature=new this.layer.featureClass(this.layer,results[i]);this.features.push(feature);}},destroyAllFeatures:function(){while(this.features.length>0){var feature=this.features.shift();feature.destroy();}},CLASS_NAME:"OpenLayers.Tile.WFS"});OpenLayers.Control.DrawFeature=OpenLayers.Class(OpenLayers.Control,{layer:null,callbacks:null,EVENT_TYPES:["featureadded"],multi:false,featureAdded:function(){},handlerOptions:null,initialize:function(layer,handler,options){this.EVENT_TYPES=OpenLayers.Control.DrawFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.callbacks=OpenLayers.Util.extend({done:this.drawFeature,modify:function(vertex,feature){this.layer.events.triggerEvent("sketchmodified",{vertex:vertex,feature:feature});},create:function(vertex,feature){this.layer.events.triggerEvent("sketchstarted",{vertex:vertex,feature:feature});}},this.callbacks);this.layer=layer;this.handlerOptions=this.handlerOptions||{};if(!("multi"in this.handlerOptions)){this.handlerOptions.multi=this.multi;}
60563 var sketchStyle=this.layer.styleMap&&this.layer.styleMap.styles.temporary;if(sketchStyle){this.handlerOptions.layerOptions=OpenLayers.Util.applyDefaults(this.handlerOptions.layerOptions,{styleMap:new OpenLayers.StyleMap({"default":sketchStyle})});}
60564 this.handler=new handler(this,this.callbacks,this.handlerOptions);},drawFeature:function(geometry){var feature=new OpenLayers.Feature.Vector(geometry);var proceed=this.layer.events.triggerEvent("sketchcomplete",{feature:feature});if(proceed!==false){feature.state=OpenLayers.State.INSERT;this.layer.addFeatures([feature]);this.featureAdded(feature);this.events.triggerEvent("featureadded",{feature:feature});}},CLASS_NAME:"OpenLayers.Control.DrawFeature"});OpenLayers.Control.Measure=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:['measure','measurepartial'],handlerOptions:null,callbacks:null,displaySystem:'metric',geodesic:false,displaySystemUnits:{geographic:['dd'],english:['mi','ft','in'],metric:['km','m']},partialDelay:300,delayedTrigger:null,persist:false,initialize:function(handler,options){this.EVENT_TYPES=OpenLayers.Control.Measure.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.callbacks=OpenLayers.Util.extend({done:this.measureComplete,point:this.measurePartial},this.callbacks);this.handlerOptions=OpenLayers.Util.extend({persist:this.persist},this.handlerOptions);this.handler=new handler(this,this.callbacks,this.handlerOptions);},cancel:function(){this.handler.cancel();},updateHandler:function(handler,options){var active=this.active;if(active){this.deactivate();}
60565 this.handler=new handler(this,this.callbacks,options);if(active){this.activate();}},measureComplete:function(geometry){if(this.delayedTrigger){window.clearTimeout(this.delayedTrigger);}
60566 this.measure(geometry,"measure");},measurePartial:function(point,geometry){if(geometry.getLength()>0){geometry=geometry.clone();this.delayedTrigger=window.setTimeout(OpenLayers.Function.bind(function(){this.measure(geometry,"measurepartial");},this),this.partialDelay);}},measure:function(geometry,eventType){var stat,order;if(geometry.CLASS_NAME.indexOf('LineString')>-1){stat=this.getBestLength(geometry);order=1;}else{stat=this.getBestArea(geometry);order=2;}
60567 this.events.triggerEvent(eventType,{measure:stat[0],units:stat[1],order:order,geometry:geometry});},getBestArea:function(geometry){var units=this.displaySystemUnits[this.displaySystem];var unit,area;for(var i=0,len=units.length;i<len;++i){unit=units[i];area=this.getArea(geometry,unit);if(area>1){break;}}
60568 return[area,unit];},getArea:function(geometry,units){var area,geomUnits;if(this.geodesic){area=geometry.getGeodesicArea(this.map.getProjectionObject());geomUnits="m";}else{area=geometry.getArea();geomUnits=this.map.getUnits();}
60569 var inPerDisplayUnit=OpenLayers.INCHES_PER_UNIT[units];if(inPerDisplayUnit){var inPerMapUnit=OpenLayers.INCHES_PER_UNIT[geomUnits];area*=Math.pow((inPerMapUnit/inPerDisplayUnit),2);}
60570 return area;},getBestLength:function(geometry){var units=this.displaySystemUnits[this.displaySystem];var unit,length;for(var i=0,len=units.length;i<len;++i){unit=units[i];length=this.getLength(geometry,unit);if(length>1){break;}}
60571 return[length,unit];},getLength:function(geometry,units){var length,geomUnits;if(this.geodesic){length=geometry.getGeodesicLength(this.map.getProjectionObject());geomUnits="m";}else{length=geometry.getLength();geomUnits=this.map.getUnits();}
60572 var inPerDisplayUnit=OpenLayers.INCHES_PER_UNIT[units];if(inPerDisplayUnit){var inPerMapUnit=OpenLayers.INCHES_PER_UNIT[geomUnits];length*=(inPerMapUnit/inPerDisplayUnit);}
60573 return length;},CLASS_NAME:"OpenLayers.Control.Measure"});OpenLayers.Control.ZoomBox=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOOL,out:false,alwaysZoom:false,draw:function(){this.handler=new OpenLayers.Handler.Box(this,{done:this.zoomBox},{keyMask:this.keyMask});},zoomBox:function(position){if(position instanceof OpenLayers.Bounds){var bounds;if(!this.out){var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat);}else{var pixWidth=Math.abs(position.right-position.left);var pixHeight=Math.abs(position.top-position.bottom);var zoomFactor=Math.min((this.map.size.h/pixHeight),(this.map.size.w/pixWidth));var extent=this.map.getExtent();var center=this.map.getLonLatFromPixel(position.getCenterPixel());var xmin=center.lon-(extent.getWidth()/2)*zoomFactor;var xmax=center.lon+(extent.getWidth()/2)*zoomFactor;var ymin=center.lat-(extent.getHeight()/2)*zoomFactor;var ymax=center.lat+(extent.getHeight()/2)*zoomFactor;bounds=new OpenLayers.Bounds(xmin,ymin,xmax,ymax);}
60574 var lastZoom=this.map.getZoom();this.map.zoomToExtent(bounds);if(lastZoom==this.map.getZoom()&&this.alwaysZoom==true){this.map.zoomTo(lastZoom+(this.out?-1:1));}}else{if(!this.out){this.map.setCenter(this.map.getLonLatFromPixel(position),this.map.getZoom()+1);}else{this.map.setCenter(this.map.getLonLatFromPixel(position),this.map.getZoom()-1);}}},CLASS_NAME:"OpenLayers.Control.ZoomBox"});OpenLayers.Format.WFSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.WFSCapabilities.v1,{initialize:function(options){OpenLayers.Format.WFSCapabilities.v1.prototype.initialize.apply(this,[options]);},read_cap_Service:function(capabilities,node){var service={};this.runChildNodes(service,node);capabilities.service=service;},read_cap_Fees:function(service,node){var fees=this.getChildValue(node);if(fees&&fees.toLowerCase()!="none"){service.fees=fees;}},read_cap_AccessConstraints:function(service,node){var constraints=this.getChildValue(node);if(constraints&&constraints.toLowerCase()!="none"){service.accessConstraints=constraints;}},read_cap_OnlineResource:function(service,node){var onlineResource=this.getChildValue(node);if(onlineResource&&onlineResource.toLowerCase()!="none"){service.onlineResource=onlineResource;}},read_cap_Keywords:function(service,node){var keywords=this.getChildValue(node);if(keywords&&keywords.toLowerCase()!="none"){service.keywords=keywords.split(', ');}},read_cap_Capability:function(capabilities,node){var capability={};this.runChildNodes(capability,node);capabilities.capability=capability;},read_cap_Request:function(obj,node){var request={};this.runChildNodes(request,node);obj.request=request;},read_cap_GetFeature:function(request,node){var getfeature={href:{},formats:[]};this.runChildNodes(getfeature,node);request.getfeature=getfeature;},read_cap_ResultFormat:function(obj,node){var children=node.childNodes;var childNode;for(var i=0;i<children.length;i++){childNode=children[i];if(childNode.nodeType==1){obj.formats.push(childNode.nodeName);}}},read_cap_DCPType:function(obj,node){this.runChildNodes(obj,node);},read_cap_HTTP:function(obj,node){this.runChildNodes(obj.href,node);},read_cap_Get:function(obj,node){obj.get=node.getAttribute("onlineResource");},read_cap_Post:function(obj,node){obj.post=node.getAttribute("onlineResource");},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1_0_0"});OpenLayers.Format.WFSCapabilities.v1_1_0=OpenLayers.Class(OpenLayers.Format.WFSCapabilities.v1,{initialize:function(options){OpenLayers.Format.WFSCapabilities.v1.prototype.initialize.apply(this,[options]);},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1_1_0"});OpenLayers.Format.WKT=OpenLayers.Class(OpenLayers.Format,{initialize:function(options){this.regExes={'typeStr':/^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/,'spaces':/\s+/,'parenComma':/\)\s*,\s*\(/,'doubleParenComma':/\)\s*\)\s*,\s*\(\s*\(/,'trimParens':/^\s*\(?(.*?)\)?\s*$/};OpenLayers.Format.prototype.initialize.apply(this,[options]);},read:function(wkt){var features,type,str;var matches=this.regExes.typeStr.exec(wkt);if(matches){type=matches[1].toLowerCase();str=matches[2];if(this.parse[type]){features=this.parse[type].apply(this,[str]);}
60575 if(this.internalProjection&&this.externalProjection){if(features&&features.CLASS_NAME=="OpenLayers.Feature.Vector"){features.geometry.transform(this.externalProjection,this.internalProjection);}else if(features&&type!="geometrycollection"&&typeof features=="object"){for(var i=0,len=features.length;i<len;i++){var component=features[i];component.geometry.transform(this.externalProjection,this.internalProjection);}}}}
60576 return features;},write:function(features){var collection,geometry,type,data,isCollection;if(features.constructor==Array){collection=features;isCollection=true;}else{collection=[features];isCollection=false;}
60577 var pieces=[];if(isCollection){pieces.push('GEOMETRYCOLLECTION(');}
60578 for(var i=0,len=collection.length;i<len;++i){if(isCollection&&i>0){pieces.push(',');}
60579 geometry=collection[i].geometry;type=geometry.CLASS_NAME.split('.')[2].toLowerCase();if(!this.extract[type]){return null;}
60580 if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
60581 data=this.extract[type].apply(this,[geometry]);pieces.push(type.toUpperCase()+'('+data+')');}
60582 if(isCollection){pieces.push(')');}
60583 return pieces.join('');},extract:{'point':function(point){return point.x+' '+point.y;},'multipoint':function(multipoint){var array=[];for(var i=0,len=multipoint.components.length;i<len;++i){array.push('('+
60584 this.extract.point.apply(this,[multipoint.components[i]])+')');}
60585 return array.join(',');},'linestring':function(linestring){var array=[];for(var i=0,len=linestring.components.length;i<len;++i){array.push(this.extract.point.apply(this,[linestring.components[i]]));}
60586 return array.join(',');},'multilinestring':function(multilinestring){var array=[];for(var i=0,len=multilinestring.components.length;i<len;++i){array.push('('+
60587 this.extract.linestring.apply(this,[multilinestring.components[i]])+')');}
60588 return array.join(',');},'polygon':function(polygon){var array=[];for(var i=0,len=polygon.components.length;i<len;++i){array.push('('+
60589 this.extract.linestring.apply(this,[polygon.components[i]])+')');}
60590 return array.join(',');},'multipolygon':function(multipolygon){var array=[];for(var i=0,len=multipolygon.components.length;i<len;++i){array.push('('+
60591 this.extract.polygon.apply(this,[multipolygon.components[i]])+')');}
60592 return array.join(',');}},parse:{'point':function(str){var coords=OpenLayers.String.trim(str).split(this.regExes.spaces);return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(coords[0],coords[1]));},'multipoint':function(str){var point;var points=OpenLayers.String.trim(str).split(this.regExes.parenComma);var components=[];for(var i=0,len=points.length;i<len;++i){point=points[i].replace(this.regExes.trimParens,'$1');components.push(this.parse.point.apply(this,[point]).geometry);}
60593 return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPoint(components));},'linestring':function(str){var points=OpenLayers.String.trim(str).split(',');var components=[];for(var i=0,len=points.length;i<len;++i){components.push(this.parse.point.apply(this,[points[i]]).geometry);}
60594 return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(components));},'multilinestring':function(str){var line;var lines=OpenLayers.String.trim(str).split(this.regExes.parenComma);var components=[];for(var i=0,len=lines.length;i<len;++i){line=lines[i].replace(this.regExes.trimParens,'$1');components.push(this.parse.linestring.apply(this,[line]).geometry);}
60595 return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiLineString(components));},'polygon':function(str){var ring,linestring,linearring;var rings=OpenLayers.String.trim(str).split(this.regExes.parenComma);var components=[];for(var i=0,len=rings.length;i<len;++i){ring=rings[i].replace(this.regExes.trimParens,'$1');linestring=this.parse.linestring.apply(this,[ring]).geometry;linearring=new OpenLayers.Geometry.LinearRing(linestring.components);components.push(linearring);}
60596 return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon(components));},'multipolygon':function(str){var polygon;var polygons=OpenLayers.String.trim(str).split(this.regExes.doubleParenComma);var components=[];for(var i=0,len=polygons.length;i<len;++i){polygon=polygons[i].replace(this.regExes.trimParens,'$1');components.push(this.parse.polygon.apply(this,[polygon]).geometry);}
60597 return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPolygon(components));},'geometrycollection':function(str){str=str.replace(/,\s*([A-Za-z])/g,'|$1');var wktArray=OpenLayers.String.trim(str).split('|');var components=[];for(var i=0,len=wktArray.length;i<len;++i){components.push(OpenLayers.Format.WKT.prototype.read.apply(this,[wktArray[i]]));}
60598 return components;}},CLASS_NAME:"OpenLayers.Format.WKT"});OpenLayers.Format.WMC.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ol:"http://openlayers.org/context",wmc:"http://www.opengis.net/context",sld:"http://www.opengis.net/sld",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},schemaLocation:"",getNamespacePrefix:function(uri){var prefix=null;if(uri==null){prefix=this.namespaces[this.defaultPrefix];}else{for(prefix in this.namespaces){if(this.namespaces[prefix]==uri){break;}}}
60599 return prefix;},defaultPrefix:"wmc",rootPrefix:null,defaultStyleName:"",defaultStyleTitle:"Default",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60600 var root=data.documentElement;this.rootPrefix=root.prefix;var context={version:root.getAttribute("version")};this.runChildNodes(context,root);return context;},runChildNodes:function(obj,node){var children=node.childNodes;var childNode,processor,prefix,local;for(var i=0,len=children.length;i<len;++i){childNode=children[i];if(childNode.nodeType==1){prefix=this.getNamespacePrefix(childNode.namespaceURI);local=childNode.nodeName.split(":").pop();processor=this["read_"+prefix+"_"+local];if(processor){processor.apply(this,[obj,childNode]);}}}},read_wmc_General:function(context,node){this.runChildNodes(context,node);},read_wmc_BoundingBox:function(context,node){context.projection=node.getAttribute("SRS");context.bounds=new OpenLayers.Bounds(parseFloat(node.getAttribute("minx")),parseFloat(node.getAttribute("miny")),parseFloat(node.getAttribute("maxx")),parseFloat(node.getAttribute("maxy")));},read_wmc_LayerList:function(context,node){context.layersContext=[];this.runChildNodes(context,node);},read_wmc_Layer:function(context,node){var layerContext={visibility:(node.getAttribute("hidden")!="1"),queryable:(node.getAttribute("queryable")=="1"),formats:[],styles:[]};this.runChildNodes(layerContext,node);context.layersContext.push(layerContext);},read_wmc_Extension:function(obj,node){this.runChildNodes(obj,node);},read_ol_units:function(layerContext,node){layerContext.units=this.getChildValue(node);},read_ol_maxExtent:function(obj,node){var bounds=new OpenLayers.Bounds(node.getAttribute("minx"),node.getAttribute("miny"),node.getAttribute("maxx"),node.getAttribute("maxy"));obj.maxExtent=bounds;},read_ol_transparent:function(layerContext,node){layerContext.transparent=this.getChildValue(node);},read_ol_numZoomLevels:function(layerContext,node){layerContext.numZoomLevels=parseInt(this.getChildValue(node));},read_ol_opacity:function(layerContext,node){layerContext.opacity=parseFloat(this.getChildValue(node));},read_ol_singleTile:function(layerContext,node){layerContext.singleTile=(this.getChildValue(node)=="true");},read_ol_tileSize:function(layerContext,node){var obj={"width":node.getAttribute("width"),"height":node.getAttribute("height")};layerContext.tileSize=obj;},read_ol_isBaseLayer:function(layerContext,node){layerContext.isBaseLayer=(this.getChildValue(node)=="true");},read_ol_displayInLayerSwitcher:function(layerContext,node){layerContext.displayInLayerSwitcher=(this.getChildValue(node)=="true");},read_wmc_Server:function(layerContext,node){layerContext.version=node.getAttribute("version");var server={};var links=node.getElementsByTagName("OnlineResource");if(links.length>0){this.read_wmc_OnlineResource(server,links[0]);}
60601 layerContext.url=server.href;},read_wmc_FormatList:function(layerContext,node){this.runChildNodes(layerContext,node);},read_wmc_Format:function(layerContext,node){var format={value:this.getChildValue(node)};if(node.getAttribute("current")=="1"){format.current=true;}
60602 layerContext.formats.push(format);},read_wmc_StyleList:function(layerContext,node){this.runChildNodes(layerContext,node);},read_wmc_Style:function(layerContext,node){var style={};this.runChildNodes(style,node);if(node.getAttribute("current")=="1"){style.current=true;}
60603 layerContext.styles.push(style);},read_wmc_SLD:function(style,node){this.runChildNodes(style,node);},read_sld_StyledLayerDescriptor:function(sld,node){var xml=OpenLayers.Format.XML.prototype.write.apply(this,[node]);sld.body=xml;},read_wmc_OnlineResource:function(obj,node){obj.href=this.getAttributeNS(node,this.namespaces.xlink,"href");},read_wmc_Name:function(obj,node){var name=this.getChildValue(node);if(name){obj.name=name;}},read_wmc_Title:function(obj,node){var title=this.getChildValue(node);if(title){obj.title=title;}},read_wmc_MetadataURL:function(layerContext,node){var metadataURL={};var links=node.getElementsByTagName("OnlineResource");if(links.length>0){this.read_wmc_OnlineResource(metadataURL,links[0]);}
60604 layerContext.metadataURL=metadataURL.href;},read_wmc_Abstract:function(obj,node){var abst=this.getChildValue(node);if(abst){obj["abstract"]=abst;}},read_wmc_LegendURL:function(style,node){var legend={width:node.getAttribute('width'),height:node.getAttribute('height')};var links=node.getElementsByTagName("OnlineResource");if(links.length>0){this.read_wmc_OnlineResource(legend,links[0]);}
60605 style.legend=legend;},write:function(context,options){var root=this.createElementDefaultNS("ViewContext");this.setAttributes(root,{version:this.VERSION,id:(options&&typeof options.id=="string")?options.id:OpenLayers.Util.createUniqueID("OpenLayers_Context_")});this.setAttributeNS(root,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);root.appendChild(this.write_wmc_General(context));root.appendChild(this.write_wmc_LayerList(context));return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},createElementDefaultNS:function(name,childValue,attributes){var node=this.createElementNS(this.namespaces[this.defaultPrefix],name);if(childValue){node.appendChild(this.createTextNode(childValue));}
60606 if(attributes){this.setAttributes(node,attributes);}
60607 return node;},setAttributes:function(node,obj){var value;for(var name in obj){value=obj[name].toString();if(value.match(/[A-Z]/)){this.setAttributeNS(node,null,name,value);}else{node.setAttribute(name,value);}}},write_wmc_General:function(context){var node=this.createElementDefaultNS("General");if(context.size){node.appendChild(this.createElementDefaultNS("Window",null,{width:context.size.w,height:context.size.h}));}
60608 var bounds=context.bounds;node.appendChild(this.createElementDefaultNS("BoundingBox",null,{minx:bounds.left.toPrecision(18),miny:bounds.bottom.toPrecision(18),maxx:bounds.right.toPrecision(18),maxy:bounds.top.toPrecision(18),SRS:context.projection}));node.appendChild(this.createElementDefaultNS("Title",context.title));node.appendChild(this.write_ol_MapExtension(context));return node;},write_ol_MapExtension:function(context){var node=this.createElementDefaultNS("Extension");var bounds=context.maxExtent;if(bounds){var maxExtent=this.createElementNS(this.namespaces.ol,"ol:maxExtent");this.setAttributes(maxExtent,{minx:bounds.left.toPrecision(18),miny:bounds.bottom.toPrecision(18),maxx:bounds.right.toPrecision(18),maxy:bounds.top.toPrecision(18)});node.appendChild(maxExtent);}
60609 return node;},write_wmc_LayerList:function(context){var list=this.createElementDefaultNS("LayerList");for(var i=0,len=context.layersContext.length;i<len;++i){list.appendChild(this.write_wmc_Layer(context.layersContext[i]));}
60610 return list;},write_wmc_Layer:function(context){var node=this.createElementDefaultNS("Layer",null,{queryable:context.queryable?"1":"0",hidden:context.visibility?"0":"1"});node.appendChild(this.write_wmc_Server(context));node.appendChild(this.createElementDefaultNS("Name",context.name));node.appendChild(this.createElementDefaultNS("Title",context.title));if(context.metadataURL){node.appendChild(this.write_wmc_MetadataURL(context.metadataURL));}
60611 return node;},write_wmc_LayerExtension:function(context){var node=this.createElementDefaultNS("Extension");var bounds=context.maxExtent;var maxExtent=this.createElementNS(this.namespaces.ol,"ol:maxExtent");this.setAttributes(maxExtent,{minx:bounds.left.toPrecision(18),miny:bounds.bottom.toPrecision(18),maxx:bounds.right.toPrecision(18),maxy:bounds.top.toPrecision(18)});node.appendChild(maxExtent);if(context.tileSize&&!context.singleTile){var size=this.createElementNS(this.namespaces.ol,"ol:tileSize");this.setAttributes(size,context.tileSize);node.appendChild(size);}
60612 var properties=["transparent","numZoomLevels","units","isBaseLayer","opacity","displayInLayerSwitcher","singleTile"];var child;for(var i=0,len=properties.length;i<len;++i){child=this.createOLPropertyNode(context,properties[i]);if(child){node.appendChild(child);}}
60613 return node;},createOLPropertyNode:function(obj,prop){var node=null;if(obj[prop]!=null){node=this.createElementNS(this.namespaces.ol,"ol:"+prop);node.appendChild(this.createTextNode(obj[prop].toString()));}
60614 return node;},write_wmc_Server:function(context){var node=this.createElementDefaultNS("Server");this.setAttributes(node,{service:"OGC:WMS",version:context.version});node.appendChild(this.write_wmc_OnlineResource(context.url));return node;},write_wmc_MetadataURL:function(metadataURL){var node=this.createElementDefaultNS("MetadataURL");node.appendChild(this.write_wmc_OnlineResource(metadataURL));return node;},write_wmc_FormatList:function(context){var node=this.createElementDefaultNS("FormatList");for(var i=0,len=context.formats.length;i<len;i++){var format=context.formats[i];node.appendChild(this.createElementDefaultNS("Format",format.value,(format.current&&format.current==true)?{current:"1"}:null));}
60615 return node;},write_wmc_StyleList:function(layer){var node=this.createElementDefaultNS("StyleList");var styles=layer.styles;if(styles&&styles instanceof Array){var sld;for(var i=0,len=styles.length;i<len;i++){var s=styles[i];var style=this.createElementDefaultNS("Style",null,(s.current&&s.current==true)?{current:"1"}:null);if(s.href){sld=this.createElementDefaultNS("SLD");var link=this.write_wmc_OnlineResource(s.href);sld.appendChild(link);sld.appendChild(this.createElementDefaultNS("Name",s.name));if(s.title){sld.appendChild(this.createElementDefaultNS("Title",s.title));}
60616 style.appendChild(sld);}else if(s.body){sld=this.createElementDefaultNS("SLD");var doc=OpenLayers.Format.XML.prototype.read.apply(this,[s.body]);var imported=doc.documentElement;if(sld.ownerDocument&&sld.ownerDocument.importNode){imported=sld.ownerDocument.importNode(imported,true);}
60617 sld.appendChild(imported);sld.appendChild(this.createElementDefaultNS("Name",s.name));if(s.title){sld.appendChild(this.createElementDefaultNS("Title",s.title));}
60618 style.appendChild(sld);}else{style.appendChild(this.createElementDefaultNS("Name",s.name));style.appendChild(this.createElementDefaultNS("Title",s.title));if(s['abstract']){style.appendChild(this.createElementDefaultNS("Abstract",s['abstract']));}}
60619 node.appendChild(style);}}
60620 return node;},write_wmc_OnlineResource:function(href){var node=this.createElementDefaultNS("OnlineResource");this.setAttributeNS(node,this.namespaces.xlink,"xlink:type","simple");this.setAttributeNS(node,this.namespaces.xlink,"xlink:href",href);return node;},CLASS_NAME:"OpenLayers.Format.WMC.v1"});OpenLayers.Format.WMSCapabilities.v1_1=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1,{readers:{"wms":OpenLayers.Util.applyDefaults({"WMT_MS_Capabilities":function(node,obj){this.readChildNodes(node,obj);},"Keyword":function(node,obj){if(obj.keywords){obj.keywords.push(this.getChildValue(node));}},"DescribeLayer":function(node,obj){obj.describelayer={formats:[]};this.readChildNodes(node,obj.describelayer);},"GetLegendGraphic":function(node,obj){obj.getlegendgraphic={formats:[]};this.readChildNodes(node,obj.getlegendgraphic);},"GetStyles":function(node,obj){obj.getstyles={formats:[]};this.readChildNodes(node,obj.getstyles);},"PutStyles":function(node,obj){obj.putstyles={formats:[]};this.readChildNodes(node,obj.putstyles);},"UserDefinedSymbolization":function(node,obj){var userSymbols={supportSLD:parseInt(node.getAttribute("SupportSLD"))==1,userLayer:parseInt(node.getAttribute("UserLayer"))==1,userStyle:parseInt(node.getAttribute("UserStyle"))==1,remoteWFS:parseInt(node.getAttribute("RemoteWFS"))==1};obj.userSymbols=userSymbols;},"LatLonBoundingBox":function(node,obj){obj.llbbox=[parseFloat(node.getAttribute("minx")),parseFloat(node.getAttribute("miny")),parseFloat(node.getAttribute("maxx")),parseFloat(node.getAttribute("maxy"))];},"BoundingBox":function(node,obj){var bbox=OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"].BoundingBox.apply(this,[node,obj]);bbox.srs=node.getAttribute("SRS");obj.bbox[bbox.srs]=bbox;},"ScaleHint":function(node,obj){var min=node.getAttribute("min");var max=node.getAttribute("max");var rad2=Math.pow(2,0.5);var ipm=OpenLayers.INCHES_PER_UNIT["m"];obj.maxScale=parseFloat(((min/rad2)*ipm*OpenLayers.DOTS_PER_INCH).toPrecision(13));obj.minScale=parseFloat(((max/rad2)*ipm*OpenLayers.DOTS_PER_INCH).toPrecision(13));},"Dimension":function(node,obj){var name=node.getAttribute("name").toLowerCase();var dim={name:name,units:node.getAttribute("units"),unitsymbol:node.getAttribute("unitSymbol")};obj.dimensions[dim.name]=dim;},"Extent":function(node,obj){var name=node.getAttribute("name").toLowerCase();if(name in obj["dimensions"]){var extent=obj.dimensions[name];extent.nearestVal=node.getAttribute("nearestValue")==="1";extent.multipleVal=node.getAttribute("multipleValues")==="1";extent.current=node.getAttribute("current")==="1";extent["default"]=node.getAttribute("default")||"";var values=this.getChildValue(node);extent.values=values.split(",");}}},OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"])},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1"});OpenLayers.Format.WMSCapabilities.v1_3=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1,{readers:{"wms":OpenLayers.Util.applyDefaults({"WMS_Capabilities":function(node,obj){this.readChildNodes(node,obj);},"LayerLimit":function(node,obj){obj.layerLimit=parseInt(this.getChildValue(node));},"MaxWidth":function(node,obj){obj.maxWidth=parseInt(this.getChildValue(node));},"MaxHeight":function(node,obj){obj.maxHeight=parseInt(this.getChildValue(node));},"BoundingBox":function(node,obj){var bbox=OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"].BoundingBox.apply(this,[node,obj]);bbox.srs=node.getAttribute("CRS");obj.bbox[bbox.srs]=bbox;},"CRS":function(node,obj){this.readers.wms.SRS.apply(this,[node,obj]);},"EX_GeographicBoundingBox":function(node,obj){obj.llbbox=[];this.readChildNodes(node,obj.llbbox);},"westBoundLongitude":function(node,obj){obj[0]=this.getChildValue(node);},"eastBoundLongitude":function(node,obj){obj[2]=this.getChildValue(node);},"southBoundLatitude":function(node,obj){obj[1]=this.getChildValue(node);},"northBoundLatitude":function(node,obj){obj[3]=this.getChildValue(node);},"MinScaleDenominator":function(node,obj){obj.maxScale=parseFloat(this.getChildValue(node)).toPrecision(16);},"MaxScaleDenominator":function(node,obj){obj.minScale=parseFloat(this.getChildValue(node)).toPrecision(16);},"Dimension":function(node,obj){var name=node.getAttribute("name").toLowerCase();var dim={name:name,units:node.getAttribute("units"),unitsymbol:node.getAttribute("unitSymbol"),nearestVal:node.getAttribute("nearestValue")==="1",multipleVal:node.getAttribute("multipleValues")==="1","default":node.getAttribute("default")||"",current:node.getAttribute("current")==="1",values:this.getChildValue(node).split(",")};obj.dimensions[dim.name]=dim;},"Keyword":function(node,obj){var keyword={value:this.getChildValue(node),vocabulary:node.getAttribute("vocabulary")};if(obj.keywords){obj.keywords.push(keyword);}}},OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"]),"sld":{"UserDefinedSymbolization":function(node,obj){this.readers.wms.UserDefinedSymbolization.apply(this,[node,obj]);obj.userSymbols.inlineFeature=parseInt(node.getAttribute("InlineFeature"))==1;obj.userSymbols.remoteWCS=parseInt(node.getAttribute("RemoteWCS"))==1;},"DescribeLayer":function(node,obj){this.readers.wms.DescribeLayer.apply(this,[node,obj]);},"GetLegendGraphic":function(node,obj){this.readers.wms.GetLegendGraphic.apply(this,[node,obj]);}}},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_3"});OpenLayers.Format.WMTSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1_1_0,{version:"1.0.0",namespaces:{ows:"http://www.opengis.net/ows/1.1",wmts:"http://www.opengis.net/wmts/1.0",xlink:"http://www.w3.org/1999/xlink"},yx:null,defaultPrefix:"wmts",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;var yx=OpenLayers.Util.extend({},OpenLayers.Format.WMTSCapabilities.prototype.yx);this.yx=OpenLayers.Util.extend(yx,this.yx);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60621 if(data&&data.nodeType==9){data=data.documentElement;}
60622 var capabilities={};this.readNode(data,capabilities);capabilities.version=this.version;return capabilities;},readers:{"wmts":{"Capabilities":function(node,obj){this.readChildNodes(node,obj);},"Contents":function(node,obj){obj.contents={};obj.contents.layers=[];obj.contents.tileMatrixSets={};this.readChildNodes(node,obj.contents);},"Layer":function(node,obj){var layer={styles:[],formats:[],tileMatrixSetLinks:[]};layer.layers=[];this.readChildNodes(node,layer);obj.layers.push(layer);},"Style":function(node,obj){var style={};style.isDefault=(node.getAttribute("isDefault")==="true");this.readChildNodes(node,style);obj.styles.push(style);},"Format":function(node,obj){obj.formats.push(this.getChildValue(node));},"TileMatrixSetLink":function(node,obj){var tileMatrixSetLink={};this.readChildNodes(node,tileMatrixSetLink);obj.tileMatrixSetLinks.push(tileMatrixSetLink);},"TileMatrixSet":function(node,obj){if(obj.layers){var tileMatrixSet={matrixIds:[]};this.readChildNodes(node,tileMatrixSet);obj.tileMatrixSets[tileMatrixSet.identifier]=tileMatrixSet;}else{obj.tileMatrixSet=this.getChildValue(node);}},"TileMatrix":function(node,obj){var tileMatrix={supportedCRS:obj.supportedCRS};this.readChildNodes(node,tileMatrix);obj.matrixIds.push(tileMatrix);},"ScaleDenominator":function(node,obj){obj.scaleDenominator=parseFloat(this.getChildValue(node));},"TopLeftCorner":function(node,obj){var topLeftCorner=this.getChildValue(node);var coords=topLeftCorner.split(" ");var yx;if(obj.supportedCRS){var crs=obj.supportedCRS.replace(/urn:ogc:def:crs:(\w+):.+:(\w+)$/,"urn:ogc:def:crs:$1::$2");yx=!!this.yx[crs];}
60623 if(yx){obj.topLeftCorner=new OpenLayers.LonLat(coords[1],coords[0]);}else{obj.topLeftCorner=new OpenLayers.LonLat(coords[0],coords[1]);}},"TileWidth":function(node,obj){obj.tileWidth=parseInt(this.getChildValue(node));},"TileHeight":function(node,obj){obj.tileHeight=parseInt(this.getChildValue(node));},"MatrixWidth":function(node,obj){obj.matrixWidth=parseInt(this.getChildValue(node));},"MatrixHeight":function(node,obj){obj.matrixHeight=parseInt(this.getChildValue(node));},"WSDL":function(node,obj){obj.wsdl={};obj.wsdl.href=node.getAttribute("xlink:href");},"ServiceMetadataURL":function(node,obj){obj.serviceMetadataUrl={};obj.serviceMetadataUrl.href=node.getAttribute("xlink:href");}},"ows":OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers["ows"]},CLASS_NAME:"OpenLayers.Format.WMTSCapabilities.v1_0_0"});OpenLayers.Layer.Boxes=OpenLayers.Class(OpenLayers.Layer.Markers,{initialize:function(name,options){OpenLayers.Layer.Markers.prototype.initialize.apply(this,arguments);},drawMarker:function(marker){var bounds=marker.bounds;var topleft=this.map.getLayerPxFromLonLat(new OpenLayers.LonLat(bounds.left,bounds.top));var botright=this.map.getLayerPxFromLonLat(new OpenLayers.LonLat(bounds.right,bounds.bottom));if(botright==null||topleft==null){marker.display(false);}else{var sz=new OpenLayers.Size(Math.max(1,botright.x-topleft.x),Math.max(1,botright.y-topleft.y));var markerDiv=marker.draw(topleft,sz);if(!marker.drawn){this.div.appendChild(markerDiv);marker.drawn=true;}}},removeMarker:function(marker){OpenLayers.Util.removeItem(this.markers,marker);if((marker.div!=null)&&(marker.div.parentNode==this.div)){this.div.removeChild(marker.div);}},CLASS_NAME:"OpenLayers.Layer.Boxes"});OpenLayers.Layer.GeoRSS=OpenLayers.Class(OpenLayers.Layer.Markers,{location:null,features:null,formatOptions:null,selectedFeature:null,icon:null,popupSize:null,useFeedTitle:true,initialize:function(name,location,options){OpenLayers.Layer.Markers.prototype.initialize.apply(this,[name,options]);this.location=location;this.features=[];},destroy:function(){OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);this.clearFeatures();this.features=null;},loadRSS:function(){if(!this.loaded){this.events.triggerEvent("loadstart");OpenLayers.Request.GET({url:this.location,success:this.parseData,scope:this});this.loaded=true;}},moveTo:function(bounds,zoomChanged,minor){OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadRSS();}},parseData:function(ajaxRequest){var doc=ajaxRequest.responseXML;if(!doc||!doc.documentElement){doc=OpenLayers.Format.XML.prototype.read(ajaxRequest.responseText);}
60624 if(this.useFeedTitle){var name=null;try{name=doc.getElementsByTagNameNS('*','title')[0].firstChild.nodeValue;}
60625 catch(e){name=doc.getElementsByTagName('title')[0].firstChild.nodeValue;}
60626 if(name){this.setName(name);}}
60627 var options={};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
60628 var format=new OpenLayers.Format.GeoRSS(options);var features=format.read(doc);for(var i=0,len=features.length;i<len;i++){var data={};var feature=features[i];if(!feature.geometry){continue;}
60629 var title=feature.attributes.title?feature.attributes.title:"Untitled";var description=feature.attributes.description?feature.attributes.description:"No description.";var link=feature.attributes.link?feature.attributes.link:"";var location=feature.geometry.getBounds().getCenterLonLat();data.icon=this.icon==null?OpenLayers.Marker.defaultIcon():this.icon.clone();data.popupSize=this.popupSize?this.popupSize.clone():new OpenLayers.Size(250,120);if(title||description){data.title=title;data.description=description;var contentHTML='<div class="olLayerGeoRSSClose">[x]</div>';contentHTML+='<div class="olLayerGeoRSSTitle">';if(link){contentHTML+='<a class="link" href="'+link+'" target="_blank">';}
60630 contentHTML+=title;if(link){contentHTML+='</a>';}
60631 contentHTML+='</div>';contentHTML+='<div style="" class="olLayerGeoRSSDescription">';contentHTML+=description;contentHTML+='</div>';data['popupContentHTML']=contentHTML;}
60632 var feature=new OpenLayers.Feature(this,location,data);this.features.push(feature);var marker=feature.createMarker();marker.events.register('click',feature,this.markerClick);this.addMarker(marker);}
60633 this.events.triggerEvent("loadend");},markerClick:function(evt){var sameMarkerClicked=(this==this.layer.selectedFeature);this.layer.selectedFeature=(!sameMarkerClicked)?this:null;for(var i=0,len=this.layer.map.popups.length;i<len;i++){this.layer.map.removePopup(this.layer.map.popups[i]);}
60634 if(!sameMarkerClicked){var popup=this.createPopup();OpenLayers.Event.observe(popup.div,"click",OpenLayers.Function.bind(function(){for(var i=0,len=this.layer.map.popups.length;i<len;i++){this.layer.map.removePopup(this.layer.map.popups[i]);}},this));this.layer.map.addPopup(popup);}
60635 OpenLayers.Event.stop(evt);},clearFeatures:function(){if(this.features!=null){while(this.features.length>0){var feature=this.features[0];OpenLayers.Util.removeItem(this.features,feature);feature.destroy();}}},CLASS_NAME:"OpenLayers.Layer.GeoRSS"});OpenLayers.Layer.Google=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:0,MAX_ZOOM_LEVEL:21,RESOLUTIONS:[1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125,0.00002145767211914062,0.00001072883605957031,0.00000536441802978515,0.00000268220901489257,0.0000013411045074462891,0.00000067055225372314453],type:null,wrapDateLine:true,sphericalMercator:false,version:null,initialize:function(name,options){options=options||{};if(!options.version){options.version=typeof GMap2==="function"?"2":"3";}
60636 var mixin=OpenLayers.Layer.Google["v"+
60637 options.version.replace(/\./g,"_")];if(mixin){OpenLayers.Util.applyDefaults(options,mixin);}else{throw"Unsupported Google Maps API version: "+options.version;}
60638 OpenLayers.Util.applyDefaults(options,mixin.DEFAULTS);if(options.maxExtent){options.maxExtent=options.maxExtent.clone();}
60639 OpenLayers.Layer.EventPane.prototype.initialize.apply(this,[name,options]);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,[name,options]);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();}},clone:function(){return new OpenLayers.Layer.Google(this.name,this.getOptions());},setVisibility:function(visible){var opacity=this.opacity==null?1:this.opacity;OpenLayers.Layer.EventPane.prototype.setVisibility.apply(this,arguments);this.setOpacity(opacity);},display:function(visible){if(!this._dragging){this.setGMapVisibility(visible);}
60640 OpenLayers.Layer.EventPane.prototype.display.apply(this,arguments);},moveTo:function(bounds,zoomChanged,dragging){this._dragging=dragging;OpenLayers.Layer.EventPane.prototype.moveTo.apply(this,arguments);delete this._dragging;},setOpacity:function(opacity){if(opacity!==this.opacity){if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"opacity"});}
60641 this.opacity=opacity;}
60642 if(this.getVisibility()){var container=this.getMapContainer();OpenLayers.Util.modifyDOMElement(container,null,null,null,null,null,null,opacity);}},destroy:function(){if(this.map){this.setGMapVisibility(false);var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache&&cache.count<=1){this.removeGMapElements();}}
60643 OpenLayers.Layer.EventPane.prototype.destroy.apply(this,arguments);},removeGMapElements:function(){var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){var container=this.mapObject&&this.getMapContainer();if(container&&container.parentNode){container.parentNode.removeChild(container);}
60644 var termsOfUse=cache.termsOfUse;if(termsOfUse&&termsOfUse.parentNode){termsOfUse.parentNode.removeChild(termsOfUse);}
60645 var poweredBy=cache.poweredBy;if(poweredBy&&poweredBy.parentNode){poweredBy.parentNode.removeChild(poweredBy);}}},removeMap:function(map){if(this.visibility&&this.mapObject){this.setGMapVisibility(false);}
60646 var cache=OpenLayers.Layer.Google.cache[map.id];if(cache){if(cache.count<=1){this.removeGMapElements();delete OpenLayers.Layer.Google.cache[map.id];}else{--cache.count;}}
60647 delete this.termsOfUse;delete this.poweredBy;delete this.mapObject;delete this.dragObject;OpenLayers.Layer.EventPane.prototype.removeMap.apply(this,arguments);},getOLBoundsFromMapObjectBounds:function(moBounds){var olBounds=null;if(moBounds!=null){var sw=moBounds.getSouthWest();var ne=moBounds.getNorthEast();if(this.sphericalMercator){sw=this.forwardMercator(sw.lng(),sw.lat());ne=this.forwardMercator(ne.lng(),ne.lat());}else{sw=new OpenLayers.LonLat(sw.lng(),sw.lat());ne=new OpenLayers.LonLat(ne.lng(),ne.lat());}
60648 olBounds=new OpenLayers.Bounds(sw.lon,sw.lat,ne.lon,ne.lat);}
60649 return olBounds;},getWarningHTML:function(){return OpenLayers.i18n("googleWarning");},getMapObjectCenter:function(){return this.mapObject.getCenter();},getMapObjectZoom:function(){return this.mapObject.getZoom();},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.lng(),moLonLat.lat()).lon:moLonLat.lng();},getLatitudeFromMapObjectLonLat:function(moLonLat){var lat=this.sphericalMercator?this.forwardMercator(moLonLat.lng(),moLonLat.lat()).lat:moLonLat.lat();return lat;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},CLASS_NAME:"OpenLayers.Layer.Google"});OpenLayers.Layer.Google.cache={};OpenLayers.Layer.Google.v2={termsOfUse:null,poweredBy:null,dragObject:null,loadMapObject:function(){if(!this.type){this.type=G_NORMAL_MAP;}
60650 var mapObject,termsOfUse,poweredBy;var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){mapObject=cache.mapObject;termsOfUse=cache.termsOfUse;poweredBy=cache.poweredBy;++cache.count;}else{var container=this.map.viewPortDiv;var div=document.createElement("div");div.id=this.map.id+"_GMap2Container";div.style.position="absolute";div.style.width="100%";div.style.height="100%";container.appendChild(div);try{mapObject=new GMap2(div);termsOfUse=div.lastChild;container.appendChild(termsOfUse);termsOfUse.style.zIndex="1100";termsOfUse.style.right="";termsOfUse.style.bottom="";termsOfUse.className="olLayerGoogleCopyright";poweredBy=div.lastChild;container.appendChild(poweredBy);poweredBy.style.zIndex="1100";poweredBy.style.right="";poweredBy.style.bottom="";poweredBy.className="olLayerGooglePoweredBy gmnoprint";}catch(e){throw(e);}
60651 OpenLayers.Layer.Google.cache[this.map.id]={mapObject:mapObject,termsOfUse:termsOfUse,poweredBy:poweredBy,count:1};}
60652 this.mapObject=mapObject;this.termsOfUse=termsOfUse;this.poweredBy=poweredBy;if(OpenLayers.Util.indexOf(this.mapObject.getMapTypes(),this.type)===-1){this.mapObject.addMapType(this.type);}
60653 if(typeof mapObject.getDragObject=="function"){this.dragObject=mapObject.getDragObject();}else{this.dragPanMapObject=null;}
60654 if(this.isBaseLayer===false){this.setGMapVisibility(this.div.style.display!=="none");}},onMapResize:function(){if(this.visibility&&this.mapObject.isLoaded()){this.mapObject.checkResize();}else{if(!this._resized){var layer=this;var handle=GEvent.addListener(this.mapObject,"load",function(){GEvent.removeListener(handle);delete layer._resized;layer.mapObject.checkResize();layer.moveTo(layer.map.getCenter(),layer.map.getZoom());});}
60655 this._resized=true;}},setGMapVisibility:function(visible){var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){var container=this.mapObject.getContainer();if(visible===true){this.mapObject.setMapType(this.type);container.style.display="";this.termsOfUse.style.left="";this.termsOfUse.style.display="";this.poweredBy.style.display="";cache.displayed=this.id;}else{if(cache.displayed===this.id){delete cache.displayed;}
60656 if(!cache.displayed){container.style.display="none";this.termsOfUse.style.display="none";this.termsOfUse.style.left="-9999px";this.poweredBy.style.display="none";}}}},getMapContainer:function(){return this.mapObject.getContainer();},getMapObjectBoundsFromOLBounds:function(olBounds){var moBounds=null;if(olBounds!=null){var sw=this.sphericalMercator?this.inverseMercator(olBounds.bottom,olBounds.left):new OpenLayers.LonLat(olBounds.bottom,olBounds.left);var ne=this.sphericalMercator?this.inverseMercator(olBounds.top,olBounds.right):new OpenLayers.LonLat(olBounds.top,olBounds.right);moBounds=new GLatLngBounds(new GLatLng(sw.lat,sw.lon),new GLatLng(ne.lat,ne.lon));}
60657 return moBounds;},setMapObjectCenter:function(center,zoom){this.mapObject.setCenter(center,zoom);},dragPanMapObject:function(dX,dY){this.dragObject.moveBy(new GSize(-dX,dY));},getMapObjectLonLatFromMapObjectPixel:function(moPixel){return this.mapObject.fromContainerPixelToLatLng(moPixel);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.fromLatLngToContainerPixel(moLonLat);},getMapObjectZoomFromMapObjectBounds:function(moBounds){return this.mapObject.getBoundsZoomLevel(moBounds);},getMapObjectLonLatFromLonLat:function(lon,lat){var gLatLng;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);gLatLng=new GLatLng(lonlat.lat,lonlat.lon);}else{gLatLng=new GLatLng(lat,lon);}
60658 return gLatLng;},getMapObjectPixelFromXY:function(x,y){return new GPoint(x,y);}};OpenLayers.Layer.Grid=OpenLayers.Class(OpenLayers.Layer.HTTPRequest,{tileSize:null,grid:null,singleTile:false,ratio:1.5,buffer:2,numLoadingTiles:0,initialize:function(name,url,params,options){OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,arguments);this.events.addEventType("tileloaded");this.grid=[];},destroy:function(){this.clearGrid();this.grid=null;this.tileSize=null;OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this,arguments);},clearGrid:function(){if(this.grid){for(var iRow=0,len=this.grid.length;iRow<len;iRow++){var row=this.grid[iRow];for(var iCol=0,clen=row.length;iCol<clen;iCol++){var tile=row[iCol];this.removeTileMonitoringHooks(tile);tile.destroy();}}
60659 this.grid=[];}},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Grid(this.name,this.url,this.params,this.getOptions());}
60660 obj=OpenLayers.Layer.HTTPRequest.prototype.clone.apply(this,[obj]);if(this.tileSize!=null){obj.tileSize=this.tileSize.clone();}
60661 obj.grid=[];return obj;},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.HTTPRequest.prototype.moveTo.apply(this,arguments);bounds=bounds||this.map.getExtent();if(bounds!=null){var forceReTile=!this.grid.length||zoomChanged;var tilesBounds=this.getTilesBounds();if(this.singleTile){if(forceReTile||(!dragging&&!tilesBounds.containsBounds(bounds))){this.initSingleTile(bounds);}}else{if(forceReTile||!tilesBounds.containsBounds(bounds,true)){this.initGriddedTiles(bounds);}else{this.moveGriddedTiles(bounds);}}}},setTileSize:function(size){if(this.singleTile){size=this.map.getSize();size.h=parseInt(size.h*this.ratio);size.w=parseInt(size.w*this.ratio);}
60662 OpenLayers.Layer.HTTPRequest.prototype.setTileSize.apply(this,[size]);},getGridBounds:function(){var msg="The getGridBounds() function is deprecated. It will be "+"removed in 3.0. Please use getTilesBounds() instead.";OpenLayers.Console.warn(msg);return this.getTilesBounds();},getTilesBounds:function(){var bounds=null;if(this.grid.length){var bottom=this.grid.length-1;var bottomLeftTile=this.grid[bottom][0];var right=this.grid[0].length-1;var topRightTile=this.grid[0][right];bounds=new OpenLayers.Bounds(bottomLeftTile.bounds.left,bottomLeftTile.bounds.bottom,topRightTile.bounds.right,topRightTile.bounds.top);}
60663 return bounds;},initSingleTile:function(bounds){var center=bounds.getCenterLonLat();var tileWidth=bounds.getWidth()*this.ratio;var tileHeight=bounds.getHeight()*this.ratio;var tileBounds=new OpenLayers.Bounds(center.lon-(tileWidth/2),center.lat-(tileHeight/2),center.lon+(tileWidth/2),center.lat+(tileHeight/2));var ul=new OpenLayers.LonLat(tileBounds.left,tileBounds.top);var px=this.map.getLayerPxFromLonLat(ul);if(!this.grid.length){this.grid[0]=[];}
60664 var tile=this.grid[0][0];if(!tile){tile=this.addTile(tileBounds,px);this.addTileMonitoringHooks(tile);tile.draw();this.grid[0][0]=tile;}else{tile.moveTo(tileBounds,px);}
60665 this.removeExcessTiles(1,1);},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left-extent.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=extent.left+tilecol*tilelon;var offsetlat=bounds.top-(extent.bottom+tilelat);var tilerow=Math.ceil(offsetlat/tilelat)+this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=-tilerowremain*this.tileSize.h;var tileoffsetlat=extent.bottom+tilerow*tilelat;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},initGriddedTiles:function(bounds){var viewSize=this.map.getSize();var minRows=Math.ceil(viewSize.h/this.tileSize.h)+
60666 Math.max(1,2*this.buffer);var minCols=Math.ceil(viewSize.w/this.tileSize.w)+
60667 Math.max(1,2*this.buffer);var extent=this.getMaxExtent();var resolution=this.map.getResolution();var tileLayout=this.calculateGridLayout(bounds,extent,resolution);var tileoffsetx=Math.round(tileLayout.tileoffsetx);var tileoffsety=Math.round(tileLayout.tileoffsety);var tileoffsetlon=tileLayout.tileoffsetlon;var tileoffsetlat=tileLayout.tileoffsetlat;var tilelon=tileLayout.tilelon;var tilelat=tileLayout.tilelat;this.origin=new OpenLayers.Pixel(tileoffsetx,tileoffsety);var startX=tileoffsetx;var startLon=tileoffsetlon;var rowidx=0;var layerContainerDivLeft=parseInt(this.map.layerContainerDiv.style.left);var layerContainerDivTop=parseInt(this.map.layerContainerDiv.style.top);do{var row=this.grid[rowidx++];if(!row){row=[];this.grid.push(row);}
60668 tileoffsetlon=startLon;tileoffsetx=startX;var colidx=0;do{var tileBounds=new OpenLayers.Bounds(tileoffsetlon,tileoffsetlat,tileoffsetlon+tilelon,tileoffsetlat+tilelat);var x=tileoffsetx;x-=layerContainerDivLeft;var y=tileoffsety;y-=layerContainerDivTop;var px=new OpenLayers.Pixel(x,y);var tile=row[colidx++];if(!tile){tile=this.addTile(tileBounds,px);this.addTileMonitoringHooks(tile);row.push(tile);}else{tile.moveTo(tileBounds,px,false);}
60669 tileoffsetlon+=tilelon;tileoffsetx+=this.tileSize.w;}while((tileoffsetlon<=bounds.right+tilelon*this.buffer)||colidx<minCols);tileoffsetlat-=tilelat;tileoffsety+=this.tileSize.h;}while((tileoffsetlat>=bounds.bottom-tilelat*this.buffer)||rowidx<minRows);this.removeExcessTiles(rowidx,colidx);this.spiralTileLoad();},getMaxExtent:function(){return this.maxExtent;},spiralTileLoad:function(){var tileQueue=[];var directions=["right","down","left","up"];var iRow=0;var iCell=-1;var direction=OpenLayers.Util.indexOf(directions,"right");var directionsTried=0;while(directionsTried<directions.length){var testRow=iRow;var testCell=iCell;switch(directions[direction]){case"right":testCell++;break;case"down":testRow++;break;case"left":testCell--;break;case"up":testRow--;break;}
60670 var tile=null;if((testRow<this.grid.length)&&(testRow>=0)&&(testCell<this.grid[0].length)&&(testCell>=0)){tile=this.grid[testRow][testCell];}
60671 if((tile!=null)&&(!tile.queued)){tileQueue.unshift(tile);tile.queued=true;directionsTried=0;iRow=testRow;iCell=testCell;}else{direction=(direction+1)%4;directionsTried++;}}
60672 for(var i=0,len=tileQueue.length;i<len;i++){var tile=tileQueue[i];tile.draw();tile.queued=false;}},addTile:function(bounds,position){},addTileMonitoringHooks:function(tile){tile.onLoadStart=function(){if(this.numLoadingTiles==0){this.events.triggerEvent("loadstart");}
60673 this.numLoadingTiles++;};tile.events.register("loadstart",this,tile.onLoadStart);tile.onLoadEnd=function(){this.numLoadingTiles--;this.events.triggerEvent("tileloaded");if(this.numLoadingTiles==0){this.events.triggerEvent("loadend");}};tile.events.register("loadend",this,tile.onLoadEnd);tile.events.register("unload",this,tile.onLoadEnd);},removeTileMonitoringHooks:function(tile){tile.unload();tile.events.un({"loadstart":tile.onLoadStart,"loadend":tile.onLoadEnd,"unload":tile.onLoadEnd,scope:this});},moveGriddedTiles:function(bounds){var buffer=this.buffer||1;while(true){var tlLayer=this.grid[0][0].position;var tlViewPort=this.map.getViewPortPxFromLayerPx(tlLayer);if(tlViewPort.x>-this.tileSize.w*(buffer-1)){this.shiftColumn(true);}else if(tlViewPort.x<-this.tileSize.w*buffer){this.shiftColumn(false);}else if(tlViewPort.y>-this.tileSize.h*(buffer-1)){this.shiftRow(true);}else if(tlViewPort.y<-this.tileSize.h*buffer){this.shiftRow(false);}else{break;}};},shiftRow:function(prepend){var modelRowIndex=(prepend)?0:(this.grid.length-1);var grid=this.grid;var modelRow=grid[modelRowIndex];var resolution=this.map.getResolution();var deltaY=(prepend)?-this.tileSize.h:this.tileSize.h;var deltaLat=resolution*-deltaY;var row=(prepend)?grid.pop():grid.shift();for(var i=0,len=modelRow.length;i<len;i++){var modelTile=modelRow[i];var bounds=modelTile.bounds.clone();var position=modelTile.position.clone();bounds.bottom=bounds.bottom+deltaLat;bounds.top=bounds.top+deltaLat;position.y=position.y+deltaY;row[i].moveTo(bounds,position);}
60674 if(prepend){grid.unshift(row);}else{grid.push(row);}},shiftColumn:function(prepend){var deltaX=(prepend)?-this.tileSize.w:this.tileSize.w;var resolution=this.map.getResolution();var deltaLon=resolution*deltaX;for(var i=0,len=this.grid.length;i<len;i++){var row=this.grid[i];var modelTileIndex=(prepend)?0:(row.length-1);var modelTile=row[modelTileIndex];var bounds=modelTile.bounds.clone();var position=modelTile.position.clone();bounds.left=bounds.left+deltaLon;bounds.right=bounds.right+deltaLon;position.x=position.x+deltaX;var tile=prepend?this.grid[i].pop():this.grid[i].shift();tile.moveTo(bounds,position);if(prepend){row.unshift(tile);}else{row.push(tile);}}},removeExcessTiles:function(rows,columns){while(this.grid.length>rows){var row=this.grid.pop();for(var i=0,l=row.length;i<l;i++){var tile=row[i];this.removeTileMonitoringHooks(tile);tile.destroy();}}
60675 while(this.grid[0].length>columns){for(var i=0,l=this.grid.length;i<l;i++){var row=this.grid[i];var tile=row.pop();this.removeTileMonitoringHooks(tile);tile.destroy();}}},onMapResize:function(){if(this.singleTile){this.clearGrid();this.setTileSize();}},getTileBounds:function(viewPortPx){var maxExtent=this.maxExtent;var resolution=this.getResolution();var tileMapWidth=resolution*this.tileSize.w;var tileMapHeight=resolution*this.tileSize.h;var mapPoint=this.getLonLatFromViewPortPx(viewPortPx);var tileLeft=maxExtent.left+(tileMapWidth*Math.floor((mapPoint.lon-
60676 maxExtent.left)/tileMapWidth));var tileBottom=maxExtent.bottom+(tileMapHeight*Math.floor((mapPoint.lat-
60677 maxExtent.bottom)/tileMapHeight));return new OpenLayers.Bounds(tileLeft,tileBottom,tileLeft+tileMapWidth,tileBottom+tileMapHeight);},CLASS_NAME:"OpenLayers.Layer.Grid"});OpenLayers.Layer.MultiMap=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:1,MAX_ZOOM_LEVEL:17,RESOLUTIONS:[9,1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125],type:null,initialize:function(name,options){OpenLayers.Layer.EventPane.prototype.initialize.apply(this,arguments);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,arguments);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();this.RESOLUTIONS.unshift(10);}},loadMapObject:function(){try{this.mapObject=new MultimapViewer(this.div);}catch(e){}},getWarningHTML:function(){return OpenLayers.i18n("getLayerWarning",{'layerType':"MM",'layerLib':"MultiMap"});},setMapObjectCenter:function(center,zoom){this.mapObject.goToPosition(center,zoom);},getMapObjectCenter:function(){return this.mapObject.getCurrentPosition();},getMapObjectZoom:function(){return this.mapObject.getZoomFactor();},getMapObjectLonLatFromMapObjectPixel:function(moPixel){moPixel.x=moPixel.x-(this.map.getSize().w/2);moPixel.y=moPixel.y-(this.map.getSize().h/2);return this.mapObject.getMapPositionAt(moPixel);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.geoPosToContainerPixels(moLonLat);},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.lon,moLonLat.lat).lon:moLonLat.lon;},getLatitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.lon,moLonLat.lat).lat:moLonLat.lat;},getMapObjectLonLatFromLonLat:function(lon,lat){var mmLatLon;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);mmLatLon=new MMLatLon(lonlat.lat,lonlat.lon);}else{mmLatLon=new MMLatLon(lat,lon);}
60678 return mmLatLon;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},getMapObjectPixelFromXY:function(x,y){return new MMPoint(x,y);},CLASS_NAME:"OpenLayers.Layer.MultiMap"});OpenLayers.Layer.VirtualEarth=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:1,MAX_ZOOM_LEVEL:19,RESOLUTIONS:[1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125,0.00002145767211914062,0.00001072883605957031,0.00000536441802978515],type:null,wrapDateLine:true,sphericalMercator:false,animationEnabled:true,initialize:function(name,options){OpenLayers.Layer.EventPane.prototype.initialize.apply(this,arguments);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,arguments);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();}},loadMapObject:function(){var veDiv=OpenLayers.Util.createDiv(this.name);var sz=this.map.getSize();veDiv.style.width=sz.w+"px";veDiv.style.height=sz.h+"px";this.div.appendChild(veDiv);try{this.mapObject=new VEMap(this.name);}catch(e){}
60679 if(this.mapObject!=null){try{this.mapObject.LoadMap(null,null,this.type,true);this.mapObject.AttachEvent("onmousedown",OpenLayers.Function.True);}catch(e){}
60680 this.mapObject.HideDashboard();if(typeof this.mapObject.SetAnimationEnabled=="function"){this.mapObject.SetAnimationEnabled(this.animationEnabled);}}
60681 if(!this.mapObject||!this.mapObject.vemapcontrol||!this.mapObject.vemapcontrol.PanMap||(typeof this.mapObject.vemapcontrol.PanMap!="function")){this.dragPanMapObject=null;}},onMapResize:function(){this.mapObject.Resize(this.map.size.w,this.map.size.h);},getWarningHTML:function(){return OpenLayers.i18n("getLayerWarning",{'layerType':'VE','layerLib':'VirtualEarth'});},setMapObjectCenter:function(center,zoom){this.mapObject.SetCenterAndZoom(center,zoom);},getMapObjectCenter:function(){return this.mapObject.GetCenter();},dragPanMapObject:function(dX,dY){this.mapObject.vemapcontrol.PanMap(dX,-dY);},getMapObjectZoom:function(){return this.mapObject.GetZoomLevel();},getMapObjectLonLatFromMapObjectPixel:function(moPixel){return(typeof VEPixel!='undefined')?this.mapObject.PixelToLatLong(moPixel):this.mapObject.PixelToLatLong(moPixel.x,moPixel.y);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.LatLongToPixel(moLonLat);},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Longitude,moLonLat.Latitude).lon:moLonLat.Longitude;},getLatitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Longitude,moLonLat.Latitude).lat:moLonLat.Latitude;},getMapObjectLonLatFromLonLat:function(lon,lat){var veLatLong;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);veLatLong=new VELatLong(lonlat.lat,lonlat.lon);}else{veLatLong=new VELatLong(lat,lon);}
60682 return veLatLong;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},getMapObjectPixelFromXY:function(x,y){return(typeof VEPixel!='undefined')?new VEPixel(x,y):new Msn.VE.Pixel(x,y);},CLASS_NAME:"OpenLayers.Layer.VirtualEarth"});OpenLayers.Layer.Yahoo=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:0,MAX_ZOOM_LEVEL:17,RESOLUTIONS:[1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125,0.00002145767211914062,0.00001072883605957031],type:null,wrapDateLine:true,sphericalMercator:false,initialize:function(name,options){OpenLayers.Layer.EventPane.prototype.initialize.apply(this,arguments);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,arguments);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();}},loadMapObject:function(){try{var size=this.getMapObjectSizeFromOLSize(this.map.getSize());this.mapObject=new YMap(this.div,this.type,size);this.mapObject.disableKeyControls();this.mapObject.disableDragMap();if(!this.mapObject.moveByXY||(typeof this.mapObject.moveByXY!="function")){this.dragPanMapObject=null;}}catch(e){}},onMapResize:function(){try{var size=this.getMapObjectSizeFromOLSize(this.map.getSize());this.mapObject.resizeTo(size);}catch(e){}},setMap:function(map){OpenLayers.Layer.EventPane.prototype.setMap.apply(this,arguments);this.map.events.register("moveend",this,this.fixYahooEventPane);},fixYahooEventPane:function(){var yahooEventPane=OpenLayers.Util.getElement("ygddfdiv");if(yahooEventPane!=null){if(yahooEventPane.parentNode!=null){yahooEventPane.parentNode.removeChild(yahooEventPane);}
60683 this.map.events.unregister("moveend",this,this.fixYahooEventPane);}},getWarningHTML:function(){return OpenLayers.i18n("getLayerWarning",{'layerType':'Yahoo','layerLib':'Yahoo'});},getOLZoomFromMapObjectZoom:function(moZoom){var zoom=null;if(moZoom!=null){zoom=OpenLayers.Layer.FixedZoomLevels.prototype.getOLZoomFromMapObjectZoom.apply(this,[moZoom]);zoom=18-zoom;}
60684 return zoom;},getMapObjectZoomFromOLZoom:function(olZoom){var zoom=null;if(olZoom!=null){zoom=OpenLayers.Layer.FixedZoomLevels.prototype.getMapObjectZoomFromOLZoom.apply(this,[olZoom]);zoom=18-zoom;}
60685 return zoom;},setMapObjectCenter:function(center,zoom){this.mapObject.drawZoomAndCenter(center,zoom);},getMapObjectCenter:function(){return this.mapObject.getCenterLatLon();},dragPanMapObject:function(dX,dY){this.mapObject.moveByXY({'x':-dX,'y':dY});},getMapObjectZoom:function(){return this.mapObject.getZoomLevel();},getMapObjectLonLatFromMapObjectPixel:function(moPixel){return this.mapObject.convertXYLatLon(moPixel);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.convertLatLonXY(moLonLat);},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Lon,moLonLat.Lat).lon:moLonLat.Lon;},getLatitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Lon,moLonLat.Lat).lat:moLonLat.Lat;},getMapObjectLonLatFromLonLat:function(lon,lat){var yLatLong;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);yLatLong=new YGeoPoint(lonlat.lat,lonlat.lon);}else{yLatLong=new YGeoPoint(lat,lon);}
60686 return yLatLong;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},getMapObjectPixelFromXY:function(x,y){return new YCoordPoint(x,y);},getMapObjectSizeFromOLSize:function(olSize){return new YSize(olSize.w,olSize.h);},CLASS_NAME:"OpenLayers.Layer.Yahoo"});OpenLayers.Style=OpenLayers.Class({id:null,name:null,title:null,description:null,layerName:null,isDefault:false,rules:null,context:null,defaultStyle:null,defaultsPerSymbolizer:false,propertyStyles:null,initialize:function(style,options){OpenLayers.Util.extend(this,options);this.rules=[];if(options&&options.rules){this.addRules(options.rules);}
60687 this.setDefaultStyle(style||OpenLayers.Feature.Vector.style["default"]);this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){for(var i=0,len=this.rules.length;i<len;i++){this.rules[i].destroy();this.rules[i]=null;}
60688 this.rules=null;this.defaultStyle=null;},createSymbolizer:function(feature){var style=this.defaultsPerSymbolizer?{}:this.createLiterals(OpenLayers.Util.extend({},this.defaultStyle),feature);var rules=this.rules;var rule,context;var elseRules=[];var appliedRules=false;for(var i=0,len=rules.length;i<len;i++){rule=rules[i];var applies=rule.evaluate(feature);if(applies){if(rule instanceof OpenLayers.Rule&&rule.elseFilter){elseRules.push(rule);}else{appliedRules=true;this.applySymbolizer(rule,style,feature);}}}
60689 if(appliedRules==false&&elseRules.length>0){appliedRules=true;for(var i=0,len=elseRules.length;i<len;i++){this.applySymbolizer(elseRules[i],style,feature);}}
60690 if(rules.length>0&&appliedRules==false){style.display="none";}
60691 return style;},applySymbolizer:function(rule,style,feature){var symbolizerPrefix=feature.geometry?this.getSymbolizerPrefix(feature.geometry):OpenLayers.Style.SYMBOLIZER_PREFIXES[0];var symbolizer=rule.symbolizer[symbolizerPrefix]||rule.symbolizer;if(this.defaultsPerSymbolizer===true){var defaults=this.defaultStyle;OpenLayers.Util.applyDefaults(symbolizer,{pointRadius:defaults.pointRadius});if(symbolizer.stroke===true||symbolizer.graphic===true){OpenLayers.Util.applyDefaults(symbolizer,{strokeWidth:defaults.strokeWidth,strokeColor:defaults.strokeColor,strokeOpacity:defaults.strokeOpacity,strokeDashstyle:defaults.strokeDashstyle,strokeLinecap:defaults.strokeLinecap});}
60692 if(symbolizer.fill===true||symbolizer.graphic===true){OpenLayers.Util.applyDefaults(symbolizer,{fillColor:defaults.fillColor,fillOpacity:defaults.fillOpacity});}
60693 if(symbolizer.graphic===true){OpenLayers.Util.applyDefaults(symbolizer,{pointRadius:this.defaultStyle.pointRadius,externalGraphic:this.defaultStyle.externalGraphic,graphicName:this.defaultStyle.graphicName,graphicOpacity:this.defaultStyle.graphicOpacity,graphicWidth:this.defaultStyle.graphicWidth,graphicHeight:this.defaultStyle.graphicHeight,graphicXOffset:this.defaultStyle.graphicXOffset,graphicYOffset:this.defaultStyle.graphicYOffset});}}
60694 return this.createLiterals(OpenLayers.Util.extend(style,symbolizer),feature);},createLiterals:function(style,feature){var context=OpenLayers.Util.extend({},feature.attributes||feature.data);OpenLayers.Util.extend(context,this.context);for(var i in this.propertyStyles){style[i]=OpenLayers.Style.createLiteral(style[i],context,feature,i);}
60695 return style;},findPropertyStyles:function(){var propertyStyles={};var style=this.defaultStyle;this.addPropertyStyles(propertyStyles,style);var rules=this.rules;var symbolizer,value;for(var i=0,len=rules.length;i<len;i++){symbolizer=rules[i].symbolizer;for(var key in symbolizer){value=symbolizer[key];if(typeof value=="object"){this.addPropertyStyles(propertyStyles,value);}else{this.addPropertyStyles(propertyStyles,symbolizer);break;}}}
60696 return propertyStyles;},addPropertyStyles:function(propertyStyles,symbolizer){var property;for(var key in symbolizer){property=symbolizer[key];if(typeof property=="string"&&property.match(/\$\{\w+\}/)){propertyStyles[key]=true;}}
60697 return propertyStyles;},addRules:function(rules){Array.prototype.push.apply(this.rules,rules);this.propertyStyles=this.findPropertyStyles();},setDefaultStyle:function(style){this.defaultStyle=style;this.propertyStyles=this.findPropertyStyles();},getSymbolizerPrefix:function(geometry){var prefixes=OpenLayers.Style.SYMBOLIZER_PREFIXES;for(var i=0,len=prefixes.length;i<len;i++){if(geometry.CLASS_NAME.indexOf(prefixes[i])!=-1){return prefixes[i];}}},clone:function(){var options=OpenLayers.Util.extend({},this);if(this.rules){options.rules=[];for(var i=0,len=this.rules.length;i<len;++i){options.rules.push(this.rules[i].clone());}}
60698 options.context=this.context&&OpenLayers.Util.extend({},this.context);var defaultStyle=OpenLayers.Util.extend({},this.defaultStyle);return new OpenLayers.Style(defaultStyle,options);},CLASS_NAME:"OpenLayers.Style"});OpenLayers.Style.createLiteral=function(value,context,feature,property){if(typeof value=="string"&&value.indexOf("${")!=-1){value=OpenLayers.String.format(value,context,[feature,property]);value=(isNaN(value)||!value)?value:parseFloat(value);}
60699 return value;};OpenLayers.Style.SYMBOLIZER_PREFIXES=['Point','Line','Polygon','Text','Raster'];OpenLayers.Control.Navigation=OpenLayers.Class(OpenLayers.Control,{dragPan:null,dragPanOptions:null,documentDrag:false,zoomBox:null,zoomBoxEnabled:true,zoomWheelEnabled:true,mouseWheelOptions:null,handleRightClicks:false,zoomBoxKeyMask:OpenLayers.Handler.MOD_SHIFT,autoActivate:true,initialize:function(options){this.handlers={};OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){this.deactivate();if(this.dragPan){this.dragPan.destroy();}
60700 this.dragPan=null;if(this.zoomBox){this.zoomBox.destroy();}
60701 this.zoomBox=null;OpenLayers.Control.prototype.destroy.apply(this,arguments);},activate:function(){this.dragPan.activate();if(this.zoomWheelEnabled){this.handlers.wheel.activate();}
60702 this.handlers.click.activate();if(this.zoomBoxEnabled){this.zoomBox.activate();}
60703 return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){this.zoomBox.deactivate();this.dragPan.deactivate();this.handlers.click.deactivate();this.handlers.wheel.deactivate();return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},draw:function(){if(this.handleRightClicks){this.map.viewPortDiv.oncontextmenu=OpenLayers.Function.False;}
60704 var clickCallbacks={'dblclick':this.defaultDblClick,'dblrightclick':this.defaultDblRightClick};var clickOptions={'double':true,'stopDouble':true};this.handlers.click=new OpenLayers.Handler.Click(this,clickCallbacks,clickOptions);this.dragPan=new OpenLayers.Control.DragPan(OpenLayers.Util.extend({map:this.map,documentDrag:this.documentDrag},this.dragPanOptions));this.zoomBox=new OpenLayers.Control.ZoomBox({map:this.map,keyMask:this.zoomBoxKeyMask});this.dragPan.draw();this.zoomBox.draw();this.handlers.wheel=new OpenLayers.Handler.MouseWheel(this,{"up":this.wheelUp,"down":this.wheelDown},this.mouseWheelOptions);},defaultDblClick:function(evt){var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom+1);},defaultDblRightClick:function(evt){var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom-1);},wheelChange:function(evt,deltaZ){var currentZoom=this.map.getZoom();var newZoom=this.map.getZoom()+Math.round(deltaZ);newZoom=Math.max(newZoom,0);newZoom=Math.min(newZoom,this.map.getNumZoomLevels());if(newZoom===currentZoom){return;}
60705 var size=this.map.getSize();var deltaX=size.w/2-evt.xy.x;var deltaY=evt.xy.y-size.h/2;var newRes=this.map.baseLayer.getResolutionForZoom(newZoom);var zoomPoint=this.map.getLonLatFromPixel(evt.xy);var newCenter=new OpenLayers.LonLat(zoomPoint.lon+deltaX*newRes,zoomPoint.lat+deltaY*newRes);this.map.setCenter(newCenter,newZoom);},wheelUp:function(evt,delta){this.wheelChange(evt,delta||1);},wheelDown:function(evt,delta){this.wheelChange(evt,delta||-1);},disableZoomBox:function(){this.zoomBoxEnabled=false;this.zoomBox.deactivate();},enableZoomBox:function(){this.zoomBoxEnabled=true;if(this.active){this.zoomBox.activate();}},disableZoomWheel:function(){this.zoomWheelEnabled=false;this.handlers.wheel.deactivate();},enableZoomWheel:function(){this.zoomWheelEnabled=true;if(this.active){this.handlers.wheel.activate();}},CLASS_NAME:"OpenLayers.Control.Navigation"});OpenLayers.Filter=OpenLayers.Class({initialize:function(options){OpenLayers.Util.extend(this,options);},destroy:function(){},evaluate:function(context){return true;},clone:function(){return null;},CLASS_NAME:"OpenLayers.Filter"});OpenLayers.Format.WMC.v1_0_0=OpenLayers.Class(OpenLayers.Format.WMC.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/context http://schemas.opengis.net/context/1.0.0/context.xsd",initialize:function(options){OpenLayers.Format.WMC.v1.prototype.initialize.apply(this,[options]);},write_wmc_Layer:function(context){var node=OpenLayers.Format.WMC.v1.prototype.write_wmc_Layer.apply(this,[context]);node.appendChild(this.write_wmc_FormatList(context));node.appendChild(this.write_wmc_StyleList(context));node.appendChild(this.write_wmc_LayerExtension(context));},CLASS_NAME:"OpenLayers.Format.WMC.v1_0_0"});OpenLayers.Format.WMC.v1_1_0=OpenLayers.Class(OpenLayers.Format.WMC.v1,{VERSION:"1.1.0",schemaLocation:"http://www.opengis.net/context http://schemas.opengis.net/context/1.1.0/context.xsd",initialize:function(options){OpenLayers.Format.WMC.v1.prototype.initialize.apply(this,[options]);},read_sld_MinScaleDenominator:function(layerContext,node){var minScaleDenominator=parseFloat(this.getChildValue(node));if(minScaleDenominator>0){layerContext.maxScale=minScaleDenominator;}},read_sld_MaxScaleDenominator:function(layerContext,node){layerContext.minScale=parseFloat(this.getChildValue(node));},write_wmc_Layer:function(context){var node=OpenLayers.Format.WMC.v1.prototype.write_wmc_Layer.apply(this,[context]);if(context.maxScale){var minSD=this.createElementNS(this.namespaces.sld,"sld:MinScaleDenominator");minSD.appendChild(this.createTextNode(context.maxScale.toPrecision(16)));node.appendChild(minSD);}
60706 if(context.minScale){var maxSD=this.createElementNS(this.namespaces.sld,"sld:MaxScaleDenominator");maxSD.appendChild(this.createTextNode(context.minScale.toPrecision(16)));node.appendChild(maxSD);}
60707 node.appendChild(this.write_wmc_FormatList(context));node.appendChild(this.write_wmc_StyleList(context));node.appendChild(this.write_wmc_LayerExtension(context));return node;},CLASS_NAME:"OpenLayers.Format.WMC.v1_1_0"});OpenLayers.Format.WMSCapabilities.v1_1_0=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_1,{version:"1.1.0",initialize:function(options){OpenLayers.Format.WMSCapabilities.v1_1.prototype.initialize.apply(this,[options]);},readers:{"wms":OpenLayers.Util.applyDefaults({"SRS":function(node,obj){var srs=this.getChildValue(node);var values=srs.split(/ +/);for(var i=0,len=values.length;i<len;i++){obj.srs[values[i]]=true;}}},OpenLayers.Format.WMSCapabilities.v1_1.prototype.readers["wms"])},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1_0"});OpenLayers.Format.WMSCapabilities.v1_1_1=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_1,{version:"1.1.1",initialize:function(options){OpenLayers.Format.WMSCapabilities.v1_1.prototype.initialize.apply(this,[options]);},readers:{"wms":OpenLayers.Util.applyDefaults({"SRS":function(node,obj){obj.srs[this.getChildValue(node)]=true;}},OpenLayers.Format.WMSCapabilities.v1_1.prototype.readers["wms"])},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1_1"});OpenLayers.Format.WMSCapabilities.v1_3_0=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_3,{version:"1.3.0",CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_3_0"});OpenLayers.Geometry=OpenLayers.Class({id:null,parent:null,bounds:null,initialize:function(){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){this.id=null;this.bounds=null;},clone:function(){return new OpenLayers.Geometry();},setBounds:function(bounds){if(bounds){this.bounds=bounds.clone();}},clearBounds:function(){this.bounds=null;if(this.parent){this.parent.clearBounds();}},extendBounds:function(newBounds){var bounds=this.getBounds();if(!bounds){this.setBounds(newBounds);}else{this.bounds.extend(newBounds);}},getBounds:function(){if(this.bounds==null){this.calculateBounds();}
60708 return this.bounds;},calculateBounds:function(){},distanceTo:function(geometry,options){},getVertices:function(nodes){},atPoint:function(lonlat,toleranceLon,toleranceLat){var atPoint=false;var bounds=this.getBounds();if((bounds!=null)&&(lonlat!=null)){var dX=(toleranceLon!=null)?toleranceLon:0;var dY=(toleranceLat!=null)?toleranceLat:0;var toleranceBounds=new OpenLayers.Bounds(this.bounds.left-dX,this.bounds.bottom-dY,this.bounds.right+dX,this.bounds.top+dY);atPoint=toleranceBounds.containsLonLat(lonlat);}
60709 return atPoint;},getLength:function(){return 0.0;},getArea:function(){return 0.0;},getCentroid:function(){return null;},toString:function(){return OpenLayers.Format.WKT.prototype.write(new OpenLayers.Feature.Vector(this));},CLASS_NAME:"OpenLayers.Geometry"});OpenLayers.Geometry.fromWKT=function(wkt){var format=arguments.callee.format;if(!format){format=new OpenLayers.Format.WKT();arguments.callee.format=format;}
60710 var geom;var result=format.read(wkt);if(result instanceof OpenLayers.Feature.Vector){geom=result.geometry;}else if(result instanceof Array){var len=result.length;var components=new Array(len);for(var i=0;i<len;++i){components[i]=result[i].geometry;}
60711 geom=new OpenLayers.Geometry.Collection(components);}
60712 return geom;};OpenLayers.Geometry.segmentsIntersect=function(seg1,seg2,options){var point=options&&options.point;var tolerance=options&&options.tolerance;var intersection=false;var x11_21=seg1.x1-seg2.x1;var y11_21=seg1.y1-seg2.y1;var x12_11=seg1.x2-seg1.x1;var y12_11=seg1.y2-seg1.y1;var y22_21=seg2.y2-seg2.y1;var x22_21=seg2.x2-seg2.x1;var d=(y22_21*x12_11)-(x22_21*y12_11);var n1=(x22_21*y11_21)-(y22_21*x11_21);var n2=(x12_11*y11_21)-(y12_11*x11_21);if(d==0){if(n1==0&&n2==0){intersection=true;}}else{var along1=n1/d;var along2=n2/d;if(along1>=0&&along1<=1&&along2>=0&&along2<=1){if(!point){intersection=true;}else{var x=seg1.x1+(along1*x12_11);var y=seg1.y1+(along1*y12_11);intersection=new OpenLayers.Geometry.Point(x,y);}}}
60713 if(tolerance){var dist;if(intersection){if(point){var segs=[seg1,seg2];var seg,x,y;outer:for(var i=0;i<2;++i){seg=segs[i];for(var j=1;j<3;++j){x=seg["x"+j];y=seg["y"+j];dist=Math.sqrt(Math.pow(x-intersection.x,2)+
60714 Math.pow(y-intersection.y,2));if(dist<tolerance){intersection.x=x;intersection.y=y;break outer;}}}}}else{var segs=[seg1,seg2];var source,target,x,y,p,result;outer:for(var i=0;i<2;++i){source=segs[i];target=segs[(i+1)%2];for(var j=1;j<3;++j){p={x:source["x"+j],y:source["y"+j]};result=OpenLayers.Geometry.distanceToSegment(p,target);if(result.distance<tolerance){if(point){intersection=new OpenLayers.Geometry.Point(p.x,p.y);}else{intersection=true;}
60715 break outer;}}}}}
60716 return intersection;};OpenLayers.Geometry.distanceToSegment=function(point,segment){var x0=point.x;var y0=point.y;var x1=segment.x1;var y1=segment.y1;var x2=segment.x2;var y2=segment.y2;var dx=x2-x1;var dy=y2-y1;var along=((dx*(x0-x1))+(dy*(y0-y1)))/(Math.pow(dx,2)+Math.pow(dy,2));var x,y;if(along<=0.0){x=x1;y=y1;}else if(along>=1.0){x=x2;y=y2;}else{x=x1+along*dx;y=y1+along*dy;}
60717 return{distance:Math.sqrt(Math.pow(x-x0,2)+Math.pow(y-y0,2)),x:x,y:y};};OpenLayers.Layer.ArcGIS93Rest=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{format:"png"},isBaseLayer:true,initialize:function(name,url,params,options){var newArguments=[];params=OpenLayers.Util.upperCaseObject(params);newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);OpenLayers.Util.applyDefaults(this.params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS));if(this.params.TRANSPARENT&&this.params.TRANSPARENT.toString().toLowerCase()=="true"){if((options==null)||(!options.isBaseLayer)){this.isBaseLayer=false;}
60718 if(this.params.FORMAT=="jpg"){this.params.FORMAT=OpenLayers.Util.alphaHack()?"gif":"png";}}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.ArcGIS93Rest(this.name,this.url,this.params,this.getOptions());}
60719 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var projWords=this.projection.getCode().split(":");var srid=projWords[projWords.length-1];var imageSize=this.getImageSize();var newParams={'BBOX':bounds.toBBOX(),'SIZE':imageSize.w+","+imageSize.h,'F':"image",'BBOXSR':srid,'IMAGESR':srid};if(this.layerDefs){var layerDefStrList=[];var layerID;for(layerID in this.layerDefs){if(this.layerDefs.hasOwnProperty(layerID)){if(this.layerDefs[layerID]){layerDefStrList.push(layerID);layerDefStrList.push(":");layerDefStrList.push(this.layerDefs[layerID]);layerDefStrList.push(";");}}}
60720 if(layerDefStrList.length>0){newParams['LAYERDEFS']=layerDefStrList.join("");}}
60721 var requestString=this.getFullRequestString(newParams);return requestString;},setLayerFilter:function(id,queryDef){if(!this.layerDefs){this.layerDefs={};}
60722 if(queryDef){this.layerDefs[id]=queryDef;}else{delete this.layerDefs[id];}},clearLayerFilter:function(id){if(id){delete this.layerDefs[id];}else{delete this.layerDefs;}},mergeNewParams:function(newParams){var upperParams=OpenLayers.Util.upperCaseObject(newParams);var newArguments=[upperParams];return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,newArguments);},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.ArcGIS93Rest"});OpenLayers.Layer.Google.v3={DEFAULTS:{maxExtent:new OpenLayers.Bounds(-128*156543.0339,-128*156543.0339,128*156543.0339,128*156543.0339),sphericalMercator:true,maxResolution:156543.0339,units:"m",projection:"EPSG:900913"},loadMapObject:function(){if(!this.type){this.type=google.maps.MapTypeId.ROADMAP;}
60723 var mapObject;var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){mapObject=cache.mapObject;++cache.count;}else{var container=this.map.viewPortDiv;var div=document.createElement("div");div.id=this.map.id+"_GMapContainer";div.style.position="absolute";div.style.width="100%";div.style.height="100%";container.appendChild(div);var center=this.map.getCenter();mapObject=new google.maps.Map(div,{center:center?new google.maps.LatLng(center.lat,center.lon):new google.maps.LatLng(0,0),zoom:this.map.getZoom()||0,mapTypeId:this.type,disableDefaultUI:true,keyboardShortcuts:false,draggable:false,disableDoubleClickZoom:true,scrollwheel:false});cache={mapObject:mapObject,count:1};OpenLayers.Layer.Google.cache[this.map.id]=cache;this.repositionListener=google.maps.event.addListenerOnce(mapObject,"center_changed",OpenLayers.Function.bind(this.repositionMapElements,this));}
60724 this.mapObject=mapObject;this.setGMapVisibility(this.visibility);},repositionMapElements:function(){google.maps.event.trigger(this.mapObject,"resize");var div=this.mapObject.getDiv().firstChild;if(!div||div.childNodes.length<3){this.repositionTimer=window.setTimeout(OpenLayers.Function.bind(this.repositionMapElements,this),250);return false;}
60725 var cache=OpenLayers.Layer.Google.cache[this.map.id];var container=this.map.viewPortDiv;var termsOfUse=div.lastChild;container.appendChild(termsOfUse);termsOfUse.style.zIndex="1100";termsOfUse.style.bottom="";termsOfUse.className="olLayerGoogleCopyright olLayerGoogleV3";termsOfUse.style.display="";cache.termsOfUse=termsOfUse;var poweredBy=div.lastChild;container.appendChild(poweredBy);poweredBy.style.zIndex="1100";poweredBy.style.bottom="";poweredBy.className="olLayerGooglePoweredBy olLayerGoogleV3 gmnoprint";poweredBy.style.display="";cache.poweredBy=poweredBy;this.setGMapVisibility(this.visibility);},onMapResize:function(){if(this.visibility){google.maps.event.trigger(this.mapObject,"resize");}else{if(!this._resized){var layer=this;google.maps.event.addListenerOnce(this.mapObject,"tilesloaded",function(){delete layer._resized;google.maps.event.trigger(layer.mapObject,"resize");layer.moveTo(layer.map.getCenter(),layer.map.getZoom());});}
60726 this._resized=true;}},setGMapVisibility:function(visible){var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){var type=this.type;var layers=this.map.layers;var layer;for(var i=layers.length-1;i>=0;--i){layer=layers[i];if(layer instanceof OpenLayers.Layer.Google&&layer.visibility===true&&layer.inRange===true){type=layer.type;visible=true;break;}}
60727 var container=this.mapObject.getDiv();if(visible===true){this.mapObject.setMapTypeId(type);container.style.left="";if(cache.termsOfUse&&cache.termsOfUse.style){cache.termsOfUse.style.left="";cache.termsOfUse.style.display="";cache.poweredBy.style.display="";}
60728 cache.displayed=this.id;}else{delete cache.displayed;container.style.left="-9999px";if(cache.termsOfUse&&cache.termsOfUse.style){cache.termsOfUse.style.display="none";cache.termsOfUse.style.left="-9999px";cache.poweredBy.style.display="none";}}}},getMapContainer:function(){return this.mapObject.getDiv();},getMapObjectBoundsFromOLBounds:function(olBounds){var moBounds=null;if(olBounds!=null){var sw=this.sphericalMercator?this.inverseMercator(olBounds.bottom,olBounds.left):new OpenLayers.LonLat(olBounds.bottom,olBounds.left);var ne=this.sphericalMercator?this.inverseMercator(olBounds.top,olBounds.right):new OpenLayers.LonLat(olBounds.top,olBounds.right);moBounds=new google.maps.LatLngBounds(new google.maps.LatLng(sw.lat,sw.lon),new google.maps.LatLng(ne.lat,ne.lon));}
60729 return moBounds;},getMapObjectLonLatFromMapObjectPixel:function(moPixel){var size=this.map.getSize();var lon=this.getLongitudeFromMapObjectLonLat(this.mapObject.center);var lat=this.getLatitudeFromMapObjectLonLat(this.mapObject.center);var res=this.map.getResolution();var delta_x=moPixel.x-(size.w/2);var delta_y=moPixel.y-(size.h/2);var lonlat=new OpenLayers.LonLat(lon+delta_x*res,lat-delta_y*res);if(this.wrapDateLine){lonlat=lonlat.wrapDateLine(this.maxExtent);}
60730 return this.getMapObjectLonLatFromLonLat(lonlat.lon,lonlat.lat);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){var lon=this.getLongitudeFromMapObjectLonLat(moLonLat);var lat=this.getLatitudeFromMapObjectLonLat(moLonLat);var res=this.map.getResolution();var extent=this.map.getExtent();var px=new OpenLayers.Pixel((1/res*(lon-extent.left)),(1/res*(extent.top-lat)));return this.getMapObjectPixelFromXY(px.x,px.y);},setMapObjectCenter:function(center,zoom){this.mapObject.setOptions({center:center,zoom:zoom});},getMapObjectZoomFromMapObjectBounds:function(moBounds){return this.mapObject.getBoundsZoomLevel(moBounds);},getMapObjectLonLatFromLonLat:function(lon,lat){var gLatLng;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);gLatLng=new google.maps.LatLng(lonlat.lat,lonlat.lon);}else{gLatLng=new google.maps.LatLng(lat,lon);}
60731 return gLatLng;},getMapObjectPixelFromXY:function(x,y){return new google.maps.Point(x,y);},destroy:function(){if(this.repositionListener){google.maps.event.removeListener(this.repositionListener);}
60732 if(this.repositionTimer){window.clearTimeout(this.repositionTimer);}
60733 OpenLayers.Layer.Google.prototype.destroy.apply(this,arguments);}};OpenLayers.Layer.KaMap=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,units:null,resolution:OpenLayers.DOTS_PER_INCH,DEFAULT_PARAMS:{i:'jpeg',map:''},initialize:function(name,url,params,options){var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS);},getURL:function(bounds){bounds=this.adjustBounds(bounds);var mapRes=this.map.getResolution();var scale=Math.round((this.map.getScale()*10000))/10000;var pX=Math.round(bounds.left/mapRes);var pY=-Math.round(bounds.top/mapRes);return this.getFullRequestString({t:pY,l:pX,s:scale});},addTile:function(bounds,position){var url=this.getURL(bounds);return new OpenLayers.Tile.Image(this,position,bounds,url,this.tileSize);},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=tilecol*tilelon;var offsetlat=bounds.top;var tilerow=Math.ceil(offsetlat/tilelat)+this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=-(tilerowremain+1)*this.tileSize.h;var tileoffsetlat=tilerow*tilelat;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.KaMap(this.name,this.url,this.params,this.getOptions());}
60734 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);if(this.tileSize!=null){obj.tileSize=this.tileSize.clone();}
60735 obj.grid=[];return obj;},getTileBounds:function(viewPortPx){var resolution=this.getResolution();var tileMapWidth=resolution*this.tileSize.w;var tileMapHeight=resolution*this.tileSize.h;var mapPoint=this.getLonLatFromViewPortPx(viewPortPx);var tileLeft=tileMapWidth*Math.floor(mapPoint.lon/tileMapWidth);var tileBottom=tileMapHeight*Math.floor(mapPoint.lat/tileMapHeight);return new OpenLayers.Bounds(tileLeft,tileBottom,tileLeft+tileMapWidth,tileBottom+tileMapHeight);},CLASS_NAME:"OpenLayers.Layer.KaMap"});OpenLayers.Layer.MapGuide=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,useHttpTile:false,singleTile:false,useOverlay:false,useAsyncOverlay:true,TILE_PARAMS:{operation:'GETTILEIMAGE',version:'1.2.0'},SINGLE_TILE_PARAMS:{operation:'GETMAPIMAGE',format:'PNG',locale:'en',clip:'1',version:'1.0.0'},OVERLAY_PARAMS:{operation:'GETDYNAMICMAPOVERLAYIMAGE',format:'PNG',locale:'en',clip:'1',version:'2.0.0'},FOLDER_PARAMS:{tileColumnsPerFolder:30,tileRowsPerFolder:30,format:'png',querystring:null},defaultSize:new OpenLayers.Size(300,300),initialize:function(name,url,params,options){OpenLayers.Layer.Grid.prototype.initialize.apply(this,arguments);if(options==null||options.isBaseLayer==null){this.isBaseLayer=((this.transparent!="true")&&(this.transparent!=true));}
60736 if(options&&options.useOverlay!=null){this.useOverlay=options.useOverlay;}
60737 if(this.singleTile){if(this.useOverlay){OpenLayers.Util.applyDefaults(this.params,this.OVERLAY_PARAMS);if(!this.useAsyncOverlay){this.params.version="1.0.0";}}else{OpenLayers.Util.applyDefaults(this.params,this.SINGLE_TILE_PARAMS);}}else{if(this.useHttpTile){OpenLayers.Util.applyDefaults(this.params,this.FOLDER_PARAMS);}else{OpenLayers.Util.applyDefaults(this.params,this.TILE_PARAMS);}
60738 this.setTileSize(this.defaultSize);}},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.MapGuide(this.name,this.url,this.params,this.getOptions());}
60739 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},getURL:function(bounds){var url;var center=bounds.getCenterLonLat();var mapSize=this.map.getSize();if(this.singleTile){var params={setdisplaydpi:OpenLayers.DOTS_PER_INCH,setdisplayheight:mapSize.h*this.ratio,setdisplaywidth:mapSize.w*this.ratio,setviewcenterx:center.lon,setviewcentery:center.lat,setviewscale:this.map.getScale()};if(this.useOverlay&&!this.useAsyncOverlay){var getVisParams={};getVisParams=OpenLayers.Util.extend(getVisParams,params);getVisParams.operation="GETVISIBLEMAPEXTENT";getVisParams.version="1.0.0";getVisParams.session=this.params.session;getVisParams.mapName=this.params.mapName;getVisParams.format='text/xml';url=this.getFullRequestString(getVisParams);OpenLayers.Request.GET({url:url,async:false});}
60740 url=this.getFullRequestString(params);}else{var currentRes=this.map.getResolution();var colidx=Math.floor((bounds.left-this.maxExtent.left)/currentRes);colidx=Math.round(colidx/this.tileSize.w);var rowidx=Math.floor((this.maxExtent.top-bounds.top)/currentRes);rowidx=Math.round(rowidx/this.tileSize.h);if(this.useHttpTile){url=this.getImageFilePath({tilecol:colidx,tilerow:rowidx,scaleindex:this.resolutions.length-this.map.zoom-1});}else{url=this.getFullRequestString({tilecol:colidx,tilerow:rowidx,scaleindex:this.resolutions.length-this.map.zoom-1});}}
60741 return url;},getFullRequestString:function(newParams,altUrl){var url=(altUrl==null)?this.url:altUrl;if(typeof url=="object"){url=url[Math.floor(Math.random()*url.length)];}
60742 var requestString=url;var allParams=OpenLayers.Util.extend({},this.params);allParams=OpenLayers.Util.extend(allParams,newParams);var urlParams=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));for(var key in allParams){if(key.toUpperCase()in urlParams){delete allParams[key];}}
60743 var paramsString=OpenLayers.Util.getParameterString(allParams);paramsString=paramsString.replace(/,/g,"+");if(paramsString!=""){var lastServerChar=url.charAt(url.length-1);if((lastServerChar=="&")||(lastServerChar=="?")){requestString+=paramsString;}else{if(url.indexOf('?')==-1){requestString+='?'+paramsString;}else{requestString+='&'+paramsString;}}}
60744 return requestString;},getImageFilePath:function(newParams,altUrl){var url=(altUrl==null)?this.url:altUrl;if(typeof url=="object"){url=url[Math.floor(Math.random()*url.length)];}
60745 var requestString=url;var tileRowGroup="";var tileColGroup="";if(newParams.tilerow<0){tileRowGroup='-';}
60746 if(newParams.tilerow==0){tileRowGroup+='0';}else{tileRowGroup+=Math.floor(Math.abs(newParams.tilerow/this.params.tileRowsPerFolder))*this.params.tileRowsPerFolder;}
60747 if(newParams.tilecol<0){tileColGroup='-';}
60748 if(newParams.tilecol==0){tileColGroup+='0';}else{tileColGroup+=Math.floor(Math.abs(newParams.tilecol/this.params.tileColumnsPerFolder))*this.params.tileColumnsPerFolder;}
60749 var tilePath='/S'+Math.floor(newParams.scaleindex)
60750 +'/'+this.params.basemaplayergroupname
60751 +'/R'+tileRowGroup
60752 +'/C'+tileColGroup
60753 +'/'+(newParams.tilerow%this.params.tileRowsPerFolder)
60754 +'_'+(newParams.tilecol%this.params.tileColumnsPerFolder)
60755 +'.'+this.params.format;if(this.params.querystring){tilePath+="?"+this.params.querystring;}
60756 requestString+=tilePath;return requestString;},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left-extent.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=extent.left+tilecol*tilelon;var offsetlat=extent.top-bounds.top+tilelat;var tilerow=Math.floor(offsetlat/tilelat)-this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=tilerowremain*this.tileSize.h;var tileoffsetlat=extent.top-tilelat*tilerow;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},CLASS_NAME:"OpenLayers.Layer.MapGuide"});OpenLayers.Layer.MapServer=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{mode:"map",map_imagetype:"png"},initialize:function(name,url,params,options){var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS);if(options==null||options.isBaseLayer==null){this.isBaseLayer=((this.params.transparent!="true")&&(this.params.transparent!=true));}},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.MapServer(this.name,this.url,this.params,this.getOptions());}
60757 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},getURL:function(bounds){bounds=this.adjustBounds(bounds);var extent=[bounds.left,bounds.bottom,bounds.right,bounds.top];var imageSize=this.getImageSize();var url=this.getFullRequestString({mapext:extent,imgext:extent,map_size:[imageSize.w,imageSize.h],imgx:imageSize.w/2,imgy:imageSize.h/2,imgxy:[imageSize.w,imageSize.h]});return url;},getFullRequestString:function(newParams,altUrl){var url=(altUrl==null)?this.url:altUrl;var allParams=OpenLayers.Util.extend({},this.params);allParams=OpenLayers.Util.extend(allParams,newParams);var paramsString=OpenLayers.Util.getParameterString(allParams);if(url instanceof Array){url=this.selectUrl(paramsString,url);}
60758 var urlParams=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));for(var key in allParams){if(key.toUpperCase()in urlParams){delete allParams[key];}}
60759 paramsString=OpenLayers.Util.getParameterString(allParams);var requestString=url;paramsString=paramsString.replace(/,/g,"+");if(paramsString!=""){var lastServerChar=url.charAt(url.length-1);if((lastServerChar=="&")||(lastServerChar=="?")){requestString+=paramsString;}else{if(url.indexOf('?')==-1){requestString+='?'+paramsString;}else{requestString+='&'+paramsString;}}}
60760 return requestString;},CLASS_NAME:"OpenLayers.Layer.MapServer"});OpenLayers.Layer.TMS=OpenLayers.Class(OpenLayers.Layer.Grid,{serviceVersion:"1.0.0",isBaseLayer:true,tileOrigin:null,serverResolutions:null,zoomOffset:0,initialize:function(name,url,options){var newArguments=[];newArguments.push(name,url,{},options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.TMS(this.name,this.url,this.getOptions());}
60761 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var res=this.map.getResolution();var x=Math.round((bounds.left-this.tileOrigin.lon)/(res*this.tileSize.w));var y=Math.round((bounds.bottom-this.tileOrigin.lat)/(res*this.tileSize.h));var z=this.serverResolutions!=null?OpenLayers.Util.indexOf(this.serverResolutions,res):this.map.getZoom()+this.zoomOffset;var path=this.serviceVersion+"/"+this.layername+"/"+z+"/"+x+"/"+y+"."+this.type;var url=this.url;if(url instanceof Array){url=this.selectUrl(path,url);}
60762 return url+path;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},setMap:function(map){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);if(!this.tileOrigin){this.tileOrigin=new OpenLayers.LonLat(this.map.maxExtent.left,this.map.maxExtent.bottom);}},CLASS_NAME:"OpenLayers.Layer.TMS"});OpenLayers.Layer.TileCache=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,format:'image/png',serverResolutions:null,initialize:function(name,url,layername,options){this.layername=layername;OpenLayers.Layer.Grid.prototype.initialize.apply(this,[name,url,{},options]);this.extension=this.format.split('/')[1].toLowerCase();this.extension=(this.extension=='jpg')?'jpeg':this.extension;},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.TileCache(this.name,this.url,this.layername,this.getOptions());}
60763 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){var res=this.map.getResolution();var bbox=this.maxExtent;var size=this.tileSize;var tileX=Math.round((bounds.left-bbox.left)/(res*size.w));var tileY=Math.round((bounds.bottom-bbox.bottom)/(res*size.h));var tileZ=this.serverResolutions!=null?OpenLayers.Util.indexOf(this.serverResolutions,res):this.map.getZoom();function zeroPad(number,length){number=String(number);var zeros=[];for(var i=0;i<length;++i){zeros.push('0');}
60764 return zeros.join('').substring(0,length-number.length)+number;}
60765 var components=[this.layername,zeroPad(tileZ,2),zeroPad(parseInt(tileX/1000000),3),zeroPad((parseInt(tileX/1000)%1000),3),zeroPad((parseInt(tileX)%1000),3),zeroPad(parseInt(tileY/1000000),3),zeroPad((parseInt(tileY/1000)%1000),3),zeroPad((parseInt(tileY)%1000),3)+'.'+this.extension];var path=components.join('/');var url=this.url;if(url instanceof Array){url=this.selectUrl(path,url);}
60766 url=(url.charAt(url.length-1)=='/')?url:url+'/';return url+path;},addTile:function(bounds,position){var url=this.getURL(bounds);return new OpenLayers.Tile.Image(this,position,bounds,url,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.TileCache"});OpenLayers.Layer.WMS=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{service:"WMS",version:"1.1.1",request:"GetMap",styles:"",exceptions:"application/vnd.ogc.se_inimage",format:"image/jpeg"},reproject:false,isBaseLayer:true,encodeBBOX:false,noMagic:false,yx:{'EPSG:4326':true},initialize:function(name,url,params,options){var newArguments=[];params=OpenLayers.Util.upperCaseObject(params);if(parseFloat(params.VERSION)>=1.3&&!params.EXCEPTIONS){params.EXCEPTIONS="INIMAGE";}
60767 newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);OpenLayers.Util.applyDefaults(this.params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS));if(!this.noMagic&&this.params.TRANSPARENT&&this.params.TRANSPARENT.toString().toLowerCase()=="true"){if((options==null)||(!options.isBaseLayer)){this.isBaseLayer=false;}
60768 if(this.params.FORMAT=="image/jpeg"){this.params.FORMAT=OpenLayers.Util.alphaHack()?"image/gif":"image/png";}}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WMS(this.name,this.url,this.params,this.getOptions());}
60769 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},reverseAxisOrder:function(){return(parseFloat(this.params.VERSION)>=1.3&&!!this.yx[this.map.getProjectionObject().getCode()]);},getURL:function(bounds){bounds=this.adjustBounds(bounds);var imageSize=this.getImageSize();var newParams={};var reverseAxisOrder=this.reverseAxisOrder();newParams.BBOX=this.encodeBBOX?bounds.toBBOX(null,reverseAxisOrder):bounds.toArray(reverseAxisOrder);newParams.WIDTH=imageSize.w;newParams.HEIGHT=imageSize.h;var requestString=this.getFullRequestString(newParams);return requestString;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},mergeNewParams:function(newParams){var upperParams=OpenLayers.Util.upperCaseObject(newParams);var newArguments=[upperParams];return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,newArguments);},getFullRequestString:function(newParams,altUrl){var projectionCode=this.map.getProjection();var value=(projectionCode=="none")?null:projectionCode
60770 if(parseFloat(this.params.VERSION)>=1.3){this.params.CRS=value;}else{this.params.SRS=value;}
60771 return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,arguments);},CLASS_NAME:"OpenLayers.Layer.WMS"});OpenLayers.Layer.WMTS=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,version:"1.0.0",requestEncoding:"KVP",url:null,layer:null,matrixSet:null,style:null,format:"image/jpeg",tileOrigin:null,tileFullExtent:null,formatSuffix:null,matrixIds:null,dimensions:null,params:null,zoomOffset:0,formatSuffixMap:{"image/png":"png","image/png8":"png","image/png24":"png","image/png32":"png","png":"png","image/jpeg":"jpg","image/jpg":"jpg","jpeg":"jpg","jpg":"jpg"},matrix:null,initialize:function(config){var required={url:true,layer:true,style:true,matrixSet:true};for(var prop in required){if(!(prop in config)){throw new Error("Missing property '"+prop+"' in layer configuration.");}}
60772 config.params=OpenLayers.Util.upperCaseObject(config.params);var args=[config.name,config.url,config.params,config];OpenLayers.Layer.Grid.prototype.initialize.apply(this,args);if(!this.formatSuffix){this.formatSuffix=this.formatSuffixMap[this.format]||this.format.split("/").pop();}
60773 if(this.matrixIds){var len=this.matrixIds.length;if(len&&typeof this.matrixIds[0]==="string"){var ids=this.matrixIds;this.matrixIds=new Array(len);for(var i=0;i<len;++i){this.matrixIds[i]={identifier:ids[i]};}}}},setMap:function(){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);this.updateMatrixProperties();},updateMatrixProperties:function(){this.matrix=this.getMatrix();if(this.matrix){if(this.matrix.topLeftCorner){this.tileOrigin=this.matrix.topLeftCorner;}
60774 if(this.matrix.tileWidth&&this.matrix.tileHeight){this.tileSize=new OpenLayers.Size(this.matrix.tileWidth,this.matrix.tileHeight);}
60775 if(!this.tileOrigin){this.tileOrigin=new OpenLayers.LonLat(this.maxExtent.left,this.maxExtent.top);}
60776 if(!this.tileFullExtent){this.tileFullExtent=this.maxExtent;}}},moveTo:function(bounds,zoomChanged,dragging){if(zoomChanged||!this.matrix){this.updateMatrixProperties();}
60777 return OpenLayers.Layer.Grid.prototype.moveTo.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WMTS(this.options);}
60778 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getMatrix:function(){var matrix;if(!this.matrixIds||this.matrixIds.length===0){matrix={identifier:this.map.getZoom()+this.zoomOffset};}else{if("scaleDenominator"in this.matrixIds[0]){var denom=OpenLayers.METERS_PER_INCH*OpenLayers.INCHES_PER_UNIT[this.units]*this.map.getResolution()/0.28E-3;var diff=Number.POSITIVE_INFINITY;var delta;for(var i=0,ii=this.matrixIds.length;i<ii;++i){delta=Math.abs(1-(this.matrixIds[i].scaleDenominator/denom));if(delta<diff){diff=delta;matrix=this.matrixIds[i];}}}else{matrix=this.matrixIds[this.map.getZoom()+this.zoomOffset];}}
60779 return matrix;},getTileInfo:function(loc){var res=this.map.getResolution();var fx=(loc.lon-this.tileOrigin.lon)/(res*this.tileSize.w);var fy=(this.tileOrigin.lat-loc.lat)/(res*this.tileSize.h);var col=Math.floor(fx);var row=Math.floor(fy);return{col:col,row:row,i:Math.floor((fx-col)*this.tileSize.w),j:Math.floor((fy-row)*this.tileSize.h)};},getURL:function(bounds){bounds=this.adjustBounds(bounds);var url="";if(!this.tileFullExtent||this.tileFullExtent.intersectsBounds(bounds)){var center=bounds.getCenterLonLat();var info=this.getTileInfo(center);var matrixId=this.matrix.identifier;if(this.requestEncoding.toUpperCase()==="REST"){var path=this.version+"/"+this.layer+"/"+this.style+"/";if(this.dimensions){for(var i=0;i<this.dimensions.length;i++){if(this.params[this.dimensions[i]]){path=path+this.params[this.dimensions[i]]+"/";}}}
60780 path=path+this.matrixSet+"/"+this.matrix.identifier+"/"+info.row+"/"+info.col+"."+this.formatSuffix;if(this.url instanceof Array){url=this.selectUrl(path,this.url);}else{url=this.url;}
60781 if(!url.match(/\/$/)){url=url+"/";}
60782 url=url+path;}else if(this.requestEncoding.toUpperCase()==="KVP"){var params={SERVICE:"WMTS",REQUEST:"GetTile",VERSION:this.version,LAYER:this.layer,STYLE:this.style,TILEMATRIXSET:this.matrixSet,TILEMATRIX:this.matrix.identifier,TILEROW:info.row,TILECOL:info.col,FORMAT:this.format};url=OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,[params]);}}
60783 return url;},mergeNewParams:function(newParams){if(this.requestEncoding.toUpperCase()==="KVP"){return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,[OpenLayers.Util.upperCaseObject(newParams)]);}},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.WMTS"});OpenLayers.Layer.WorldWind=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{},isBaseLayer:true,lzd:null,zoomLevels:null,initialize:function(name,url,lzd,zoomLevels,params,options){this.lzd=lzd;this.zoomLevels=zoomLevels;var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS);},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},getZoom:function(){var zoom=this.map.getZoom();var extent=this.map.getMaxExtent();zoom=zoom-Math.log(this.maxResolution/(this.lzd/512))/Math.log(2);return zoom;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var zoom=this.getZoom();var extent=this.map.getMaxExtent();var deg=this.lzd/Math.pow(2,this.getZoom());var x=Math.floor((bounds.left-extent.left)/deg);var y=Math.floor((bounds.bottom-extent.bottom)/deg);if(this.map.getResolution()<=(this.lzd/512)&&this.getZoom()<=this.zoomLevels){return this.getFullRequestString({L:zoom,X:x,Y:y});}else{return OpenLayers.Util.getImagesLocation()+"blank.gif";}},CLASS_NAME:"OpenLayers.Layer.WorldWind"});OpenLayers.Layer.XYZ=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,sphericalMercator:false,zoomOffset:0,initialize:function(name,url,options){if(options&&options.sphericalMercator||this.sphericalMercator){options=OpenLayers.Util.extend({maxExtent:new OpenLayers.Bounds(-128*156543.0339,-128*156543.0339,128*156543.0339,128*156543.0339),maxResolution:156543.0339,numZoomLevels:19,units:"m",projection:"EPSG:900913"},options);}
60784 url=url||this.url;name=name||this.name;var newArguments=[name,url,{},options];OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.XYZ(this.name,this.url,this.getOptions());}
60785 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){var res=this.map.getResolution();var x=Math.round((bounds.left-this.maxExtent.left)/(res*this.tileSize.w));var y=Math.round((this.maxExtent.top-bounds.top)/(res*this.tileSize.h));var z=this.map.getZoom()+this.zoomOffset;var url=this.url;var s=''+x+y+z;if(url instanceof Array)
60786 {url=this.selectUrl(s,url);}
60787 var path=OpenLayers.String.format(url,{'x':x,'y':y,'z':z});return path;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},setMap:function(map){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);if(!this.tileOrigin){this.tileOrigin=new OpenLayers.LonLat(this.maxExtent.left,this.maxExtent.bottom);}},CLASS_NAME:"OpenLayers.Layer.XYZ"});OpenLayers.Layer.OSM=OpenLayers.Class(OpenLayers.Layer.XYZ,{name:"OpenStreetMap",attribution:"Data CC-By-SA by <a href='http://openstreetmap.org/'>OpenStreetMap</a>",sphericalMercator:true,url:'http://tile.openstreetmap.org/${z}/${x}/${y}.png',clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.OSM(this.name,this.url,this.getOptions());}
60788 obj=OpenLayers.Layer.XYZ.prototype.clone.apply(this,[obj]);return obj;},CLASS_NAME:"OpenLayers.Layer.OSM"});OpenLayers.Layer.Zoomify=OpenLayers.Class(OpenLayers.Layer.Grid,{url:null,size:null,isBaseLayer:true,standardTileSize:256,numberOfTiers:0,tileCountUpToTier:new Array(),tierSizeInTiles:new Array(),tierImageSize:new Array(),initialize:function(name,url,size,options){this.initializeZoomify(size);var newArguments=[];newArguments.push(name,url,size,{},options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);},initializeZoomify:function(size){var imageSize=size.clone()
60789 var tiles=new OpenLayers.Size(Math.ceil(imageSize.w/this.standardTileSize),Math.ceil(imageSize.h/this.standardTileSize));this.tierSizeInTiles.push(tiles);this.tierImageSize.push(imageSize);while(imageSize.w>this.standardTileSize||imageSize.h>this.standardTileSize){imageSize=new OpenLayers.Size(Math.floor(imageSize.w/2),Math.floor(imageSize.h/2));tiles=new OpenLayers.Size(Math.ceil(imageSize.w/this.standardTileSize),Math.ceil(imageSize.h/this.standardTileSize));this.tierSizeInTiles.push(tiles);this.tierImageSize.push(imageSize);}
60790 this.tierSizeInTiles.reverse();this.tierImageSize.reverse();this.numberOfTiers=this.tierSizeInTiles.length;this.tileCountUpToTier[0]=0;for(var i=1;i<this.numberOfTiers;i++){this.tileCountUpToTier.push(this.tierSizeInTiles[i-1].w*this.tierSizeInTiles[i-1].h+
60791 this.tileCountUpToTier[i-1]);}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);this.tileCountUpToTier.length=0
60792 this.tierSizeInTiles.length=0
60793 this.tierImageSize.length=0},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Zoomify(this.name,this.url,this.size,this.options);}
60794 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var res=this.map.getResolution();var x=Math.round((bounds.left-this.tileOrigin.lon)/(res*this.tileSize.w));var y=Math.round((this.tileOrigin.lat-bounds.top)/(res*this.tileSize.h));var z=this.map.getZoom();var tileIndex=x+y*this.tierSizeInTiles[z].w+this.tileCountUpToTier[z];var path="TileGroup"+Math.floor((tileIndex)/256)+"/"+z+"-"+x+"-"+y+".jpg";var url=this.url;if(url instanceof Array){url=this.selectUrl(path,url);}
60795 return url+path;},getImageSize:function(){if(arguments.length>0){bounds=this.adjustBounds(arguments[0]);var res=this.map.getResolution();var x=Math.round((bounds.left-this.tileOrigin.lon)/(res*this.tileSize.w));var y=Math.round((this.tileOrigin.lat-bounds.top)/(res*this.tileSize.h));var z=this.map.getZoom();var w=this.standardTileSize;var h=this.standardTileSize;if(x==this.tierSizeInTiles[z].w-1){var w=this.tierImageSize[z].w%this.standardTileSize;};if(y==this.tierSizeInTiles[z].h-1){var h=this.tierImageSize[z].h%this.standardTileSize;};return(new OpenLayers.Size(w,h));}else{return this.tileSize;}},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},setMap:function(map){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);this.tileOrigin=new OpenLayers.LonLat(this.map.maxExtent.left,this.map.maxExtent.top);},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left-extent.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=extent.left+tilecol*tilelon;var offsetlat=extent.top-bounds.top+tilelat;var tilerow=Math.floor(offsetlat/tilelat)-this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=tilerowremain*this.tileSize.h;var tileoffsetlat=extent.top-tilelat*tilerow;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},CLASS_NAME:"OpenLayers.Layer.Zoomify"});OpenLayers.Protocol.SQL.Gears=OpenLayers.Class(OpenLayers.Protocol.SQL,{FID_PREFIX:'__gears_fid__',NULL_GEOMETRY:'__gears_null_geometry__',NULL_FEATURE_STATE:'__gears_null_feature_state__',jsonParser:null,wktParser:null,fidRegExp:null,saveFeatureState:true,typeOfFid:"string",db:null,initialize:function(options){if(!this.supported()){return;}
60796 OpenLayers.Protocol.SQL.prototype.initialize.apply(this,[options]);this.jsonParser=new OpenLayers.Format.JSON();this.wktParser=new OpenLayers.Format.WKT();this.fidRegExp=new RegExp('^'+this.FID_PREFIX);this.initializeDatabase();},initializeDatabase:function(){this.db=google.gears.factory.create('beta.database');this.db.open(this.databaseName);this.db.execute("CREATE TABLE IF NOT EXISTS "+this.tableName+" (fid TEXT UNIQUE, geometry TEXT, properties TEXT,"+"  state TEXT)");},destroy:function(){this.db.close();this.db=null;this.jsonParser=null;this.wktParser=null;OpenLayers.Protocol.SQL.prototype.destroy.apply(this);},supported:function(){return!!(window.google&&google.gears);},read:function(options){OpenLayers.Protocol.prototype.read.apply(this,arguments);options=OpenLayers.Util.applyDefaults(options,this.options);var feature,features=[];var rs=this.db.execute("SELECT * FROM "+this.tableName);while(rs.isValidRow()){feature=this.unfreezeFeature(rs);if(this.evaluateFilter(feature,options.filter)){if(!options.noFeatureStateReset){feature.state=null;}
60797 features.push(feature);}
60798 rs.next();}
60799 rs.close();var resp=new OpenLayers.Protocol.Response({code:OpenLayers.Protocol.Response.SUCCESS,requestType:"read",features:features});if(options&&options.callback){options.callback.call(options.scope,resp);}
60800 return resp;},unfreezeFeature:function(row){var feature;var wkt=row.fieldByName('geometry');if(wkt==this.NULL_GEOMETRY){feature=new OpenLayers.Feature.Vector();}else{feature=this.wktParser.read(wkt);}
60801 feature.attributes=this.jsonParser.read(row.fieldByName('properties'));feature.fid=this.extractFidFromField(row.fieldByName('fid'));var state=row.fieldByName('state');if(state==this.NULL_FEATURE_STATE){state=null;}
60802 feature.state=state;return feature;},extractFidFromField:function(field){if(!field.match(this.fidRegExp)&&this.typeOfFid=="number"){field=parseFloat(field);}
60803 return field;},create:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=this.createOrUpdate(features);resp.requestType="create";if(options&&options.callback){options.callback.call(options.scope,resp);}
60804 return resp;},update:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=this.createOrUpdate(features);resp.requestType="update";if(options&&options.callback){options.callback.call(options.scope,resp);}
60805 return resp;},createOrUpdate:function(features){if(!(features instanceof Array)){features=[features];}
60806 var i,len=features.length,feature;var insertedFeatures=new Array(len);for(i=0;i<len;i++){feature=features[i];var params=this.freezeFeature(feature);this.db.execute("REPLACE INTO "+this.tableName+" (fid, geometry, properties, state)"+" VALUES (?, ?, ?, ?)",params);var clone=feature.clone();clone.fid=this.extractFidFromField(params[0]);insertedFeatures[i]=clone;}
60807 return new OpenLayers.Protocol.Response({code:OpenLayers.Protocol.Response.SUCCESS,features:insertedFeatures,reqFeatures:features});},freezeFeature:function(feature){feature.fid=feature.fid!=null?""+feature.fid:OpenLayers.Util.createUniqueID(this.FID_PREFIX);var geometry=feature.geometry!=null?feature.geometry.toString():this.NULL_GEOMETRY;var properties=this.jsonParser.write(feature.attributes);var state=this.getFeatureStateForFreeze(feature);return[feature.fid,geometry,properties,state];},getFeatureStateForFreeze:function(feature){var state;if(!this.saveFeatureState){state=this.NULL_FEATURE_STATE;}else if(this.createdOffline(feature)){state=OpenLayers.State.INSERT;}else{state=feature.state;}
60808 return state;},"delete":function(features,options){if(!(features instanceof Array)){features=[features];}
60809 options=OpenLayers.Util.applyDefaults(options,this.options);var i,len,feature;for(i=0,len=features.length;i<len;i++){feature=features[i];if(this.saveFeatureState&&!this.createdOffline(feature)){var toDelete=feature.clone();toDelete.fid=feature.fid;if(toDelete.geometry){toDelete.geometry.destroy();toDelete.geometry=null;}
60810 toDelete.state=feature.state;this.createOrUpdate(toDelete);}else{this.db.execute("DELETE FROM "+this.tableName+" WHERE fid = ?",[feature.fid]);}}
60811 var resp=new OpenLayers.Protocol.Response({code:OpenLayers.Protocol.Response.SUCCESS,requestType:"delete",reqFeatures:features});if(options&&options.callback){options.callback.call(options.scope,resp);}
60812 return resp;},createdOffline:function(feature){return(typeof feature.fid=="string"&&!!(feature.fid.match(this.fidRegExp)));},commit:function(features,options){var opt,resp=[],nRequests=0,nResponses=0;function callback(resp){if(++nResponses<nRequests){resp.last=false;}
60813 this.callUserCallback(options,resp);}
60814 var feature,toCreate=[],toUpdate=[],toDelete=[];for(var i=features.length-1;i>=0;i--){feature=features[i];switch(feature.state){case OpenLayers.State.INSERT:toCreate.push(feature);break;case OpenLayers.State.UPDATE:toUpdate.push(feature);break;case OpenLayers.State.DELETE:toDelete.push(feature);break;}}
60815 if(toCreate.length>0){nRequests++;opt=OpenLayers.Util.applyDefaults({"callback":callback,"scope":this},options.create);resp.push(this.create(toCreate,opt));}
60816 if(toUpdate.length>0){nRequests++;opt=OpenLayers.Util.applyDefaults({"callback":callback,"scope":this},options.update);resp.push(this.update(toUpdate,opt));}
60817 if(toDelete.length>0){nRequests++;opt=OpenLayers.Util.applyDefaults({"callback":callback,"scope":this},options["delete"]);resp.push(this["delete"](toDelete,opt));}
60818 return resp;},clear:function(){this.db.execute("DELETE FROM "+this.tableName);},callUserCallback:function(options,resp){var opt=options[resp.requestType];if(opt&&opt.callback){opt.callback.call(opt.scope,resp);}
60819 if(resp.last&&options.callback){options.callback.call(options.scope);}},CLASS_NAME:"OpenLayers.Protocol.SQL.Gears"});OpenLayers.Rule=OpenLayers.Class({id:null,name:null,title:null,description:null,context:null,filter:null,elseFilter:false,symbolizer:null,symbolizers:null,minScaleDenominator:null,maxScaleDenominator:null,initialize:function(options){this.symbolizer={};OpenLayers.Util.extend(this,options);if(this.symbolizers){delete this.symbolizer;}
60820 this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){for(var i in this.symbolizer){this.symbolizer[i]=null;}
60821 this.symbolizer=null;delete this.symbolizers;},evaluate:function(feature){var context=this.getContext(feature);var applies=true;if(this.minScaleDenominator||this.maxScaleDenominator){var scale=feature.layer.map.getScale();}
60822 if(this.minScaleDenominator){applies=scale>=OpenLayers.Style.createLiteral(this.minScaleDenominator,context);}
60823 if(applies&&this.maxScaleDenominator){applies=scale<OpenLayers.Style.createLiteral(this.maxScaleDenominator,context);}
60824 if(applies&&this.filter){if(this.filter.CLASS_NAME=="OpenLayers.Filter.FeatureId"){applies=this.filter.evaluate(feature);}else{applies=this.filter.evaluate(context);}}
60825 return applies;},getContext:function(feature){var context=this.context;if(!context){context=feature.attributes||feature.data;}
60826 if(typeof this.context=="function"){context=this.context(feature);}
60827 return context;},clone:function(){var options=OpenLayers.Util.extend({},this);if(this.symbolizers){var len=this.symbolizers.length;options.symbolizers=new Array(len);for(var i=0;i<len;++i){options.symbolizers[i]=this.symbolizers[i].clone();}}else{options.symbolizer={};var value,type;for(var key in this.symbolizer){value=this.symbolizer[key];type=typeof value;if(type==="object"){options.symbolizer[key]=OpenLayers.Util.extend({},value);}else if(type==="string"){options.symbolizer[key]=value;}}}
60828 options.filter=this.filter&&this.filter.clone();options.context=this.context&&OpenLayers.Util.extend({},this.context);return new OpenLayers.Rule(options);},CLASS_NAME:"OpenLayers.Rule"});OpenLayers.StyleMap=OpenLayers.Class({styles:null,extendDefault:true,initialize:function(style,options){this.styles={"default":new OpenLayers.Style(OpenLayers.Feature.Vector.style["default"]),"select":new OpenLayers.Style(OpenLayers.Feature.Vector.style["select"]),"temporary":new OpenLayers.Style(OpenLayers.Feature.Vector.style["temporary"]),"delete":new OpenLayers.Style(OpenLayers.Feature.Vector.style["delete"])};if(style instanceof OpenLayers.Style){this.styles["default"]=style;this.styles["select"]=style;this.styles["temporary"]=style;this.styles["delete"]=style;}else if(typeof style=="object"){for(var key in style){if(style[key]instanceof OpenLayers.Style){this.styles[key]=style[key];}else if(typeof style[key]=="object"){this.styles[key]=new OpenLayers.Style(style[key]);}else{this.styles["default"]=new OpenLayers.Style(style);this.styles["select"]=new OpenLayers.Style(style);this.styles["temporary"]=new OpenLayers.Style(style);this.styles["delete"]=new OpenLayers.Style(style);break;}}}
60829 OpenLayers.Util.extend(this,options);},destroy:function(){for(var key in this.styles){this.styles[key].destroy();}
60830 this.styles=null;},createSymbolizer:function(feature,intent){if(!feature){feature=new OpenLayers.Feature.Vector();}
60831 if(!this.styles[intent]){intent="default";}
60832 feature.renderIntent=intent;var defaultSymbolizer={};if(this.extendDefault&&intent!="default"){defaultSymbolizer=this.styles["default"].createSymbolizer(feature);}
60833 return OpenLayers.Util.extend(defaultSymbolizer,this.styles[intent].createSymbolizer(feature));},addUniqueValueRules:function(renderIntent,property,symbolizers,context){var rules=[];for(var value in symbolizers){rules.push(new OpenLayers.Rule({symbolizer:symbolizers[value],context:context,filter:new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO,property:property,value:value})}));}
60834 this.styles[renderIntent].addRules(rules);},CLASS_NAME:"OpenLayers.StyleMap"});OpenLayers.Control.NavToolbar=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.Navigation(),new OpenLayers.Control.ZoomBox()]);},draw:function(){var div=OpenLayers.Control.Panel.prototype.draw.apply(this,arguments);this.activateControl(this.controls[0]);return div;},CLASS_NAME:"OpenLayers.Control.NavToolbar"});OpenLayers.Filter.Comparison=OpenLayers.Class(OpenLayers.Filter,{type:null,property:null,value:null,matchCase:true,lowerBoundary:null,upperBoundary:null,initialize:function(options){OpenLayers.Filter.prototype.initialize.apply(this,[options]);},evaluate:function(context){if(context instanceof OpenLayers.Feature.Vector){context=context.attributes;}
60835 var result=false;var got=context[this.property];switch(this.type){case OpenLayers.Filter.Comparison.EQUAL_TO:var exp=this.value;if(!this.matchCase&&typeof got=="string"&&typeof exp=="string"){result=(got.toUpperCase()==exp.toUpperCase());}else{result=(got==exp);}
60836 break;case OpenLayers.Filter.Comparison.NOT_EQUAL_TO:var exp=this.value;if(!this.matchCase&&typeof got=="string"&&typeof exp=="string"){result=(got.toUpperCase()!=exp.toUpperCase());}else{result=(got!=exp);}
60837 break;case OpenLayers.Filter.Comparison.LESS_THAN:result=got<this.value;break;case OpenLayers.Filter.Comparison.GREATER_THAN:result=got>this.value;break;case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO:result=got<=this.value;break;case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO:result=got>=this.value;break;case OpenLayers.Filter.Comparison.BETWEEN:result=(got>=this.lowerBoundary)&&(got<=this.upperBoundary);break;case OpenLayers.Filter.Comparison.LIKE:var regexp=new RegExp(this.value,"gi");result=regexp.test(got);break;}
60838 return result;},value2regex:function(wildCard,singleChar,escapeChar){if(wildCard=="."){var msg="'.' is an unsupported wildCard character for "+"OpenLayers.Filter.Comparison";OpenLayers.Console.error(msg);return null;}
60839 wildCard=wildCard?wildCard:"*";singleChar=singleChar?singleChar:".";escapeChar=escapeChar?escapeChar:"!";this.value=this.value.replace(new RegExp("\\"+escapeChar+"(.|$)","g"),"\\$1");this.value=this.value.replace(new RegExp("\\"+singleChar,"g"),".");this.value=this.value.replace(new RegExp("\\"+wildCard,"g"),".*");this.value=this.value.replace(new RegExp("\\\\.\\*","g"),"\\"+wildCard);this.value=this.value.replace(new RegExp("\\\\\\.","g"),"\\"+singleChar);return this.value;},regex2value:function(){var value=this.value;value=value.replace(/!/g,"!!");value=value.replace(/(\\)?\\\./g,function($0,$1){return $1?$0:"!.";});value=value.replace(/(\\)?\\\*/g,function($0,$1){return $1?$0:"!*";});value=value.replace(/\\\\/g,"\\");value=value.replace(/\.\*/g,"*");return value;},clone:function(){return OpenLayers.Util.extend(new OpenLayers.Filter.Comparison(),this);},CLASS_NAME:"OpenLayers.Filter.Comparison"});OpenLayers.Filter.Comparison.EQUAL_TO="==";OpenLayers.Filter.Comparison.NOT_EQUAL_TO="!=";OpenLayers.Filter.Comparison.LESS_THAN="<";OpenLayers.Filter.Comparison.GREATER_THAN=">";OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO="<=";OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO=">=";OpenLayers.Filter.Comparison.BETWEEN="..";OpenLayers.Filter.Comparison.LIKE="~";OpenLayers.Filter.FeatureId=OpenLayers.Class(OpenLayers.Filter,{fids:null,initialize:function(options){this.fids=[];OpenLayers.Filter.prototype.initialize.apply(this,[options]);},evaluate:function(feature){for(var i=0,len=this.fids.length;i<len;i++){var fid=feature.fid||feature.id;if(fid==this.fids[i]){return true;}}
60840 return false;},clone:function(){var filter=new OpenLayers.Filter.FeatureId();OpenLayers.Util.extend(filter,this);filter.fids=this.fids.slice();return filter;},CLASS_NAME:"OpenLayers.Filter.FeatureId"});OpenLayers.Filter.Logical=OpenLayers.Class(OpenLayers.Filter,{filters:null,type:null,initialize:function(options){this.filters=[];OpenLayers.Filter.prototype.initialize.apply(this,[options]);},destroy:function(){this.filters=null;OpenLayers.Filter.prototype.destroy.apply(this);},evaluate:function(context){switch(this.type){case OpenLayers.Filter.Logical.AND:for(var i=0,len=this.filters.length;i<len;i++){if(this.filters[i].evaluate(context)==false){return false;}}
60841 return true;case OpenLayers.Filter.Logical.OR:for(var i=0,len=this.filters.length;i<len;i++){if(this.filters[i].evaluate(context)==true){return true;}}
60842 return false;case OpenLayers.Filter.Logical.NOT:return(!this.filters[0].evaluate(context));}},clone:function(){var filters=[];for(var i=0,len=this.filters.length;i<len;++i){filters.push(this.filters[i].clone());}
60843 return new OpenLayers.Filter.Logical({type:this.type,filters:filters});},CLASS_NAME:"OpenLayers.Filter.Logical"});OpenLayers.Filter.Logical.AND="&&";OpenLayers.Filter.Logical.OR="||";OpenLayers.Filter.Logical.NOT="!";OpenLayers.Filter.Spatial=OpenLayers.Class(OpenLayers.Filter,{type:null,property:null,value:null,distance:null,distanceUnits:null,initialize:function(options){OpenLayers.Filter.prototype.initialize.apply(this,[options]);},evaluate:function(feature){var intersect=false;switch(this.type){case OpenLayers.Filter.Spatial.BBOX:case OpenLayers.Filter.Spatial.INTERSECTS:if(feature.geometry){var geom=this.value;if(this.value.CLASS_NAME=="OpenLayers.Bounds"){geom=this.value.toGeometry();}
60844 if(feature.geometry.intersects(geom)){intersect=true;}}
60845 break;default:OpenLayers.Console.error(OpenLayers.i18n("filterEvaluateNotImplemented"));break;}
60846 return intersect;},clone:function(){var options=OpenLayers.Util.applyDefaults({value:this.value&&this.value.clone&&this.value.clone()},this);return new OpenLayers.Filter.Spatial(options);},CLASS_NAME:"OpenLayers.Filter.Spatial"});OpenLayers.Filter.Spatial.BBOX="BBOX";OpenLayers.Filter.Spatial.INTERSECTS="INTERSECTS";OpenLayers.Filter.Spatial.DWITHIN="DWITHIN";OpenLayers.Filter.Spatial.WITHIN="WITHIN";OpenLayers.Filter.Spatial.CONTAINS="CONTAINS";OpenLayers.Geometry.Collection=OpenLayers.Class(OpenLayers.Geometry,{components:null,componentTypes:null,initialize:function(components){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.components=[];if(components!=null){this.addComponents(components);}},destroy:function(){this.components.length=0;this.components=null;OpenLayers.Geometry.prototype.destroy.apply(this,arguments);},clone:function(){var geometry=eval("new "+this.CLASS_NAME+"()");for(var i=0,len=this.components.length;i<len;i++){geometry.addComponent(this.components[i].clone());}
60847 OpenLayers.Util.applyDefaults(geometry,this);return geometry;},getComponentsString:function(){var strings=[];for(var i=0,len=this.components.length;i<len;i++){strings.push(this.components[i].toShortString());}
60848 return strings.join(",");},calculateBounds:function(){this.bounds=null;if(this.components&&this.components.length>0){this.setBounds(this.components[0].getBounds());for(var i=1,len=this.components.length;i<len;i++){this.extendBounds(this.components[i].getBounds());}}},addComponents:function(components){if(!(components instanceof Array)){components=[components];}
60849 for(var i=0,len=components.length;i<len;i++){this.addComponent(components[i]);}},addComponent:function(component,index){var added=false;if(component){if(this.componentTypes==null||(OpenLayers.Util.indexOf(this.componentTypes,component.CLASS_NAME)>-1)){if(index!=null&&(index<this.components.length)){var components1=this.components.slice(0,index);var components2=this.components.slice(index,this.components.length);components1.push(component);this.components=components1.concat(components2);}else{this.components.push(component);}
60850 component.parent=this;this.clearBounds();added=true;}}
60851 return added;},removeComponents:function(components){if(!(components instanceof Array)){components=[components];}
60852 for(var i=components.length-1;i>=0;--i){this.removeComponent(components[i]);}},removeComponent:function(component){OpenLayers.Util.removeItem(this.components,component);this.clearBounds();},getLength:function(){var length=0.0;for(var i=0,len=this.components.length;i<len;i++){length+=this.components[i].getLength();}
60853 return length;},getArea:function(){var area=0.0;for(var i=0,len=this.components.length;i<len;i++){area+=this.components[i].getArea();}
60854 return area;},getGeodesicArea:function(projection){var area=0.0;for(var i=0,len=this.components.length;i<len;i++){area+=this.components[i].getGeodesicArea(projection);}
60855 return area;},getCentroid:function(weighted){if(!weighted){return this.components.length&&this.components[0].getCentroid();}
60856 var len=this.components.length;if(!len){return false;}
60857 var areas=[];var centroids=[];var areaSum=0;var minArea=Number.MAX_VALUE;var component;for(var i=0;i<len;++i){component=this.components[i];var area=component.getArea();var centroid=component.getCentroid(true);if(isNaN(area)||isNaN(centroid.x)||isNaN(centroid.y)){continue;}
60858 areas.push(area);areaSum+=area;minArea=(area<minArea&&area>0)?area:minArea;centroids.push(centroid);}
60859 len=areas.length;if(areaSum===0){for(var i=0;i<len;++i){areas[i]=1;}
60860 areaSum=areas.length;}else{for(var i=0;i<len;++i){areas[i]/=minArea;}
60861 areaSum/=minArea;}
60862 var xSum=0,ySum=0,centroid,area;for(var i=0;i<len;++i){centroid=centroids[i];area=areas[i];xSum+=centroid.x*area;ySum+=centroid.y*area;}
60863 return new OpenLayers.Geometry.Point(xSum/areaSum,ySum/areaSum);},getGeodesicLength:function(projection){var length=0.0;for(var i=0,len=this.components.length;i<len;i++){length+=this.components[i].getGeodesicLength(projection);}
60864 return length;},move:function(x,y){for(var i=0,len=this.components.length;i<len;i++){this.components[i].move(x,y);}},rotate:function(angle,origin){for(var i=0,len=this.components.length;i<len;++i){this.components[i].rotate(angle,origin);}},resize:function(scale,origin,ratio){for(var i=0;i<this.components.length;++i){this.components[i].resize(scale,origin,ratio);}
60865 return this;},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var details=edge&&options&&options.details;var result,best,distance;var min=Number.POSITIVE_INFINITY;for(var i=0,len=this.components.length;i<len;++i){result=this.components[i].distanceTo(geometry,options);distance=details?result.distance:result;if(distance<min){min=distance;best=result;if(min==0){break;}}}
60866 return best;},equals:function(geometry){var equivalent=true;if(!geometry||!geometry.CLASS_NAME||(this.CLASS_NAME!=geometry.CLASS_NAME)){equivalent=false;}else if(!(geometry.components instanceof Array)||(geometry.components.length!=this.components.length)){equivalent=false;}else{for(var i=0,len=this.components.length;i<len;++i){if(!this.components[i].equals(geometry.components[i])){equivalent=false;break;}}}
60867 return equivalent;},transform:function(source,dest){if(source&&dest){for(var i=0,len=this.components.length;i<len;i++){var component=this.components[i];component.transform(source,dest);}
60868 this.bounds=null;}
60869 return this;},intersects:function(geometry){var intersect=false;for(var i=0,len=this.components.length;i<len;++i){intersect=geometry.intersects(this.components[i]);if(intersect){break;}}
60870 return intersect;},getVertices:function(nodes){var vertices=[];for(var i=0,len=this.components.length;i<len;++i){Array.prototype.push.apply(vertices,this.components[i].getVertices(nodes));}
60871 return vertices;},CLASS_NAME:"OpenLayers.Geometry.Collection"});OpenLayers.Geometry.Point=OpenLayers.Class(OpenLayers.Geometry,{x:null,y:null,initialize:function(x,y){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.x=parseFloat(x);this.y=parseFloat(y);},clone:function(obj){if(obj==null){obj=new OpenLayers.Geometry.Point(this.x,this.y);}
60872 OpenLayers.Util.applyDefaults(obj,this);return obj;},calculateBounds:function(){this.bounds=new OpenLayers.Bounds(this.x,this.y,this.x,this.y);},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var details=edge&&options&&options.details;var distance,x0,y0,x1,y1,result;if(geometry instanceof OpenLayers.Geometry.Point){x0=this.x;y0=this.y;x1=geometry.x;y1=geometry.y;distance=Math.sqrt(Math.pow(x0-x1,2)+Math.pow(y0-y1,2));result=!details?distance:{x0:x0,y0:y0,x1:x1,y1:y1,distance:distance};}else{result=geometry.distanceTo(this,options);if(details){result={x0:result.x1,y0:result.y1,x1:result.x0,y1:result.y0,distance:result.distance};}}
60873 return result;},equals:function(geom){var equals=false;if(geom!=null){equals=((this.x==geom.x&&this.y==geom.y)||(isNaN(this.x)&&isNaN(this.y)&&isNaN(geom.x)&&isNaN(geom.y)));}
60874 return equals;},toShortString:function(){return(this.x+", "+this.y);},move:function(x,y){this.x=this.x+x;this.y=this.y+y;this.clearBounds();},rotate:function(angle,origin){angle*=Math.PI/180;var radius=this.distanceTo(origin);var theta=angle+Math.atan2(this.y-origin.y,this.x-origin.x);this.x=origin.x+(radius*Math.cos(theta));this.y=origin.y+(radius*Math.sin(theta));this.clearBounds();},getCentroid:function(){return new OpenLayers.Geometry.Point(this.x,this.y);},resize:function(scale,origin,ratio){ratio=(ratio==undefined)?1:ratio;this.x=origin.x+(scale*ratio*(this.x-origin.x));this.y=origin.y+(scale*(this.y-origin.y));this.clearBounds();return this;},intersects:function(geometry){var intersect=false;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){intersect=this.equals(geometry);}else{intersect=geometry.intersects(this);}
60875 return intersect;},transform:function(source,dest){if((source&&dest)){OpenLayers.Projection.transform(this,source,dest);this.bounds=null;}
60876 return this;},getVertices:function(nodes){return[this];},CLASS_NAME:"OpenLayers.Geometry.Point"});OpenLayers.Geometry.Rectangle=OpenLayers.Class(OpenLayers.Geometry,{x:null,y:null,width:null,height:null,initialize:function(x,y,width,height){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.x=x;this.y=y;this.width=width;this.height=height;},calculateBounds:function(){this.bounds=new OpenLayers.Bounds(this.x,this.y,this.x+this.width,this.y+this.height);},getLength:function(){var length=(2*this.width)+(2*this.height);return length;},getArea:function(){var area=this.width*this.height;return area;},CLASS_NAME:"OpenLayers.Geometry.Rectangle"});OpenLayers.Geometry.Surface=OpenLayers.Class(OpenLayers.Geometry,{initialize:function(){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Geometry.Surface"});OpenLayers.Layer.KaMapCache=OpenLayers.Class(OpenLayers.Layer.KaMap,{IMAGE_EXTENSIONS:{'jpeg':'jpg','gif':'gif','png':'png','png8':'png','png24':'png','dithered':'png'},DEFAULT_FORMAT:'jpeg',initialize:function(name,url,params,options){OpenLayers.Layer.KaMap.prototype.initialize.apply(this,arguments);this.extension=this.IMAGE_EXTENSIONS[this.params.i.toLowerCase()||DEFAULT_FORMAT];},getURL:function(bounds){bounds=this.adjustBounds(bounds);var mapRes=this.map.getResolution();var scale=Math.round((this.map.getScale()*10000))/10000;var pX=Math.round(bounds.left/mapRes);var pY=-Math.round(bounds.top/mapRes);var metaX=Math.floor(pX/this.tileSize.w/this.params.metaTileSize.w)*this.tileSize.w*this.params.metaTileSize.w;var metaY=Math.floor(pY/this.tileSize.h/this.params.metaTileSize.h)*this.tileSize.h*this.params.metaTileSize.h;var url=this.url;if(url instanceof Array){url=this.selectUrl(paramsString,url);}
60877 var components=[url,"/",this.params.map,"/",scale,"/",this.params.g.replace(/\s/g,'_'),"/def/t",metaY,"/l",metaX,"/t",pY,"l",pX,".",this.extension];return components.join("");},CLASS_NAME:"OpenLayers.Layer.KaMapCache"});OpenLayers.Layer.MapServer.Untiled=OpenLayers.Class(OpenLayers.Layer.MapServer,{singleTile:true,initialize:function(name,url,params,options){OpenLayers.Layer.MapServer.prototype.initialize.apply(this,arguments);var msg="The OpenLayers.Layer.MapServer.Untiled class is deprecated and "+"will be removed in 3.0. Instead, you should use the "+"normal OpenLayers.Layer.MapServer class, passing it the option "+"'singleTile' as true.";OpenLayers.Console.warn(msg);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.MapServer.Untiled(this.name,this.url,this.params,this.getOptions());}
60878 obj=OpenLayers.Layer.MapServer.prototype.clone.apply(this,[obj]);return obj;},CLASS_NAME:"OpenLayers.Layer.MapServer.Untiled"});OpenLayers.Layer.Vector=OpenLayers.Class(OpenLayers.Layer,{EVENT_TYPES:["beforefeatureadded","beforefeaturesadded","featureadded","featuresadded","beforefeatureremoved","beforefeaturesremoved","featureremoved","featuresremoved","beforefeatureselected","featureselected","featureunselected","beforefeaturemodified","featuremodified","afterfeaturemodified","vertexmodified","sketchstarted","sketchmodified","sketchcomplete","refresh"],isBaseLayer:false,isFixed:false,isVector:true,features:null,filter:null,selectedFeatures:null,unrenderedFeatures:null,reportError:true,style:null,styleMap:null,strategies:null,protocol:null,renderers:['SVG','VML','Canvas'],renderer:null,rendererOptions:null,geometryType:null,drawn:false,initialize:function(name,options){this.EVENT_TYPES=OpenLayers.Layer.Vector.prototype.EVENT_TYPES.concat(OpenLayers.Layer.prototype.EVENT_TYPES);OpenLayers.Layer.prototype.initialize.apply(this,arguments);if(!this.renderer||!this.renderer.supported()){this.assignRenderer();}
60879 if(!this.renderer||!this.renderer.supported()){this.renderer=null;this.displayError();}
60880 if(!this.styleMap){this.styleMap=new OpenLayers.StyleMap();}
60881 this.features=[];this.selectedFeatures=[];this.unrenderedFeatures={};if(this.strategies){for(var i=0,len=this.strategies.length;i<len;i++){this.strategies[i].setLayer(this);}}},destroy:function(){if(this.strategies){var strategy,i,len;for(i=0,len=this.strategies.length;i<len;i++){strategy=this.strategies[i];if(strategy.autoDestroy){strategy.destroy();}}
60882 this.strategies=null;}
60883 if(this.protocol){if(this.protocol.autoDestroy){this.protocol.destroy();}
60884 this.protocol=null;}
60885 this.destroyFeatures();this.features=null;this.selectedFeatures=null;this.unrenderedFeatures=null;if(this.renderer){this.renderer.destroy();}
60886 this.renderer=null;this.geometryType=null;this.drawn=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Vector(this.name,this.getOptions());}
60887 obj=OpenLayers.Layer.prototype.clone.apply(this,[obj]);var features=this.features;var len=features.length;var clonedFeatures=new Array(len);for(var i=0;i<len;++i){clonedFeatures[i]=features[i].clone();}
60888 obj.features=clonedFeatures;return obj;},refresh:function(obj){if(this.calculateInRange()&&this.visibility){this.events.triggerEvent("refresh",obj);}},assignRenderer:function(){for(var i=0,len=this.renderers.length;i<len;i++){var rendererClass=this.renderers[i];var renderer=(typeof rendererClass=="function")?rendererClass:OpenLayers.Renderer[rendererClass];if(renderer&&renderer.prototype.supported()){this.renderer=new renderer(this.div,this.rendererOptions);break;}}},displayError:function(){if(this.reportError){OpenLayers.Console.userError(OpenLayers.i18n("browserNotSupported",{'renderers':this.renderers.join("\n")}));}},setMap:function(map){OpenLayers.Layer.prototype.setMap.apply(this,arguments);if(!this.renderer){this.map.removeLayer(this);}else{this.renderer.map=this.map;this.renderer.setSize(this.map.getSize());}},afterAdd:function(){if(this.strategies){var strategy,i,len;for(i=0,len=this.strategies.length;i<len;i++){strategy=this.strategies[i];if(strategy.autoActivate){strategy.activate();}}}},removeMap:function(map){this.drawn=false;if(this.strategies){var strategy,i,len;for(i=0,len=this.strategies.length;i<len;i++){strategy=this.strategies[i];if(strategy.autoActivate){strategy.deactivate();}}}},onMapResize:function(){OpenLayers.Layer.prototype.onMapResize.apply(this,arguments);this.renderer.setSize(this.map.getSize());},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);var coordSysUnchanged=true;if(!dragging){this.renderer.root.style.visibility="hidden";this.div.style.left=-parseInt(this.map.layerContainerDiv.style.left)+"px";this.div.style.top=-parseInt(this.map.layerContainerDiv.style.top)+"px";var extent=this.map.getExtent();coordSysUnchanged=this.renderer.setExtent(extent,zoomChanged);this.renderer.root.style.visibility="visible";if(navigator.userAgent.toLowerCase().indexOf("gecko")!=-1){this.div.scrollLeft=this.div.scrollLeft;}
60889 if(!zoomChanged&&coordSysUnchanged){for(var i in this.unrenderedFeatures){var feature=this.unrenderedFeatures[i];this.drawFeature(feature);}}}
60890 if(!this.drawn||zoomChanged||!coordSysUnchanged){this.drawn=true;var feature;for(var i=0,len=this.features.length;i<len;i++){this.renderer.locked=(i!==(len-1));feature=this.features[i];this.drawFeature(feature);}}},display:function(display){OpenLayers.Layer.prototype.display.apply(this,arguments);var currentDisplay=this.div.style.display;if(currentDisplay!=this.renderer.root.style.display){this.renderer.root.style.display=currentDisplay;}},addFeatures:function(features,options){if(!(features instanceof Array)){features=[features];}
60891 var notify=!options||!options.silent;if(notify){var event={features:features};var ret=this.events.triggerEvent("beforefeaturesadded",event);if(ret===false){return;}
60892 features=event.features;}
60893 var featuresAdded=[];for(var i=0,len=features.length;i<len;i++){if(i!=(features.length-1)){this.renderer.locked=true;}else{this.renderer.locked=false;}
60894 var feature=features[i];if(this.geometryType&&!(feature.geometry instanceof this.geometryType)){var throwStr=OpenLayers.i18n('componentShouldBe',{'geomType':this.geometryType.prototype.CLASS_NAME});throw throwStr;}
60895 feature.layer=this;if(!feature.style&&this.style){feature.style=OpenLayers.Util.extend({},this.style);}
60896 if(notify){if(this.events.triggerEvent("beforefeatureadded",{feature:feature})===false){continue;};this.preFeatureInsert(feature);}
60897 featuresAdded.push(feature);this.features.push(feature);this.drawFeature(feature);if(notify){this.events.triggerEvent("featureadded",{feature:feature});this.onFeatureInsert(feature);}}
60898 if(notify){this.events.triggerEvent("featuresadded",{features:featuresAdded});}},removeFeatures:function(features,options){if(!features||features.length===0){return;}
60899 if(features===this.features){return this.removeAllFeatures(options);}
60900 if(!(features instanceof Array)){features=[features];}
60901 if(features===this.selectedFeatures){features=features.slice();}
60902 var notify=!options||!options.silent;if(notify){this.events.triggerEvent("beforefeaturesremoved",{features:features});}
60903 for(var i=features.length-1;i>=0;i--){if(i!=0&&features[i-1].geometry){this.renderer.locked=true;}else{this.renderer.locked=false;}
60904 var feature=features[i];delete this.unrenderedFeatures[feature.id];if(notify){this.events.triggerEvent("beforefeatureremoved",{feature:feature});}
60905 this.features=OpenLayers.Util.removeItem(this.features,feature);feature.layer=null;if(feature.geometry){this.renderer.eraseFeatures(feature);}
60906 if(OpenLayers.Util.indexOf(this.selectedFeatures,feature)!=-1){OpenLayers.Util.removeItem(this.selectedFeatures,feature);}
60907 if(notify){this.events.triggerEvent("featureremoved",{feature:feature});}}
60908 if(notify){this.events.triggerEvent("featuresremoved",{features:features});}},removeAllFeatures:function(options){var notify=!options||!options.silent;var features=this.features;if(notify){this.events.triggerEvent("beforefeaturesremoved",{features:features});}
60909 var feature;for(var i=features.length-1;i>=0;i--){feature=features[i];if(notify){this.events.triggerEvent("beforefeatureremoved",{feature:feature});}
60910 feature.layer=null;if(notify){this.events.triggerEvent("featureremoved",{feature:feature});}}
60911 this.renderer.clear();this.features=[];this.unrenderedFeatures={};this.selectedFeatures=[];if(notify){this.events.triggerEvent("featuresremoved",{features:features});}},destroyFeatures:function(features,options){var all=(features==undefined);if(all){features=this.features;}
60912 if(features){this.removeFeatures(features,options);for(var i=features.length-1;i>=0;i--){features[i].destroy();}}},drawFeature:function(feature,style){if(!this.drawn){return}
60913 if(typeof style!="object"){if(!style&&feature.state===OpenLayers.State.DELETE){style="delete";}
60914 var renderIntent=style||feature.renderIntent;style=feature.style||this.style;if(!style){style=this.styleMap.createSymbolizer(feature,renderIntent);}}
60915 if(!this.renderer.drawFeature(feature,style)){this.unrenderedFeatures[feature.id]=feature;}else{delete this.unrenderedFeatures[feature.id];};},eraseFeatures:function(features){this.renderer.eraseFeatures(features);},getFeatureFromEvent:function(evt){if(!this.renderer){OpenLayers.Console.error(OpenLayers.i18n("getFeatureError"));return null;}
60916 var featureId=this.renderer.getFeatureIdFromEvent(evt);return this.getFeatureById(featureId);},getFeatureBy:function(property,value){var feature=null;for(var i=0,len=this.features.length;i<len;++i){if(this.features[i][property]==value){feature=this.features[i];break;}}
60917 return feature;},getFeatureById:function(featureId){return this.getFeatureBy('id',featureId);},getFeatureByFid:function(featureFid){return this.getFeatureBy('fid',featureFid);},onFeatureInsert:function(feature){},preFeatureInsert:function(feature){},getDataExtent:function(){var maxExtent=null;var features=this.features;if(features&&(features.length>0)){maxExtent=new OpenLayers.Bounds();var geometry=null;for(var i=0,len=features.length;i<len;i++){geometry=features[i].geometry;if(geometry){maxExtent.extend(geometry.getBounds());}}}
60918 return maxExtent;},CLASS_NAME:"OpenLayers.Layer.Vector"});OpenLayers.Layer.WMS.Post=OpenLayers.Class(OpenLayers.Layer.WMS,{tileClass:null,unsupportedBrowsers:["mozilla","firefox","opera"],SUPPORTED_TRANSITIONS:[],initialize:function(name,url,params,options){var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.WMS.prototype.initialize.apply(this,newArguments);this.tileClass=OpenLayers.Util.indexOf(this.unsupportedBrowsers,OpenLayers.Util.getBrowserName())!=-1?OpenLayers.Tile.Image:OpenLayers.Tile.Image.IFrame;},addTile:function(bounds,position){return new this.tileClass(this,position,bounds,null,this.tileSize);},CLASS_NAME:'OpenLayers.Layer.WMS.Post'});OpenLayers.Layer.WMS.Untiled=OpenLayers.Class(OpenLayers.Layer.WMS,{singleTile:true,initialize:function(name,url,params,options){OpenLayers.Layer.WMS.prototype.initialize.apply(this,arguments);var msg="The OpenLayers.Layer.WMS.Untiled class is deprecated and "+"will be removed in 3.0. Instead, you should use the "+"normal OpenLayers.Layer.WMS class, passing it the option "+"'singleTile' as true.";OpenLayers.Console.warn(msg);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WMS.Untiled(this.name,this.url,this.params,this.getOptions());}
60919 obj=OpenLayers.Layer.WMS.prototype.clone.apply(this,[obj]);return obj;},CLASS_NAME:"OpenLayers.Layer.WMS.Untiled"});OpenLayers.Strategy.Filter=OpenLayers.Class(OpenLayers.Strategy,{filter:null,cache:null,caching:false,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);if(!this.filter||!(this.filter instanceof OpenLayers.Filter)){throw new Error("Filter strategy must be constructed with a filter");}},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.apply(this,arguments);if(activated){this.cache=[];this.layer.events.on({"beforefeaturesadded":this.handleAdd,"beforefeaturesremoved":this.handleRemove,scope:this});}
60920 return activated;},deactivate:function(){this.cache=null;if(this.layer&&this.layer.events){this.layer.events.un({"beforefeaturesadded":this.handleAdd,"beforefeaturesremoved":this.handleRemove,scope:this});}
60921 return OpenLayers.Strategy.prototype.deactivate.apply(this,arguments);},handleAdd:function(event){if(!this.caching){var features=event.features;event.features=[];var feature;for(var i=0,ii=features.length;i<ii;++i){feature=features[i];if(this.filter.evaluate(feature)){event.features.push(feature);}else{this.cache.push(feature);}}}},handleRemove:function(event){if(!this.caching){this.cache=[];}},setFilter:function(filter){this.filter=filter;var previousCache=this.cache;this.cache=[];this.handleAdd({features:this.layer.features});if(this.cache.length>0){this.caching=true;this.layer.removeFeatures(this.cache.slice(),{silent:true});this.caching=false;}
60922 if(previousCache.length>0){var event={features:previousCache};this.handleAdd(event);this.caching=true;this.layer.addFeatures(event.features,{silent:true});this.caching=false;}},CLASS_NAME:"OpenLayers.Strategy.Filter"});OpenLayers.Style2=OpenLayers.Class({id:null,name:null,title:null,description:null,layerName:null,isDefault:false,rules:null,initialize:function(config){OpenLayers.Util.extend(this,config);this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){for(var i=0,len=this.rules.length;i<len;i++){this.rules[i].destroy();}
60923 delete this.rules;},clone:function(){var config=OpenLayers.Util.extend({},this);if(this.rules){config.rules=[];for(var i=0,len=this.rules.length;i<len;++i){config.rules.push(this.rules[i].clone());}}
60924 return new OpenLayers.Style2(config);},CLASS_NAME:"OpenLayers.Style2"});OpenLayers.Control.GetFeature=OpenLayers.Class(OpenLayers.Control,{protocol:null,multipleKey:null,toggleKey:null,modifiers:null,multiple:false,click:true,single:true,clickout:true,toggle:false,clickTolerance:5,hover:false,box:false,maxFeatures:10,features:null,hoverFeature:null,handlerOptions:null,handlers:null,hoverResponse:null,filterType:OpenLayers.Filter.Spatial.BBOX,EVENT_TYPES:["featureselected","featuresselected","featureunselected","clickout","beforefeatureselected","beforefeaturesselected","hoverfeature","outfeature"],initialize:function(options){this.EVENT_TYPES=OpenLayers.Control.GetFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);options.handlerOptions=options.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[options]);this.features={};this.handlers={};if(this.click){this.handlers.click=new OpenLayers.Handler.Click(this,{click:this.selectClick},this.handlerOptions.click||{});}
60925 if(this.box){this.handlers.box=new OpenLayers.Handler.Box(this,{done:this.selectBox},OpenLayers.Util.extend(this.handlerOptions.box,{boxDivClassName:"olHandlerBoxSelectFeature"}));}
60926 if(this.hover){this.handlers.hover=new OpenLayers.Handler.Hover(this,{'move':this.cancelHover,'pause':this.selectHover},OpenLayers.Util.extend(this.handlerOptions.hover,{'delay':250}));}},activate:function(){if(!this.active){for(var i in this.handlers){this.handlers[i].activate();}}
60927 return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){if(this.active){for(var i in this.handlers){this.handlers[i].deactivate();}}
60928 return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},selectClick:function(evt){var bounds=this.pixelToBounds(evt.xy);this.setModifiers(evt);this.request(bounds,{single:this.single});},selectBox:function(position){var bounds;if(position instanceof OpenLayers.Bounds){var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat);}else{if(this.click){return;}
60929 bounds=this.pixelToBounds(position);}
60930 this.setModifiers(this.handlers.box.dragHandler.evt);this.request(bounds);},selectHover:function(evt){var bounds=this.pixelToBounds(evt.xy);this.request(bounds,{single:true,hover:true});},cancelHover:function(){if(this.hoverResponse){this.protocol.abort(this.hoverResponse);this.hoverResponse=null;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");}},request:function(bounds,options){options=options||{};var filter=new OpenLayers.Filter.Spatial({type:this.filterType,value:bounds});OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");var response=this.protocol.read({maxFeatures:options.single==true?this.maxFeatures:undefined,filter:filter,callback:function(result){if(result.success()){if(result.features.length){if(options.single==true){this.selectBestFeature(result.features,bounds.getCenterLonLat(),options);}else{this.select(result.features);}}else if(options.hover){this.hoverSelect();}else{this.events.triggerEvent("clickout");if(this.clickout){this.unselectAll();}}}
60931 OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");},scope:this});if(options.hover==true){this.hoverResponse=response;}},selectBestFeature:function(features,clickPosition,options){options=options||{};if(features.length){var point=new OpenLayers.Geometry.Point(clickPosition.lon,clickPosition.lat);var feature,resultFeature,dist;var minDist=Number.MAX_VALUE;for(var i=0;i<features.length;++i){feature=features[i];if(feature.geometry){dist=point.distanceTo(feature.geometry,{edge:false});if(dist<minDist){minDist=dist;resultFeature=feature;if(minDist==0){break;}}}}
60932 if(options.hover==true){this.hoverSelect(resultFeature);}else{this.select(resultFeature||features);}}},setModifiers:function(evt){this.modifiers={multiple:this.multiple||(this.multipleKey&&evt[this.multipleKey]),toggle:this.toggle||(this.toggleKey&&evt[this.toggleKey])};},select:function(features){if(!this.modifiers.multiple&&!this.modifiers.toggle){this.unselectAll();}
60933 if(!(features instanceof Array)){features=[features];}
60934 var cont=this.events.triggerEvent("beforefeaturesselected",{features:features});if(cont!==false){var selectedFeatures=[];var feature;for(var i=0,len=features.length;i<len;++i){feature=features[i];if(this.features[feature.fid||feature.id]){if(this.modifiers.toggle){this.unselect(this.features[feature.fid||feature.id]);}}else{cont=this.events.triggerEvent("beforefeatureselected",{feature:feature});if(cont!==false){this.features[feature.fid||feature.id]=feature;selectedFeatures.push(feature);this.events.triggerEvent("featureselected",{feature:feature});}}}
60935 this.events.triggerEvent("featuresselected",{features:selectedFeatures});}},hoverSelect:function(feature){var fid=feature?feature.fid||feature.id:null;var hfid=this.hoverFeature?this.hoverFeature.fid||this.hoverFeature.id:null;if(hfid&&hfid!=fid){this.events.triggerEvent("outfeature",{feature:this.hoverFeature});this.hoverFeature=null;}
60936 if(fid&&fid!=hfid){this.events.triggerEvent("hoverfeature",{feature:feature});this.hoverFeature=feature;}},unselect:function(feature){delete this.features[feature.fid||feature.id];this.events.triggerEvent("featureunselected",{feature:feature});},unselectAll:function(){for(var fid in this.features){this.unselect(this.features[fid]);}},setMap:function(map){for(var i in this.handlers){this.handlers[i].setMap(map);}
60937 OpenLayers.Control.prototype.setMap.apply(this,arguments);},pixelToBounds:function(pixel){var llPx=pixel.add(-this.clickTolerance/2,this.clickTolerance/2);var urPx=pixel.add(this.clickTolerance/2,-this.clickTolerance/2);var ll=this.map.getLonLatFromPixel(llPx);var ur=this.map.getLonLatFromPixel(urPx);return new OpenLayers.Bounds(ll.lon,ll.lat,ur.lon,ur.lat);},CLASS_NAME:"OpenLayers.Control.GetFeature"});OpenLayers.Control.Snapping=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforesnap","snap","unsnap"],DEFAULTS:{tolerance:10,node:true,edge:true,vertex:true},greedy:true,precedence:["node","vertex","edge"],resolution:null,geoToleranceCache:null,layer:null,feature:null,point:null,initialize:function(options){Array.prototype.push.apply(this.EVENT_TYPES,OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.options=options||{};if(this.options.layer){this.setLayer(this.options.layer);}
60938 var defaults=OpenLayers.Util.extend({},this.options.defaults);this.defaults=OpenLayers.Util.applyDefaults(defaults,this.DEFAULTS);this.setTargets(this.options.targets);if(this.targets.length===0&&this.layer){this.addTargetLayer(this.layer);}
60939 this.geoToleranceCache={};},setLayer:function(layer){if(this.active){this.deactivate();this.layer=layer;this.activate();}else{this.layer=layer;}},setTargets:function(targets){this.targets=[];if(targets&&targets.length){var target;for(var i=0,len=targets.length;i<len;++i){target=targets[i];if(target instanceof OpenLayers.Layer.Vector){this.addTargetLayer(target);}else{this.addTarget(target);}}}},addTargetLayer:function(layer){this.addTarget({layer:layer});},addTarget:function(target){target=OpenLayers.Util.applyDefaults(target,this.defaults);target.nodeTolerance=target.nodeTolerance||target.tolerance;target.vertexTolerance=target.vertexTolerance||target.tolerance;target.edgeTolerance=target.edgeTolerance||target.tolerance;this.targets.push(target);},removeTargetLayer:function(layer){var target;for(var i=this.targets.length-1;i>=0;--i){target=this.targets[i];if(target.layer===layer){this.removeTarget(target);}}},removeTarget:function(target){return OpenLayers.Util.removeItem(this.targets,target);},activate:function(){var activated=OpenLayers.Control.prototype.activate.call(this);if(activated){if(this.layer&&this.layer.events){this.layer.events.on({sketchstarted:this.onSketchModified,sketchmodified:this.onSketchModified,vertexmodified:this.onVertexModified,scope:this});}}
60940 return activated;},deactivate:function(){var deactivated=OpenLayers.Control.prototype.deactivate.call(this);if(deactivated){if(this.layer&&this.layer.events){this.layer.events.un({sketchstarted:this.onSketchModified,sketchmodified:this.onSketchModified,vertexmodified:this.onVertexModified,scope:this});}}
60941 this.feature=null;this.point=null;return deactivated;},onSketchModified:function(event){this.feature=event.feature;this.considerSnapping(event.vertex,event.vertex);},onVertexModified:function(event){this.feature=event.feature;var loc=this.layer.map.getLonLatFromViewPortPx(event.pixel);this.considerSnapping(event.vertex,new OpenLayers.Geometry.Point(loc.lon,loc.lat));},considerSnapping:function(point,loc){var best={rank:Number.POSITIVE_INFINITY,dist:Number.POSITIVE_INFINITY,x:null,y:null};var snapped=false;var result,target;for(var i=0,len=this.targets.length;i<len;++i){target=this.targets[i];result=this.testTarget(target,loc);if(result){if(this.greedy){best=result;best.target=target;snapped=true;break;}else{if((result.rank<best.rank)||(result.rank===best.rank&&result.dist<best.dist)){best=result;best.target=target;snapped=true;}}}}
60942 if(snapped){var proceed=this.events.triggerEvent("beforesnap",{point:point,x:best.x,y:best.y,distance:best.dist,layer:best.target.layer,snapType:this.precedence[best.rank]});if(proceed!==false){point.x=best.x;point.y=best.y;this.point=point;this.events.triggerEvent("snap",{point:point,snapType:this.precedence[best.rank],layer:best.target.layer,distance:best.dist});}else{snapped=false;}}
60943 if(this.point&&!snapped){point.x=loc.x;point.y=loc.y;this.point=null;this.events.triggerEvent("unsnap",{point:point});}},testTarget:function(target,loc){var tolerance={node:this.getGeoTolerance(target.nodeTolerance),vertex:this.getGeoTolerance(target.vertexTolerance),edge:this.getGeoTolerance(target.edgeTolerance)};var maxTolerance=Math.max(tolerance.node,tolerance.vertex,tolerance.edge);var result={rank:Number.POSITIVE_INFINITY,dist:Number.POSITIVE_INFINITY};var eligible=false;var features=target.layer.features;var feature,type,vertices,vertex,closest,dist,found;var numTypes=this.precedence.length;var ll=new OpenLayers.LonLat(loc.x,loc.y);for(var i=0,len=features.length;i<len;++i){feature=features[i];if(feature!==this.feature&&!feature._sketch&&feature.state!==OpenLayers.State.DELETE&&(!target.filter||target.filter.evaluate(feature.attributes))){if(feature.atPoint(ll,maxTolerance,maxTolerance)){for(var j=0,stop=Math.min(result.rank+1,numTypes);j<stop;++j){type=this.precedence[j];if(target[type]){if(type==="edge"){closest=feature.geometry.distanceTo(loc,{details:true});dist=closest.distance;if(dist<=tolerance[type]&&dist<result.dist){result={rank:j,dist:dist,x:closest.x0,y:closest.y0};eligible=true;break;}}else{vertices=feature.geometry.getVertices(type==="node");found=false;for(var k=0,klen=vertices.length;k<klen;++k){vertex=vertices[k];dist=vertex.distanceTo(loc);if(dist<=tolerance[type]&&(j<result.rank||(j===result.rank&&dist<result.dist))){result={rank:j,dist:dist,x:vertex.x,y:vertex.y};eligible=true;found=true;}}
60944 if(found){break;}}}}}}}
60945 return eligible?result:null;},getGeoTolerance:function(tolerance){var resolution=this.layer.map.getResolution();if(resolution!==this.resolution){this.resolution=resolution;this.geoToleranceCache={};}
60946 var geoTolerance=this.geoToleranceCache[tolerance];if(geoTolerance===undefined){geoTolerance=tolerance*resolution;this.geoToleranceCache[tolerance]=geoTolerance;}
60947 return geoTolerance;},destroy:function(){if(this.active){this.deactivate();}
60948 delete this.layer;delete this.targets;OpenLayers.Control.prototype.destroy.call(this);},CLASS_NAME:"OpenLayers.Control.Snapping"});OpenLayers.Format.Filter=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},write:function(filter,options){var version=(options&&options.version)||this.version||this.defaultVersion;if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.Filter["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a Filter parser for version "+
60949 version;}
60950 this.parser=new format(this.options);}
60951 return this.parser.write(filter);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60952 var version=this.version;if(!version){version=this.defaultVersion;}
60953 if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.Filter["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a Filter parser for version "+
60954 version;}
60955 this.parser=new format(this.options);}
60956 var filter=this.parser.read(data);return filter;},CLASS_NAME:"OpenLayers.Format.Filter"});OpenLayers.Format.SLD=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,namedLayersAsArray:false,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},write:function(sld,options){var version=(options&&options.version)||this.version||this.defaultVersion;if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.SLD["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a SLD parser for version "+
60957 version;}
60958 this.parser=new format(this.options);}
60959 var root=this.parser.write(sld);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},read:function(data,options){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60960 var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");if(!version){version=this.defaultVersion;}}
60961 if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.SLD["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a SLD parser for version "+
60962 version;}
60963 this.parser=new format(this.options);}
60964 var sld=this.parser.read(data,options);return sld;},CLASS_NAME:"OpenLayers.Format.SLD"});OpenLayers.Format.Text=OpenLayers.Class(OpenLayers.Format,{defaultStyle:null,extractStyles:true,initialize:function(options){options=options||{};if(options.extractStyles!==false){options.defaultStyle={'externalGraphic':OpenLayers.Util.getImagesLocation()+"marker.png",'graphicWidth':21,'graphicHeight':25,'graphicXOffset':-10.5,'graphicYOffset':-12.5};}
60965 OpenLayers.Format.prototype.initialize.apply(this,[options]);},read:function(text){var lines=text.split('\n');var columns;var features=[];for(var lcv=0;lcv<(lines.length-1);lcv++){var currLine=lines[lcv].replace(/^\s*/,'').replace(/\s*$/,'');if(currLine.charAt(0)!='#'){if(!columns){columns=currLine.split('\t');}else{var vals=currLine.split('\t');var geometry=new OpenLayers.Geometry.Point(0,0);var attributes={};var style=this.defaultStyle?OpenLayers.Util.applyDefaults({},this.defaultStyle):null;var icon,iconSize,iconOffset,overflow;var set=false;for(var valIndex=0;valIndex<vals.length;valIndex++){if(vals[valIndex]){if(columns[valIndex]=='point'){var coords=vals[valIndex].split(',');geometry.y=parseFloat(coords[0]);geometry.x=parseFloat(coords[1]);set=true;}else if(columns[valIndex]=='lat'){geometry.y=parseFloat(vals[valIndex]);set=true;}else if(columns[valIndex]=='lon'){geometry.x=parseFloat(vals[valIndex]);set=true;}else if(columns[valIndex]=='title')
60966 attributes['title']=vals[valIndex];else if(columns[valIndex]=='image'||columns[valIndex]=='icon'&&style){style['externalGraphic']=vals[valIndex];}else if(columns[valIndex]=='iconSize'&&style){var size=vals[valIndex].split(',');style['graphicWidth']=parseFloat(size[0]);style['graphicHeight']=parseFloat(size[1]);}else if(columns[valIndex]=='iconOffset'&&style){var offset=vals[valIndex].split(',');style['graphicXOffset']=parseFloat(offset[0]);style['graphicYOffset']=parseFloat(offset[1]);}else if(columns[valIndex]=='description'){attributes['description']=vals[valIndex];}else if(columns[valIndex]=='overflow'){attributes['overflow']=vals[valIndex];}else{attributes[columns[valIndex]]=vals[valIndex];}}}
60967 if(set){if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}
60968 var feature=new OpenLayers.Feature.Vector(geometry,attributes,style);features.push(feature);}}}}
60969 return features;},CLASS_NAME:"OpenLayers.Format.Text"});OpenLayers.Geometry.MultiPoint=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.Point"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},addPoint:function(point,index){this.addComponent(point,index);},removePoint:function(point){this.removeComponent(point);},CLASS_NAME:"OpenLayers.Geometry.MultiPoint"});OpenLayers.Handler.Point=OpenLayers.Class(OpenLayers.Handler,{point:null,layer:null,multi:false,drawing:false,mouseDown:false,lastDown:null,lastUp:null,persist:false,layerOptions:null,initialize:function(control,callbacks,options){if(!(options&&options.layerOptions&&options.layerOptions.styleMap)){this.style=OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'],{});}
60970 OpenLayers.Handler.prototype.initialize.apply(this,arguments);},activate:function(){if(!OpenLayers.Handler.prototype.activate.apply(this,arguments)){return false;}
60971 var options=OpenLayers.Util.extend({displayInLayerSwitcher:false,calculateInRange:OpenLayers.Function.True},this.layerOptions);this.layer=new OpenLayers.Layer.Vector(this.CLASS_NAME,options);this.map.addLayer(this.layer);return true;},createFeature:function(pixel){var lonlat=this.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.callback("create",[this.point.geometry,this.point]);this.point.geometry.clearBounds();this.layer.addFeatures([this.point],{silent:true});},deactivate:function(){if(!OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){return false;}
60972 if(this.drawing){this.cancel();}
60973 this.destroyFeature();if(this.layer.map!=null){this.layer.destroy(false);}
60974 this.layer=null;return true;},destroyFeature:function(){if(this.layer){this.layer.destroyFeatures();}
60975 this.point=null;},finalize:function(cancel){var key=cancel?"cancel":"done";this.drawing=false;this.mouseDown=false;this.lastDown=null;this.lastUp=null;this.callback(key,[this.geometryClone()]);if(cancel||!this.persist){this.destroyFeature();}},cancel:function(){this.finalize(true);},click:function(evt){OpenLayers.Event.stop(evt);return false;},dblclick:function(evt){OpenLayers.Event.stop(evt);return false;},modifyFeature:function(pixel){var lonlat=this.map.getLonLatFromPixel(pixel);this.point.geometry.x=lonlat.lon;this.point.geometry.y=lonlat.lat;this.callback("modify",[this.point.geometry,this.point]);this.point.geometry.clearBounds();this.drawFeature();},drawFeature:function(){this.layer.drawFeature(this.point,this.style);},getGeometry:function(){var geometry=this.point&&this.point.geometry;if(geometry&&this.multi){geometry=new OpenLayers.Geometry.MultiPoint([geometry]);}
60976 return geometry;},geometryClone:function(){var geom=this.getGeometry();return geom&&geom.clone();},mousedown:function(evt){if(!this.checkModifiers(evt)){return true;}
60977 if(this.lastDown&&this.lastDown.equals(evt.xy)){return true;}
60978 this.drawing=true;if(this.lastDown==null){if(this.persist){this.destroyFeature();}
60979 this.createFeature(evt.xy);}else{this.modifyFeature(evt.xy);}
60980 this.lastDown=evt.xy;return false;},mousemove:function(evt){if(this.drawing){this.modifyFeature(evt.xy);}
60981 return true;},mouseup:function(evt){if(this.drawing){this.finalize();return false;}else{return true;}},CLASS_NAME:"OpenLayers.Handler.Point"});OpenLayers.Layer.GML=OpenLayers.Class(OpenLayers.Layer.Vector,{loaded:false,format:null,formatOptions:null,initialize:function(name,url,options){var newArguments=[];newArguments.push(name,options);OpenLayers.Layer.Vector.prototype.initialize.apply(this,newArguments);this.url=url;},setVisibility:function(visibility,noEvent){OpenLayers.Layer.Vector.prototype.setVisibility.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadGML();}},moveTo:function(bounds,zoomChanged,minor){OpenLayers.Layer.Vector.prototype.moveTo.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadGML();}},loadGML:function(){if(!this.loaded){this.events.triggerEvent("loadstart");OpenLayers.Request.GET({url:this.url,success:this.requestSuccess,failure:this.requestFailure,scope:this});this.loaded=true;}},setUrl:function(url){this.url=url;this.destroyFeatures();this.loaded=false;this.loadGML();},requestSuccess:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
60982 var options={};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
60983 var gml=this.format?new this.format(options):new OpenLayers.Format.GML(options);this.addFeatures(gml.read(doc));this.events.triggerEvent("loadend");},requestFailure:function(request){OpenLayers.Console.userError(OpenLayers.i18n("errorLoadingGML",{'url':this.url}));this.events.triggerEvent("loadend");},CLASS_NAME:"OpenLayers.Layer.GML"});OpenLayers.Layer.PointTrack=OpenLayers.Class(OpenLayers.Layer.Vector,{dataFrom:null,initialize:function(name,options){OpenLayers.Layer.Vector.prototype.initialize.apply(this,arguments);},addNodes:function(pointFeatures){if(pointFeatures.length<2){OpenLayers.Console.error("At least two point features have to be added to create"+"a line from");return;}
60984 var lines=new Array(pointFeatures.length-1);var pointFeature,startPoint,endPoint;for(var i=0,len=pointFeatures.length;i<len;i++){pointFeature=pointFeatures[i];endPoint=pointFeature.geometry;if(!endPoint){var lonlat=pointFeature.lonlat;endPoint=new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);}else if(endPoint.CLASS_NAME!="OpenLayers.Geometry.Point"){OpenLayers.Console.error("Only features with point geometries are supported.");return;}
60985 if(i>0){var attributes=(this.dataFrom!=null)?(pointFeatures[i+this.dataFrom].data||pointFeatures[i+this.dataFrom].attributes):null;var line=new OpenLayers.Geometry.LineString([startPoint,endPoint]);lines[i-1]=new OpenLayers.Feature.Vector(line,attributes);}
60986 startPoint=endPoint;}
60987 this.addFeatures(lines);},CLASS_NAME:"OpenLayers.Layer.PointTrack"});OpenLayers.Layer.PointTrack.dataFrom={'SOURCE_NODE':-1,'TARGET_NODE':0};OpenLayers.Layer.Vector.RootContainer=OpenLayers.Class(OpenLayers.Layer.Vector,{displayInLayerSwitcher:false,layers:null,initialize:function(name,options){OpenLayers.Layer.Vector.prototype.initialize.apply(this,arguments);},display:function(){},getFeatureFromEvent:function(evt){var layers=this.layers;var feature;for(var i=0;i<layers.length;i++){feature=layers[i].getFeatureFromEvent(evt);if(feature){return feature;}}},setMap:function(map){OpenLayers.Layer.Vector.prototype.setMap.apply(this,arguments);this.collectRoots();map.events.register("changelayer",this,this.handleChangeLayer);},removeMap:function(map){map.events.unregister("changelayer",this,this.handleChangeLayer);this.resetRoots();OpenLayers.Layer.Vector.prototype.removeMap.apply(this,arguments);},collectRoots:function(){var layer;for(var i=0;i<this.map.layers.length;++i){layer=this.map.layers[i];if(OpenLayers.Util.indexOf(this.layers,layer)!=-1){layer.renderer.moveRoot(this.renderer);}}},resetRoots:function(){var layer;for(var i=0;i<this.layers.length;++i){layer=this.layers[i];if(this.renderer&&layer.renderer.getRenderLayerId()==this.id){this.renderer.moveRoot(layer.renderer);}}},handleChangeLayer:function(evt){var layer=evt.layer;if(evt.property=="order"&&OpenLayers.Util.indexOf(this.layers,layer)!=-1){this.resetRoots();this.collectRoots();}},CLASS_NAME:"OpenLayers.Layer.Vector.RootContainer"});OpenLayers.Layer.WFS=OpenLayers.Class(OpenLayers.Layer.Vector,OpenLayers.Layer.Markers,{isBaseLayer:false,tile:null,ratio:2,DEFAULT_PARAMS:{service:"WFS",version:"1.0.0",request:"GetFeature"},featureClass:null,format:null,formatObject:null,formatOptions:null,vectorMode:true,encodeBBOX:false,extractAttributes:false,initialize:function(name,url,params,options){if(options==undefined){options={};}
60988 if(options.featureClass||!OpenLayers.Layer.Vector||!OpenLayers.Feature.Vector){this.vectorMode=false;}
60989 params=OpenLayers.Util.upperCaseObject(params);OpenLayers.Util.extend(options,{'reportError':false});var newArguments=[];newArguments.push(name,options);OpenLayers.Layer.Vector.prototype.initialize.apply(this,newArguments);if(!this.renderer||!this.vectorMode){this.vectorMode=false;if(!options.featureClass){options.featureClass=OpenLayers.Feature.WFS;}
60990 OpenLayers.Layer.Markers.prototype.initialize.apply(this,newArguments);}
60991 if(this.params&&this.params.typename&&!this.options.typename){this.options.typename=this.params.typename;}
60992 if(!this.options.geometry_column){this.options.geometry_column="the_geom";}
60993 this.params=OpenLayers.Util.applyDefaults(params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS));this.url=url;},destroy:function(){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.destroy.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);}
60994 if(this.tile){this.tile.destroy();}
60995 this.tile=null;this.ratio=null;this.featureClass=null;this.format=null;if(this.formatObject&&this.formatObject.destroy){this.formatObject.destroy();}
60996 this.formatObject=null;this.formatOptions=null;this.vectorMode=null;this.encodeBBOX=null;this.extractAttributes=null;},setMap:function(map){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.setMap.apply(this,arguments);var options={'extractAttributes':this.extractAttributes};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
60997 this.formatObject=this.format?new this.format(options):new OpenLayers.Format.GML(options);}else{OpenLayers.Layer.Markers.prototype.setMap.apply(this,arguments);}},moveTo:function(bounds,zoomChanged,dragging){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.moveTo.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);}
60998 if(dragging){return false;}
60999 if(zoomChanged){if(this.vectorMode){this.renderer.clear();}}
61000 if(this.options.minZoomLevel){OpenLayers.Console.warn(OpenLayers.i18n('minZoomLevelError'));if(this.map.getZoom()<this.options.minZoomLevel){return null;}}
61001 if(bounds==null){bounds=this.map.getExtent();}
61002 var firstRendering=(this.tile==null);var outOfBounds=(!firstRendering&&!this.tile.bounds.containsBounds(bounds));if(zoomChanged||firstRendering||(!dragging&&outOfBounds)){var center=bounds.getCenterLonLat();var tileWidth=bounds.getWidth()*this.ratio;var tileHeight=bounds.getHeight()*this.ratio;var tileBounds=new OpenLayers.Bounds(center.lon-(tileWidth/2),center.lat-(tileHeight/2),center.lon+(tileWidth/2),center.lat+(tileHeight/2));var tileSize=this.map.getSize();tileSize.w=tileSize.w*this.ratio;tileSize.h=tileSize.h*this.ratio;var ul=new OpenLayers.LonLat(tileBounds.left,tileBounds.top);var pos=this.map.getLayerPxFromLonLat(ul);var url=this.getFullRequestString();var params=null;var filter=this.params.filter||this.params.FILTER;if(filter){params={FILTER:filter};}
61003 else{params={BBOX:this.encodeBBOX?tileBounds.toBBOX():tileBounds.toArray()};}
61004 if(this.map&&!this.projection.equals(this.map.getProjectionObject())){var projectedBounds=tileBounds.clone();projectedBounds.transform(this.map.getProjectionObject(),this.projection);if(!filter){params.BBOX=this.encodeBBOX?projectedBounds.toBBOX():projectedBounds.toArray();}}
61005 url+="&"+OpenLayers.Util.getParameterString(params);if(!this.tile){this.tile=new OpenLayers.Tile.WFS(this,pos,tileBounds,url,tileSize);this.addTileMonitoringHooks(this.tile);this.tile.draw();}else{if(this.vectorMode){this.destroyFeatures();this.renderer.clear();}else{this.clearMarkers();}
61006 this.removeTileMonitoringHooks(this.tile);this.tile.destroy();this.tile=null;this.tile=new OpenLayers.Tile.WFS(this,pos,tileBounds,url,tileSize);this.addTileMonitoringHooks(this.tile);this.tile.draw();}}},addTileMonitoringHooks:function(tile){tile.onLoadStart=function(){if(this==this.layer.tile){this.layer.events.triggerEvent("loadstart");}};tile.events.register("loadstart",tile,tile.onLoadStart);tile.onLoadEnd=function(){if(this==this.layer.tile){this.layer.events.triggerEvent("tileloaded");this.layer.events.triggerEvent("loadend");}};tile.events.register("loadend",tile,tile.onLoadEnd);tile.events.register("unload",tile,tile.onLoadEnd);},removeTileMonitoringHooks:function(tile){tile.unload();tile.events.un({"loadstart":tile.onLoadStart,"loadend":tile.onLoadEnd,"unload":tile.onLoadEnd,scope:tile});},onMapResize:function(){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.onMapResize.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.onMapResize.apply(this,arguments);}},display:function(){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.display.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.display.apply(this,arguments);}},mergeNewParams:function(newParams){var upperParams=OpenLayers.Util.upperCaseObject(newParams);var newArguments=[upperParams];return OpenLayers.Layer.HTTPRequest.prototype.mergeNewParams.apply(this,newArguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WFS(this.name,this.url,this.params,this.getOptions());}
61007 if(this.vectorMode){obj=OpenLayers.Layer.Vector.prototype.clone.apply(this,[obj]);}else{obj=OpenLayers.Layer.Markers.prototype.clone.apply(this,[obj]);}
61008 return obj;},getFullRequestString:function(newParams,altUrl){var projectionCode=this.projection.getCode()||this.map.getProjection();this.params.SRS=(projectionCode=="none")?null:projectionCode;return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,arguments);},commit:function(){if(!this.writer){var options={};if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
61009 this.writer=new OpenLayers.Format.WFS(options,this);}
61010 var data=this.writer.write(this.features);OpenLayers.Request.POST({url:this.url,data:data,success:this.commitSuccess,failure:this.commitFailure,scope:this});},commitSuccess:function(request){var response=request.responseText;if(response.indexOf('SUCCESS')!=-1){this.commitReport(OpenLayers.i18n("commitSuccess",{'response':response}));for(var i=0;i<this.features.length;i++){this.features[i].state=null;}}else if(response.indexOf('FAILED')!=-1||response.indexOf('Exception')!=-1){this.commitReport(OpenLayers.i18n("commitFailed",{'response':response}));}},commitFailure:function(request){},commitReport:function(string,response){OpenLayers.Console.userError(string);},refresh:function(){if(this.tile){if(this.vectorMode){this.renderer.clear();this.features.length=0;}else{this.clearMarkers();this.markers.length=0;}
61011 this.tile.draw();}},getDataExtent:function(){var extent;if(this.vectorMode){extent=OpenLayers.Layer.Vector.prototype.getDataExtent.apply(this);}else{extent=OpenLayers.Layer.Markers.prototype.getDataExtent.apply(this);}
61012 return extent;},setOpacity:function(opacity){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.setOpacity.apply(this,[opacity]);}else{OpenLayers.Layer.Markers.prototype.setOpacity.apply(this,[opacity]);}},CLASS_NAME:"OpenLayers.Layer.WFS"});OpenLayers.Protocol.HTTP=OpenLayers.Class(OpenLayers.Protocol,{url:null,headers:null,params:null,callback:null,scope:null,readWithPOST:false,wildcarded:false,initialize:function(options){options=options||{};this.params={};this.headers={};OpenLayers.Protocol.prototype.initialize.apply(this,arguments);},destroy:function(){this.params=null;this.headers=null;OpenLayers.Protocol.prototype.destroy.apply(this);},read:function(options){OpenLayers.Protocol.prototype.read.apply(this,arguments);options=OpenLayers.Util.applyDefaults(options,this.options);options.params=OpenLayers.Util.applyDefaults(options.params,this.options.params);if(options.filter){options.params=this.filterToParams(options.filter,options.params);}
61013 var readWithPOST=(options.readWithPOST!==undefined)?options.readWithPOST:this.readWithPOST;var resp=new OpenLayers.Protocol.Response({requestType:"read"});if(readWithPOST){resp.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleRead,resp,options),data:OpenLayers.Util.getParameterString(options.params),headers:{"Content-Type":"application/x-www-form-urlencoded"}});}else{resp.priv=OpenLayers.Request.GET({url:options.url,callback:this.createCallback(this.handleRead,resp,options),params:options.params,headers:options.headers});}
61014 return resp;},handleRead:function(resp,options){this.handleResponse(resp,options);},filterToParams:function(filter,params){params=params||{};var className=filter.CLASS_NAME;var filterType=className.substring(className.lastIndexOf(".")+1);switch(filterType){case"Spatial":switch(filter.type){case OpenLayers.Filter.Spatial.BBOX:params.bbox=filter.value.toArray();break;case OpenLayers.Filter.Spatial.DWITHIN:params.tolerance=filter.distance;case OpenLayers.Filter.Spatial.WITHIN:params.lon=filter.value.x;params.lat=filter.value.y;break;default:OpenLayers.Console.warn("Unknown spatial filter type "+filter.type);}
61015 break;case"Comparison":var op=OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR[filter.type];if(op!==undefined){var value=filter.value;if(filter.type==OpenLayers.Filter.Comparison.LIKE){value=this.regex2value(value);if(this.wildcarded){value="%"+value+"%";}}
61016 params[filter.property+"__"+op]=value;params.queryable=params.queryable||[];params.queryable.push(filter.property);}else{OpenLayers.Console.warn("Unknown comparison filter type "+filter.type);}
61017 break;case"Logical":if(filter.type===OpenLayers.Filter.Logical.AND){for(var i=0,len=filter.filters.length;i<len;i++){params=this.filterToParams(filter.filters[i],params);}}else{OpenLayers.Console.warn("Unsupported logical filter type "+filter.type);}
61018 break;default:OpenLayers.Console.warn("Unknown filter type "+filterType);}
61019 return params;},regex2value:function(value){value=value.replace(/%/g,"\\%");value=value.replace(/\\\\\.(\*)?/g,function($0,$1){return $1?$0:"\\\\_";});value=value.replace(/\\\\\.\*/g,"\\\\%");value=value.replace(/(\\)?\.(\*)?/g,function($0,$1,$2){return $1||$2?$0:"_";});value=value.replace(/(\\)?\.\*/g,function($0,$1){return $1?$0:"%";});value=value.replace(/\\\./g,".");value=value.replace(/(\\)?\\\*/g,function($0,$1){return $1?$0:"*";});return value;},create:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=new OpenLayers.Protocol.Response({reqFeatures:features,requestType:"create"});resp.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleCreate,resp,options),headers:options.headers,data:this.format.write(features)});return resp;},handleCreate:function(resp,options){this.handleResponse(resp,options);},update:function(feature,options){options=options||{};var url=options.url||feature.url||this.options.url+"/"+feature.fid;options=OpenLayers.Util.applyDefaults(options,this.options);var resp=new OpenLayers.Protocol.Response({reqFeatures:feature,requestType:"update"});resp.priv=OpenLayers.Request.PUT({url:url,callback:this.createCallback(this.handleUpdate,resp,options),headers:options.headers,data:this.format.write(feature)});return resp;},handleUpdate:function(resp,options){this.handleResponse(resp,options);},"delete":function(feature,options){options=options||{};var url=options.url||feature.url||this.options.url+"/"+feature.fid;options=OpenLayers.Util.applyDefaults(options,this.options);var resp=new OpenLayers.Protocol.Response({reqFeatures:feature,requestType:"delete"});resp.priv=OpenLayers.Request.DELETE({url:url,callback:this.createCallback(this.handleDelete,resp,options),headers:options.headers});return resp;},handleDelete:function(resp,options){this.handleResponse(resp,options);},handleResponse:function(resp,options){var request=resp.priv;if(options.callback){if(request.status>=200&&request.status<300){if(resp.requestType!="delete"){resp.features=this.parseFeatures(request);}
61020 resp.code=OpenLayers.Protocol.Response.SUCCESS;}else{resp.code=OpenLayers.Protocol.Response.FAILURE;}
61021 options.callback.call(options.scope,resp);}},parseFeatures:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
61022 if(!doc||doc.length<=0){return null;}
61023 return this.format.read(doc);},commit:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=[],nResponses=0;var types={};types[OpenLayers.State.INSERT]=[];types[OpenLayers.State.UPDATE]=[];types[OpenLayers.State.DELETE]=[];var feature,list,requestFeatures=[];for(var i=0,len=features.length;i<len;++i){feature=features[i];list=types[feature.state];if(list){list.push(feature);requestFeatures.push(feature);}}
61024 var nRequests=(types[OpenLayers.State.INSERT].length>0?1:0)+
61025 types[OpenLayers.State.UPDATE].length+
61026 types[OpenLayers.State.DELETE].length;var success=true;var finalResponse=new OpenLayers.Protocol.Response({reqFeatures:requestFeatures});function insertCallback(response){var len=response.features?response.features.length:0;var fids=new Array(len);for(var i=0;i<len;++i){fids[i]=response.features[i].fid;}
61027 finalResponse.insertIds=fids;callback.apply(this,[response]);}
61028 function callback(response){this.callUserCallback(response,options);success=success&&response.success();nResponses++;if(nResponses>=nRequests){if(options.callback){finalResponse.code=success?OpenLayers.Protocol.Response.SUCCESS:OpenLayers.Protocol.Response.FAILURE;options.callback.apply(options.scope,[finalResponse]);}}}
61029 var queue=types[OpenLayers.State.INSERT];if(queue.length>0){resp.push(this.create(queue,OpenLayers.Util.applyDefaults({callback:insertCallback,scope:this},options.create)));}
61030 queue=types[OpenLayers.State.UPDATE];for(var i=queue.length-1;i>=0;--i){resp.push(this.update(queue[i],OpenLayers.Util.applyDefaults({callback:callback,scope:this},options.update)));}
61031 queue=types[OpenLayers.State.DELETE];for(var i=queue.length-1;i>=0;--i){resp.push(this["delete"](queue[i],OpenLayers.Util.applyDefaults({callback:callback,scope:this},options["delete"])));}
61032 return resp;},abort:function(response){if(response){response.priv.abort();}},callUserCallback:function(resp,options){var opt=options[resp.requestType];if(opt&&opt.callback){opt.callback.call(opt.scope,resp);}},CLASS_NAME:"OpenLayers.Protocol.HTTP"});(function(){var o=OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR={};o[OpenLayers.Filter.Comparison.EQUAL_TO]="eq";o[OpenLayers.Filter.Comparison.NOT_EQUAL_TO]="ne";o[OpenLayers.Filter.Comparison.LESS_THAN]="lt";o[OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO]="lte";o[OpenLayers.Filter.Comparison.GREATER_THAN]="gt";o[OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO]="gte";o[OpenLayers.Filter.Comparison.LIKE]="ilike";})();OpenLayers.Strategy.BBOX=OpenLayers.Class(OpenLayers.Strategy,{bounds:null,resolution:null,ratio:2,resFactor:null,response:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){this.layer.events.on({"moveend":this.update,scope:this});this.layer.events.on({"refresh":this.update,scope:this});}
61033 return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.layer.events.un({"moveend":this.update,scope:this});this.layer.events.un({"refresh":this.update,scope:this});}
61034 return deactivated;},update:function(options){var mapBounds=this.getMapBounds();if((options&&options.force)||this.invalidBounds(mapBounds)){this.calculateBounds(mapBounds);this.resolution=this.layer.map.getResolution();this.triggerRead();}},getMapBounds:function(){var bounds=this.layer.map.getExtent();if(!this.layer.projection.equals(this.layer.map.getProjectionObject())){bounds=bounds.clone().transform(this.layer.map.getProjectionObject(),this.layer.projection);}
61035 return bounds;},invalidBounds:function(mapBounds){if(!mapBounds){mapBounds=this.getMapBounds();}
61036 var invalid=!this.bounds||!this.bounds.containsBounds(mapBounds);if(!invalid&&this.resFactor){var ratio=this.resolution/this.layer.map.getResolution();invalid=(ratio>=this.resFactor||ratio<=(1/this.resFactor));}
61037 return invalid;},calculateBounds:function(mapBounds){if(!mapBounds){mapBounds=this.getMapBounds();}
61038 var center=mapBounds.getCenterLonLat();var dataWidth=mapBounds.getWidth()*this.ratio;var dataHeight=mapBounds.getHeight()*this.ratio;this.bounds=new OpenLayers.Bounds(center.lon-(dataWidth/2),center.lat-(dataHeight/2),center.lon+(dataWidth/2),center.lat+(dataHeight/2));},triggerRead:function(){if(this.response){this.layer.protocol.abort(this.response);this.layer.events.triggerEvent("loadend");}
61039 this.layer.events.triggerEvent("loadstart");this.response=this.layer.protocol.read({filter:this.createFilter(),callback:this.merge,scope:this});},createFilter:function(){var filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.BBOX,value:this.bounds,projection:this.layer.projection});if(this.layer.filter){filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND,filters:[this.layer.filter,filter]});}
61040 return filter;},merge:function(resp){this.layer.destroyFeatures();var features=resp.features;if(features&&features.length>0){var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var geom;for(var i=0,len=features.length;i<len;++i){geom=features[i].geometry;if(geom){geom.transform(remote,local);}}}
61041 this.layer.addFeatures(features);}
61042 this.response=null;this.layer.events.triggerEvent("loadend");},CLASS_NAME:"OpenLayers.Strategy.BBOX"});OpenLayers.Control.SelectFeature=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforefeaturehighlighted","featurehighlighted","featureunhighlighted"],multipleKey:null,toggleKey:null,multiple:false,clickout:true,toggle:false,hover:false,highlightOnly:false,box:false,onBeforeSelect:function(){},onSelect:function(){},onUnselect:function(){},scope:null,geometryTypes:null,layer:null,layers:null,callbacks:null,selectStyle:null,renderIntent:"select",handlers:null,initialize:function(layers,options){this.EVENT_TYPES=OpenLayers.Control.SelectFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);if(this.scope===null){this.scope=this;}
61043 this.initLayer(layers);var callbacks={click:this.clickFeature,clickout:this.clickoutFeature};if(this.hover){callbacks.over=this.overFeature;callbacks.out=this.outFeature;}
61044 this.callbacks=OpenLayers.Util.extend(callbacks,this.callbacks);this.handlers={feature:new OpenLayers.Handler.Feature(this,this.layer,this.callbacks,{geometryTypes:this.geometryTypes})};if(this.box){this.handlers.box=new OpenLayers.Handler.Box(this,{done:this.selectBox},{boxDivClassName:"olHandlerBoxSelectFeature"});}},initLayer:function(layers){if(layers instanceof Array){this.layers=layers;this.layer=new OpenLayers.Layer.Vector.RootContainer(this.id+"_container",{layers:layers});}else{this.layer=layers;}},destroy:function(){if(this.active&&this.layers){this.map.removeLayer(this.layer);}
61045 OpenLayers.Control.prototype.destroy.apply(this,arguments);if(this.layers){this.layer.destroy();}},activate:function(){if(!this.active){if(this.layers){this.map.addLayer(this.layer);}
61046 this.handlers.feature.activate();if(this.box&&this.handlers.box){this.handlers.box.activate();}}
61047 return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){if(this.active){this.handlers.feature.deactivate();if(this.handlers.box){this.handlers.box.deactivate();}
61048 if(this.layers){this.map.removeLayer(this.layer);}}
61049 return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},unselectAll:function(options){var layers=this.layers||[this.layer];var layer,feature;for(var l=0;l<layers.length;++l){layer=layers[l];for(var i=layer.selectedFeatures.length-1;i>=0;--i){feature=layer.selectedFeatures[i];if(!options||options.except!=feature){this.unselect(feature);}}}},clickFeature:function(feature){if(!this.hover){var selected=(OpenLayers.Util.indexOf(feature.layer.selectedFeatures,feature)>-1);if(selected){if(this.toggleSelect()){this.unselect(feature);}else if(!this.multipleSelect()){this.unselectAll({except:feature});}}else{if(!this.multipleSelect()){this.unselectAll({except:feature});}
61050 this.select(feature);}}},multipleSelect:function(){return this.multiple||(this.handlers.feature.evt&&this.handlers.feature.evt[this.multipleKey]);},toggleSelect:function(){return this.toggle||(this.handlers.feature.evt&&this.handlers.feature.evt[this.toggleKey]);},clickoutFeature:function(feature){if(!this.hover&&this.clickout){this.unselectAll();}},overFeature:function(feature){var layer=feature.layer;if(this.hover){if(this.highlightOnly){this.highlight(feature);}else if(OpenLayers.Util.indexOf(layer.selectedFeatures,feature)==-1){this.select(feature);}}},outFeature:function(feature){if(this.hover){if(this.highlightOnly){if(feature._lastHighlighter==this.id){if(feature._prevHighlighter&&feature._prevHighlighter!=this.id){delete feature._lastHighlighter;var control=this.map.getControl(feature._prevHighlighter);if(control){control.highlight(feature);}}else{this.unhighlight(feature);}}}else{this.unselect(feature);}}},highlight:function(feature){var layer=feature.layer;var cont=this.events.triggerEvent("beforefeaturehighlighted",{feature:feature});if(cont!==false){feature._prevHighlighter=feature._lastHighlighter;feature._lastHighlighter=this.id;var style=this.selectStyle||this.renderIntent;layer.drawFeature(feature,style);this.events.triggerEvent("featurehighlighted",{feature:feature});}},unhighlight:function(feature){var layer=feature.layer;feature._lastHighlighter=feature._prevHighlighter;delete feature._prevHighlighter;layer.drawFeature(feature,feature.style||feature.layer.style||"default");this.events.triggerEvent("featureunhighlighted",{feature:feature});},select:function(feature){var cont=this.onBeforeSelect.call(this.scope,feature);var layer=feature.layer;if(cont!==false){cont=layer.events.triggerEvent("beforefeatureselected",{feature:feature});if(cont!==false){layer.selectedFeatures.push(feature);this.highlight(feature);if(!this.handlers.feature.lastFeature){this.handlers.feature.lastFeature=layer.selectedFeatures[0];}
61051 layer.events.triggerEvent("featureselected",{feature:feature});this.onSelect.call(this.scope,feature);}}},unselect:function(feature){var layer=feature.layer;this.unhighlight(feature);OpenLayers.Util.removeItem(layer.selectedFeatures,feature);layer.events.triggerEvent("featureunselected",{feature:feature});this.onUnselect.call(this.scope,feature);},selectBox:function(position){if(position instanceof OpenLayers.Bounds){var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));var bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat);if(!this.multipleSelect()){this.unselectAll();}
61052 var prevMultiple=this.multiple;this.multiple=true;var layers=this.layers||[this.layer];var layer;for(var l=0;l<layers.length;++l){layer=layers[l];for(var i=0,len=layer.features.length;i<len;++i){var feature=layer.features[i];if(!feature.getVisibility()){continue;}
61053 if(this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)>-1){if(bounds.toGeometry().intersects(feature.geometry)){if(OpenLayers.Util.indexOf(layer.selectedFeatures,feature)==-1){this.select(feature);}}}}}
61054 this.multiple=prevMultiple;}},setMap:function(map){this.handlers.feature.setMap(map);if(this.box){this.handlers.box.setMap(map);}
61055 OpenLayers.Control.prototype.setMap.apply(this,arguments);},setLayer:function(layers){var isActive=this.active;this.unselectAll();this.deactivate();if(this.layers){this.layer.destroy();this.layers=null;}
61056 this.initLayer(layers);this.handlers.feature.layer=this.layer;if(isActive){this.activate();}},CLASS_NAME:"OpenLayers.Control.SelectFeature"});OpenLayers.Format.Filter.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ogc:"http://www.opengis.net/ogc",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"ogc",schemaLocation:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){var obj={};this.readers.ogc["Filter"].apply(this,[data,obj]);return obj.filter;},readers:{"ogc":{"Filter":function(node,parent){var obj={fids:[],filters:[]};this.readChildNodes(node,obj);if(obj.fids.length>0){parent.filter=new OpenLayers.Filter.FeatureId({fids:obj.fids});}else if(obj.filters.length>0){parent.filter=obj.filters[0];}},"FeatureId":function(node,obj){var fid=node.getAttribute("fid");if(fid){obj.fids.push(fid);}},"And":function(node,obj){var filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND});this.readChildNodes(node,filter);obj.filters.push(filter);},"Or":function(node,obj){var filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.OR});this.readChildNodes(node,filter);obj.filters.push(filter);},"Not":function(node,obj){var filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.NOT});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLessThan":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LESS_THAN});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsGreaterThan":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.GREATER_THAN});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLessThanOrEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsGreaterThanOrEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsBetween":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.BETWEEN});this.readChildNodes(node,filter);obj.filters.push(filter);},"Literal":function(node,obj){obj.value=OpenLayers.String.numericIf(this.getChildValue(node));},"PropertyName":function(node,filter){filter.property=this.getChildValue(node);},"LowerBoundary":function(node,filter){filter.lowerBoundary=OpenLayers.String.numericIf(this.readOgcExpression(node));},"UpperBoundary":function(node,filter){filter.upperBoundary=OpenLayers.String.numericIf(this.readOgcExpression(node));},"Intersects":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.INTERSECTS);},"Within":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.WITHIN);},"Contains":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.CONTAINS);},"DWithin":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.DWITHIN);},"Distance":function(node,obj){obj.distance=parseInt(this.getChildValue(node));obj.distanceUnits=node.getAttribute("units");}}},readSpatial:function(node,obj,type){var filter=new OpenLayers.Filter.Spatial({type:type});this.readChildNodes(node,filter);filter.value=filter.components[0];delete filter.components;obj.filters.push(filter);},readOgcExpression:function(node){var obj={};this.readChildNodes(node,obj);var value=obj.value;if(value===undefined){value=this.getChildValue(node);}
61057 return value;},write:function(filter){return this.writers.ogc["Filter"].apply(this,[filter]);},writers:{"ogc":{"Filter":function(filter){var node=this.createElementNSPlus("ogc:Filter");var sub=filter.CLASS_NAME.split(".").pop();if(sub=="FeatureId"){for(var i=0;i<filter.fids.length;++i){this.writeNode("FeatureId",filter.fids[i],node);}}else{this.writeNode(this.getFilterType(filter),filter,node);}
61058 return node;},"FeatureId":function(fid){return this.createElementNSPlus("ogc:FeatureId",{attributes:{fid:fid}});},"And":function(filter){var node=this.createElementNSPlus("ogc:And");var childFilter;for(var i=0;i<filter.filters.length;++i){childFilter=filter.filters[i];this.writeNode(this.getFilterType(childFilter),childFilter,node);}
61059 return node;},"Or":function(filter){var node=this.createElementNSPlus("ogc:Or");var childFilter;for(var i=0;i<filter.filters.length;++i){childFilter=filter.filters[i];this.writeNode(this.getFilterType(childFilter),childFilter,node);}
61060 return node;},"Not":function(filter){var node=this.createElementNSPlus("ogc:Not");var childFilter=filter.filters[0];this.writeNode(this.getFilterType(childFilter),childFilter,node);return node;},"PropertyIsLessThan":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLessThan");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsGreaterThan":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsGreaterThan");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsLessThanOrEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLessThanOrEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsGreaterThanOrEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsGreaterThanOrEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsBetween":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsBetween");this.writeNode("PropertyName",filter,node);this.writeNode("LowerBoundary",filter,node);this.writeNode("UpperBoundary",filter,node);return node;},"PropertyName":function(filter){return this.createElementNSPlus("ogc:PropertyName",{value:filter.property});},"Literal":function(value){return this.createElementNSPlus("ogc:Literal",{value:value});},"LowerBoundary":function(filter){var node=this.createElementNSPlus("ogc:LowerBoundary");this.writeNode("Literal",filter.lowerBoundary,node);return node;},"UpperBoundary":function(filter){var node=this.createElementNSPlus("ogc:UpperBoundary");this.writeNode("Literal",filter.upperBoundary,node);return node;},"INTERSECTS":function(filter){return this.writeSpatial(filter,"Intersects");},"WITHIN":function(filter){return this.writeSpatial(filter,"Within");},"CONTAINS":function(filter){return this.writeSpatial(filter,"Contains");},"DWITHIN":function(filter){var node=this.writeSpatial(filter,"DWithin");this.writeNode("Distance",filter,node);return node;},"Distance":function(filter){return this.createElementNSPlus("ogc:Distance",{attributes:{units:filter.distanceUnits},value:filter.distance});}}},getFilterType:function(filter){var filterType=this.filterMap[filter.type];if(!filterType){throw"Filter writing not supported for rule type: "+filter.type;}
61061 return filterType;},filterMap:{"&&":"And","||":"Or","!":"Not","==":"PropertyIsEqualTo","!=":"PropertyIsNotEqualTo","<":"PropertyIsLessThan",">":"PropertyIsGreaterThan","<=":"PropertyIsLessThanOrEqualTo",">=":"PropertyIsGreaterThanOrEqualTo","..":"PropertyIsBetween","~":"PropertyIsLike","BBOX":"BBOX","DWITHIN":"DWITHIN","WITHIN":"WITHIN","CONTAINS":"CONTAINS","INTERSECTS":"INTERSECTS"},CLASS_NAME:"OpenLayers.Format.Filter.v1"});OpenLayers.Geometry.Curve=OpenLayers.Class(OpenLayers.Geometry.MultiPoint,{componentTypes:["OpenLayers.Geometry.Point"],initialize:function(points){OpenLayers.Geometry.MultiPoint.prototype.initialize.apply(this,arguments);},getLength:function(){var length=0.0;if(this.components&&(this.components.length>1)){for(var i=1,len=this.components.length;i<len;i++){length+=this.components[i-1].distanceTo(this.components[i]);}}
61062 return length;},getGeodesicLength:function(projection){var geom=this;if(projection){var gg=new OpenLayers.Projection("EPSG:4326");if(!gg.equals(projection)){geom=this.clone().transform(projection,gg);}}
61063 var length=0.0;if(geom.components&&(geom.components.length>1)){var p1,p2;for(var i=1,len=geom.components.length;i<len;i++){p1=geom.components[i-1];p2=geom.components[i];length+=OpenLayers.Util.distVincenty({lon:p1.x,lat:p1.y},{lon:p2.x,lat:p2.y});}}
61064 return length*1000;},CLASS_NAME:"OpenLayers.Geometry.Curve"});OpenLayers.Layer.Text=OpenLayers.Class(OpenLayers.Layer.Markers,{location:null,features:null,formatOptions:null,selectedFeature:null,initialize:function(name,options){OpenLayers.Layer.Markers.prototype.initialize.apply(this,arguments);this.features=new Array();},destroy:function(){OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);this.clearFeatures();this.features=null;},loadText:function(){if(!this.loaded){if(this.location!=null){var onFail=function(e){this.events.triggerEvent("loadend");};this.events.triggerEvent("loadstart");OpenLayers.Request.GET({url:this.location,success:this.parseData,failure:onFail,scope:this});this.loaded=true;}}},moveTo:function(bounds,zoomChanged,minor){OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadText();}},parseData:function(ajaxRequest){var text=ajaxRequest.responseText;var options={};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
61065 var parser=new OpenLayers.Format.Text(options);var features=parser.read(text);for(var i=0,len=features.length;i<len;i++){var data={};var feature=features[i];var location;var iconSize,iconOffset;location=new OpenLayers.LonLat(feature.geometry.x,feature.geometry.y);if(feature.style.graphicWidth&&feature.style.graphicHeight){iconSize=new OpenLayers.Size(feature.style.graphicWidth,feature.style.graphicHeight);}
61066 if(feature.style.graphicXOffset!==undefined&&feature.style.graphicYOffset!==undefined){iconOffset=new OpenLayers.Pixel(feature.style.graphicXOffset,feature.style.graphicYOffset);}
61067 if(feature.style.externalGraphic!=null){data.icon=new OpenLayers.Icon(feature.style.externalGraphic,iconSize,iconOffset);}else{data.icon=OpenLayers.Marker.defaultIcon();if(iconSize!=null){data.icon.setSize(iconSize);}}
61068 if((feature.attributes.title!=null)&&(feature.attributes.description!=null)){data['popupContentHTML']='<h2>'+feature.attributes.title+'</h2>'+'<p>'+feature.attributes.description+'</p>';}
61069 data['overflow']=feature.attributes.overflow||"auto";var markerFeature=new OpenLayers.Feature(this,location,data);this.features.push(markerFeature);var marker=markerFeature.createMarker();if((feature.attributes.title!=null)&&(feature.attributes.description!=null)){marker.events.register('click',markerFeature,this.markerClick);}
61070 this.addMarker(marker);}
61071 this.events.triggerEvent("loadend");},markerClick:function(evt){var sameMarkerClicked=(this==this.layer.selectedFeature);this.layer.selectedFeature=(!sameMarkerClicked)?this:null;for(var i=0,len=this.layer.map.popups.length;i<len;i++){this.layer.map.removePopup(this.layer.map.popups[i]);}
61072 if(!sameMarkerClicked){this.layer.map.addPopup(this.createPopup());}
61073 OpenLayers.Event.stop(evt);},clearFeatures:function(){if(this.features!=null){while(this.features.length>0){var feature=this.features[0];OpenLayers.Util.removeItem(this.features,feature);feature.destroy();}}},CLASS_NAME:"OpenLayers.Layer.Text"});OpenLayers.Control.ModifyFeature=OpenLayers.Class(OpenLayers.Control,{geometryTypes:null,clickout:true,toggle:true,standalone:false,layer:null,feature:null,vertices:null,virtualVertices:null,selectControl:null,dragControl:null,handlers:null,deleteCodes:null,virtualStyle:null,mode:null,modified:false,radiusHandle:null,dragHandle:null,onModificationStart:function(){},onModification:function(){},onModificationEnd:function(){},initialize:function(layer,options){this.layer=layer;this.vertices=[];this.virtualVertices=[];this.virtualStyle=OpenLayers.Util.extend({},this.layer.style||this.layer.styleMap.createSymbolizer());this.virtualStyle.fillOpacity=0.3;this.virtualStyle.strokeOpacity=0.3;this.deleteCodes=[46,68];this.mode=OpenLayers.Control.ModifyFeature.RESHAPE;OpenLayers.Control.prototype.initialize.apply(this,[options]);if(!(this.deleteCodes instanceof Array)){this.deleteCodes=[this.deleteCodes];}
61074 var control=this;var selectOptions={geometryTypes:this.geometryTypes,clickout:this.clickout,toggle:this.toggle,onBeforeSelect:this.beforeSelectFeature,onSelect:this.selectFeature,onUnselect:this.unselectFeature,scope:this};if(this.standalone===false){this.selectControl=new OpenLayers.Control.SelectFeature(layer,selectOptions);}
61075 var dragOptions={geometryTypes:["OpenLayers.Geometry.Point"],snappingOptions:this.snappingOptions,onStart:function(feature,pixel){control.dragStart.apply(control,[feature,pixel]);},onDrag:function(feature,pixel){control.dragVertex.apply(control,[feature,pixel]);},onComplete:function(feature){control.dragComplete.apply(control,[feature]);},featureCallbacks:{over:function(feature){if(control.standalone!==true||feature._sketch||control.feature===feature){control.dragControl.overFeature.apply(control.dragControl,[feature]);}}}};this.dragControl=new OpenLayers.Control.DragFeature(layer,dragOptions);var keyboardOptions={keydown:this.handleKeypress};this.handlers={keyboard:new OpenLayers.Handler.Keyboard(this,keyboardOptions)};},destroy:function(){this.layer=null;this.standalone||this.selectControl.destroy();this.dragControl.destroy();OpenLayers.Control.prototype.destroy.apply(this,[]);},activate:function(){return((this.standalone||this.selectControl.activate())&&this.handlers.keyboard.activate()&&OpenLayers.Control.prototype.activate.apply(this,arguments));},deactivate:function(){var deactivated=false;if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.layer.removeFeatures(this.vertices,{silent:true});this.layer.removeFeatures(this.virtualVertices,{silent:true});this.vertices=[];this.dragControl.deactivate();var feature=this.feature;var valid=feature&&feature.geometry&&feature.layer;if(this.standalone===false){if(valid){this.selectControl.unselect.apply(this.selectControl,[feature]);}
61076 this.selectControl.deactivate();}else{if(valid){this.unselectFeature(feature);}}
61077 this.handlers.keyboard.deactivate();deactivated=true;}
61078 return deactivated;},beforeSelectFeature:function(feature){return this.layer.events.triggerEvent("beforefeaturemodified",{feature:feature});},selectFeature:function(feature){this.feature=feature;this.modified=false;this.resetVertices();this.dragControl.activate();this.onModificationStart(this.feature);},unselectFeature:function(feature){this.layer.removeFeatures(this.vertices,{silent:true});this.vertices=[];this.layer.destroyFeatures(this.virtualVertices,{silent:true});this.virtualVertices=[];if(this.dragHandle){this.layer.destroyFeatures([this.dragHandle],{silent:true});delete this.dragHandle;}
61079 if(this.radiusHandle){this.layer.destroyFeatures([this.radiusHandle],{silent:true});delete this.radiusHandle;}
61080 this.feature=null;this.dragControl.deactivate();this.onModificationEnd(feature);this.layer.events.triggerEvent("afterfeaturemodified",{feature:feature,modified:this.modified});this.modified=false;},dragStart:function(feature,pixel){if(feature!=this.feature&&!feature.geometry.parent&&feature!=this.dragHandle&&feature!=this.radiusHandle){if(this.standalone===false&&this.feature){this.selectControl.clickFeature.apply(this.selectControl,[this.feature]);}
61081 if(this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)!=-1){this.standalone||this.selectControl.clickFeature.apply(this.selectControl,[feature]);this.dragControl.overFeature.apply(this.dragControl,[feature]);this.dragControl.lastPixel=pixel;this.dragControl.handlers.drag.started=true;this.dragControl.handlers.drag.start=pixel;this.dragControl.handlers.drag.last=pixel;}}},dragVertex:function(vertex,pixel){this.modified=true;if(this.feature.geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){if(this.feature!=vertex){this.feature=vertex;}
61082 this.layer.events.triggerEvent("vertexmodified",{vertex:vertex.geometry,feature:this.feature,pixel:pixel});}else{if(vertex._index){vertex.geometry.parent.addComponent(vertex.geometry,vertex._index);delete vertex._index;OpenLayers.Util.removeItem(this.virtualVertices,vertex);this.vertices.push(vertex);}else if(vertex==this.dragHandle){this.layer.removeFeatures(this.vertices,{silent:true});this.vertices=[];if(this.radiusHandle){this.layer.destroyFeatures([this.radiusHandle],{silent:true});this.radiusHandle=null;}}else if(vertex!==this.radiusHandle){this.layer.events.triggerEvent("vertexmodified",{vertex:vertex.geometry,feature:this.feature,pixel:pixel});}
61083 if(this.virtualVertices.length>0){this.layer.destroyFeatures(this.virtualVertices,{silent:true});this.virtualVertices=[];}
61084 this.layer.drawFeature(this.feature,this.standalone?undefined:this.selectControl.renderIntent);}
61085 this.layer.drawFeature(vertex);},dragComplete:function(vertex){this.resetVertices();this.setFeatureState();this.onModification(this.feature);this.layer.events.triggerEvent("featuremodified",{feature:this.feature});},setFeatureState:function(){if(this.feature.state!=OpenLayers.State.INSERT&&this.feature.state!=OpenLayers.State.DELETE){this.feature.state=OpenLayers.State.UPDATE;}},resetVertices:function(){if(this.dragControl.feature){this.dragControl.outFeature(this.dragControl.feature);}
61086 if(this.vertices.length>0){this.layer.removeFeatures(this.vertices,{silent:true});this.vertices=[];}
61087 if(this.virtualVertices.length>0){this.layer.removeFeatures(this.virtualVertices,{silent:true});this.virtualVertices=[];}
61088 if(this.dragHandle){this.layer.destroyFeatures([this.dragHandle],{silent:true});this.dragHandle=null;}
61089 if(this.radiusHandle){this.layer.destroyFeatures([this.radiusHandle],{silent:true});this.radiusHandle=null;}
61090 if(this.feature&&this.feature.geometry.CLASS_NAME!="OpenLayers.Geometry.Point"){if((this.mode&OpenLayers.Control.ModifyFeature.DRAG)){this.collectDragHandle();}
61091 if((this.mode&(OpenLayers.Control.ModifyFeature.ROTATE|OpenLayers.Control.ModifyFeature.RESIZE))){this.collectRadiusHandle();}
61092 if(this.mode&OpenLayers.Control.ModifyFeature.RESHAPE){if(!(this.mode&OpenLayers.Control.ModifyFeature.RESIZE)){this.collectVertices();}}}},handleKeypress:function(evt){var code=evt.keyCode;if(this.feature&&OpenLayers.Util.indexOf(this.deleteCodes,code)!=-1){var vertex=this.dragControl.feature;if(vertex&&OpenLayers.Util.indexOf(this.vertices,vertex)!=-1&&!this.dragControl.handlers.drag.dragging&&vertex.geometry.parent){vertex.geometry.parent.removeComponent(vertex.geometry);this.layer.drawFeature(this.feature,this.standalone?undefined:this.selectControl.renderIntent);this.resetVertices();this.setFeatureState();this.onModification(this.feature);this.layer.events.triggerEvent("featuremodified",{feature:this.feature});}}},collectVertices:function(){this.vertices=[];this.virtualVertices=[];var control=this;function collectComponentVertices(geometry){var i,vertex,component,len;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){vertex=new OpenLayers.Feature.Vector(geometry);vertex._sketch=true;control.vertices.push(vertex);}else{var numVert=geometry.components.length;if(geometry.CLASS_NAME=="OpenLayers.Geometry.LinearRing"){numVert-=1;}
61093 for(i=0;i<numVert;++i){component=geometry.components[i];if(component.CLASS_NAME=="OpenLayers.Geometry.Point"){vertex=new OpenLayers.Feature.Vector(component);vertex._sketch=true;control.vertices.push(vertex);}else{collectComponentVertices(component);}}
61094 if(geometry.CLASS_NAME!="OpenLayers.Geometry.MultiPoint"){for(i=0,len=geometry.components.length;i<len-1;++i){var prevVertex=geometry.components[i];var nextVertex=geometry.components[i+1];if(prevVertex.CLASS_NAME=="OpenLayers.Geometry.Point"&&nextVertex.CLASS_NAME=="OpenLayers.Geometry.Point"){var x=(prevVertex.x+nextVertex.x)/2;var y=(prevVertex.y+nextVertex.y)/2;var point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(x,y),null,control.virtualStyle);point.geometry.parent=geometry;point._index=i+1;point._sketch=true;control.virtualVertices.push(point);}}}}}
61095 collectComponentVertices.call(this,this.feature.geometry);this.layer.addFeatures(this.virtualVertices,{silent:true});this.layer.addFeatures(this.vertices,{silent:true});},collectDragHandle:function(){var geometry=this.feature.geometry;var center=geometry.getBounds().getCenterLonLat();var originGeometry=new OpenLayers.Geometry.Point(center.lon,center.lat);var origin=new OpenLayers.Feature.Vector(originGeometry);originGeometry.move=function(x,y){OpenLayers.Geometry.Point.prototype.move.call(this,x,y);geometry.move(x,y);};origin._sketch=true;this.dragHandle=origin;this.layer.addFeatures([this.dragHandle],{silent:true});},collectRadiusHandle:function(){var geometry=this.feature.geometry;var bounds=geometry.getBounds();var center=bounds.getCenterLonLat();var originGeometry=new OpenLayers.Geometry.Point(center.lon,center.lat);var radiusGeometry=new OpenLayers.Geometry.Point(bounds.right,bounds.bottom);var radius=new OpenLayers.Feature.Vector(radiusGeometry);var resize=(this.mode&OpenLayers.Control.ModifyFeature.RESIZE);var reshape=(this.mode&OpenLayers.Control.ModifyFeature.RESHAPE);var rotate=(this.mode&OpenLayers.Control.ModifyFeature.ROTATE);radiusGeometry.move=function(x,y){OpenLayers.Geometry.Point.prototype.move.call(this,x,y);var dx1=this.x-originGeometry.x;var dy1=this.y-originGeometry.y;var dx0=dx1-x;var dy0=dy1-y;if(rotate){var a0=Math.atan2(dy0,dx0);var a1=Math.atan2(dy1,dx1);var angle=a1-a0;angle*=180/Math.PI;geometry.rotate(angle,originGeometry);}
61096 if(resize){var scale,ratio;if(reshape){scale=dy1/dy0;ratio=(dx1/dx0)/scale;}else{var l0=Math.sqrt((dx0*dx0)+(dy0*dy0));var l1=Math.sqrt((dx1*dx1)+(dy1*dy1));scale=l1/l0;}
61097 geometry.resize(scale,originGeometry,ratio);}};radius._sketch=true;this.radiusHandle=radius;this.layer.addFeatures([this.radiusHandle],{silent:true});},setMap:function(map){this.standalone||this.selectControl.setMap(map);this.dragControl.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.ModifyFeature"});OpenLayers.Control.ModifyFeature.RESHAPE=1;OpenLayers.Control.ModifyFeature.RESIZE=2;OpenLayers.Control.ModifyFeature.ROTATE=4;OpenLayers.Control.ModifyFeature.DRAG=8;OpenLayers.Geometry.LineString=OpenLayers.Class(OpenLayers.Geometry.Curve,{initialize:function(points){OpenLayers.Geometry.Curve.prototype.initialize.apply(this,arguments);},removeComponent:function(point){if(this.components&&(this.components.length>2)){OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,arguments);}},intersects:function(geometry){var intersect=false;var type=geometry.CLASS_NAME;if(type=="OpenLayers.Geometry.LineString"||type=="OpenLayers.Geometry.LinearRing"||type=="OpenLayers.Geometry.Point"){var segs1=this.getSortedSegments();var segs2;if(type=="OpenLayers.Geometry.Point"){segs2=[{x1:geometry.x,y1:geometry.y,x2:geometry.x,y2:geometry.y}];}else{segs2=geometry.getSortedSegments();}
61098 var seg1,seg1x1,seg1x2,seg1y1,seg1y2,seg2,seg2y1,seg2y2;outer:for(var i=0,len=segs1.length;i<len;++i){seg1=segs1[i];seg1x1=seg1.x1;seg1x2=seg1.x2;seg1y1=seg1.y1;seg1y2=seg1.y2;inner:for(var j=0,jlen=segs2.length;j<jlen;++j){seg2=segs2[j];if(seg2.x1>seg1x2){break;}
61099 if(seg2.x2<seg1x1){continue;}
61100 seg2y1=seg2.y1;seg2y2=seg2.y2;if(Math.min(seg2y1,seg2y2)>Math.max(seg1y1,seg1y2)){continue;}
61101 if(Math.max(seg2y1,seg2y2)<Math.min(seg1y1,seg1y2)){continue;}
61102 if(OpenLayers.Geometry.segmentsIntersect(seg1,seg2)){intersect=true;break outer;}}}}else{intersect=geometry.intersects(this);}
61103 return intersect;},getSortedSegments:function(){var numSeg=this.components.length-1;var segments=new Array(numSeg),point1,point2;for(var i=0;i<numSeg;++i){point1=this.components[i];point2=this.components[i+1];if(point1.x<point2.x){segments[i]={x1:point1.x,y1:point1.y,x2:point2.x,y2:point2.y};}else{segments[i]={x1:point2.x,y1:point2.y,x2:point1.x,y2:point1.y};}}
61104 function byX1(seg1,seg2){return seg1.x1-seg2.x1;}
61105 return segments.sort(byX1);},splitWithSegment:function(seg,options){var edge=!(options&&options.edge===false);var tolerance=options&&options.tolerance;var lines=[];var verts=this.getVertices();var points=[];var intersections=[];var split=false;var vert1,vert2,point;var node,vertex,target;var interOptions={point:true,tolerance:tolerance};var result=null;for(var i=0,stop=verts.length-2;i<=stop;++i){vert1=verts[i];points.push(vert1.clone());vert2=verts[i+1];target={x1:vert1.x,y1:vert1.y,x2:vert2.x,y2:vert2.y};point=OpenLayers.Geometry.segmentsIntersect(seg,target,interOptions);if(point instanceof OpenLayers.Geometry.Point){if((point.x===seg.x1&&point.y===seg.y1)||(point.x===seg.x2&&point.y===seg.y2)||point.equals(vert1)||point.equals(vert2)){vertex=true;}else{vertex=false;}
61106 if(vertex||edge){if(!point.equals(intersections[intersections.length-1])){intersections.push(point.clone());}
61107 if(i===0){if(point.equals(vert1)){continue;}}
61108 if(point.equals(vert2)){continue;}
61109 split=true;if(!point.equals(vert1)){points.push(point);}
61110 lines.push(new OpenLayers.Geometry.LineString(points));points=[point.clone()];}}}
61111 if(split){points.push(vert2.clone());lines.push(new OpenLayers.Geometry.LineString(points));}
61112 if(intersections.length>0){var xDir=seg.x1<seg.x2?1:-1;var yDir=seg.y1<seg.y2?1:-1;result={lines:lines,points:intersections.sort(function(p1,p2){return(xDir*p1.x-xDir*p2.x)||(yDir*p1.y-yDir*p2.y);})};}
61113 return result;},split:function(target,options){var results=null;var mutual=options&&options.mutual;var sourceSplit,targetSplit,sourceParts,targetParts;if(target instanceof OpenLayers.Geometry.LineString){var verts=this.getVertices();var vert1,vert2,seg,splits,lines,point;var points=[];sourceParts=[];for(var i=0,stop=verts.length-2;i<=stop;++i){vert1=verts[i];vert2=verts[i+1];seg={x1:vert1.x,y1:vert1.y,x2:vert2.x,y2:vert2.y};targetParts=targetParts||[target];if(mutual){points.push(vert1.clone());}
61114 for(var j=0;j<targetParts.length;++j){splits=targetParts[j].splitWithSegment(seg,options);if(splits){lines=splits.lines;if(lines.length>0){lines.unshift(j,1);Array.prototype.splice.apply(targetParts,lines);j+=lines.length-2;}
61115 if(mutual){for(var k=0,len=splits.points.length;k<len;++k){point=splits.points[k];if(!point.equals(vert1)){points.push(point);sourceParts.push(new OpenLayers.Geometry.LineString(points));if(point.equals(vert2)){points=[];}else{points=[point.clone()];}}}}}}}
61116 if(mutual&&sourceParts.length>0&&points.length>0){points.push(vert2.clone());sourceParts.push(new OpenLayers.Geometry.LineString(points));}}else{results=target.splitWith(this,options);}
61117 if(targetParts&&targetParts.length>1){targetSplit=true;}else{targetParts=[];}
61118 if(sourceParts&&sourceParts.length>1){sourceSplit=true;}else{sourceParts=[];}
61119 if(targetSplit||sourceSplit){if(mutual){results=[sourceParts,targetParts];}else{results=targetParts;}}
61120 return results;},splitWith:function(geometry,options){return geometry.split(this,options);},getVertices:function(nodes){var vertices;if(nodes===true){vertices=[this.components[0],this.components[this.components.length-1]];}else if(nodes===false){vertices=this.components.slice(1,this.components.length-1);}else{vertices=this.components.slice();}
61121 return vertices;},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var details=edge&&options&&options.details;var result,best={};var min=Number.POSITIVE_INFINITY;if(geometry instanceof OpenLayers.Geometry.Point){var segs=this.getSortedSegments();var x=geometry.x;var y=geometry.y;var seg;for(var i=0,len=segs.length;i<len;++i){seg=segs[i];result=OpenLayers.Geometry.distanceToSegment(geometry,seg);if(result.distance<min){min=result.distance;best=result;if(min===0){break;}}else{if(seg.x2>x&&((y>seg.y1&&y<seg.y2)||(y<seg.y1&&y>seg.y2))){break;}}}
61122 if(details){best={distance:best.distance,x0:best.x,y0:best.y,x1:x,y1:y};}else{best=best.distance;}}else if(geometry instanceof OpenLayers.Geometry.LineString){var segs0=this.getSortedSegments();var segs1=geometry.getSortedSegments();var seg0,seg1,intersection,x0,y0;var len1=segs1.length;var interOptions={point:true};outer:for(var i=0,len=segs0.length;i<len;++i){seg0=segs0[i];x0=seg0.x1;y0=seg0.y1;for(var j=0;j<len1;++j){seg1=segs1[j];intersection=OpenLayers.Geometry.segmentsIntersect(seg0,seg1,interOptions);if(intersection){min=0;best={distance:0,x0:intersection.x,y0:intersection.y,x1:intersection.x,y1:intersection.y};break outer;}else{result=OpenLayers.Geometry.distanceToSegment({x:x0,y:y0},seg1);if(result.distance<min){min=result.distance;best={distance:min,x0:x0,y0:y0,x1:result.x,y1:result.y};}}}}
61123 if(!details){best=best.distance;}
61124 if(min!==0){if(seg0){result=geometry.distanceTo(new OpenLayers.Geometry.Point(seg0.x2,seg0.y2),options);var dist=details?result.distance:result;if(dist<min){if(details){best={distance:min,x0:result.x1,y0:result.y1,x1:result.x0,y1:result.y0};}else{best=dist;}}}}}else{best=geometry.distanceTo(this,options);if(details){best={distance:best.distance,x0:best.x1,y0:best.y1,x1:best.x0,y1:best.y0};}}
61125 return best;},CLASS_NAME:"OpenLayers.Geometry.LineString"});OpenLayers.Control.TransformFeature=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforesetfeature","setfeature","beforetransform","transform","transformcomplete"],geometryTypes:null,layer:null,preserveAspectRatio:false,rotate:true,feature:null,renderIntent:"temporary",rotationHandleSymbolizer:null,box:null,center:null,scale:1,ratio:1,rotation:0,handles:null,rotationHandles:null,dragControl:null,initialize:function(layer,options){this.EVENT_TYPES=OpenLayers.Control.TransformFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.layer=layer;if(!this.rotationHandleSymbolizer){this.rotationHandleSymbolizer={stroke:false,pointRadius:10,fillOpacity:0,cursor:"pointer"};}
61126 this.createBox();this.createControl();},activate:function(){var activated=false;if(OpenLayers.Control.prototype.activate.apply(this,arguments)){this.dragControl.activate();this.layer.addFeatures([this.box]);this.rotate&&this.layer.addFeatures(this.rotationHandles);this.layer.addFeatures(this.handles);activated=true;}
61127 return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.layer.removeFeatures(this.handles);this.rotate&&this.layer.removeFeatures(this.rotationHandles);this.layer.removeFeatures([this.box]);this.dragControl.deactivate();deactivated=true;}
61128 return deactivated;},setMap:function(map){this.dragControl.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},setFeature:function(feature,initialParams){initialParams=OpenLayers.Util.applyDefaults(initialParams,{rotation:0,scale:1,ratio:1});var evt={feature:feature};var oldRotation=this.rotation;var oldCenter=this.center;OpenLayers.Util.extend(this,initialParams);if(this.events.triggerEvent("beforesetfeature",evt)===false){return;}
61129 this.feature=feature;this.activate();this._setfeature=true;var featureBounds=this.feature.geometry.getBounds();this.box.move(featureBounds.getCenterLonLat());this.box.geometry.rotate(-oldRotation,oldCenter);this._angle=0;var ll;if(this.rotation){var geom=feature.geometry.clone();geom.rotate(-this.rotation,this.center);var box=new OpenLayers.Feature.Vector(geom.getBounds().toGeometry());box.geometry.rotate(this.rotation,this.center);this.box.geometry.rotate(this.rotation,this.center);this.box.move(box.geometry.getBounds().getCenterLonLat());var llGeom=box.geometry.components[0].components[0];ll=llGeom.getBounds().getCenterLonLat();}else{ll=new OpenLayers.LonLat(featureBounds.left,featureBounds.bottom);}
61130 this.handles[0].move(ll);delete this._setfeature;this.events.triggerEvent("setfeature",evt);},createBox:function(){var control=this;this.center=new OpenLayers.Geometry.Point(0,0);var box=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([new OpenLayers.Geometry.Point(-1,-1),new OpenLayers.Geometry.Point(0,-1),new OpenLayers.Geometry.Point(1,-1),new OpenLayers.Geometry.Point(1,0),new OpenLayers.Geometry.Point(1,1),new OpenLayers.Geometry.Point(0,1),new OpenLayers.Geometry.Point(-1,1),new OpenLayers.Geometry.Point(-1,0),new OpenLayers.Geometry.Point(-1,-1)]),null,typeof this.renderIntent=="string"?null:this.renderIntent);box.geometry.move=function(x,y){control._moving=true;OpenLayers.Geometry.LineString.prototype.move.apply(this,arguments);control.center.move(x,y);delete control._moving;};var vertexMoveFn=function(x,y){OpenLayers.Geometry.Point.prototype.move.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.move(x,y);this._handle.geometry.move(x,y);};var vertexResizeFn=function(scale,center,ratio){OpenLayers.Geometry.Point.prototype.resize.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.resize(scale,center,ratio);this._handle.geometry.resize(scale,center,ratio);};var vertexRotateFn=function(angle,center){OpenLayers.Geometry.Point.prototype.rotate.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.rotate(angle,center);this._handle.geometry.rotate(angle,center);};var handleMoveFn=function(x,y){var oldX=this.x,oldY=this.y;OpenLayers.Geometry.Point.prototype.move.call(this,x,y);if(control._moving){return;}
61131 var evt=control.dragControl.handlers.drag.evt;var preserveAspectRatio=!control._setfeature&&control.preserveAspectRatio;var reshape=!preserveAspectRatio&&!(evt&&evt.shiftKey);var oldGeom=new OpenLayers.Geometry.Point(oldX,oldY);var centerGeometry=control.center;this.rotate(-control.rotation,centerGeometry);oldGeom.rotate(-control.rotation,centerGeometry);var dx1=this.x-centerGeometry.x;var dy1=this.y-centerGeometry.y;var dx0=dx1-(this.x-oldGeom.x);var dy0=dy1-(this.y-oldGeom.y);this.x=oldX;this.y=oldY;var scale,ratio=1;if(reshape){scale=Math.abs(dy0)<0.00001?1:dy1/dy0;ratio=(Math.abs(dx0)<0.00001?1:(dx1/dx0))/scale;}else{var l0=Math.sqrt((dx0*dx0)+(dy0*dy0));var l1=Math.sqrt((dx1*dx1)+(dy1*dy1));scale=l1/l0;}
61132 control._moving=true;control.box.geometry.rotate(-control.rotation,centerGeometry);delete control._moving;control.box.geometry.resize(scale,centerGeometry,ratio);control.box.geometry.rotate(control.rotation,centerGeometry);control.transformFeature({scale:scale,ratio:ratio});};var rotationHandleMoveFn=function(x,y){var oldX=this.x,oldY=this.y;OpenLayers.Geometry.Point.prototype.move.call(this,x,y);if(control._moving){return;}
61133 var evt=control.dragControl.handlers.drag.evt;var constrain=(evt&&evt.shiftKey)?45:1;var centerGeometry=control.center;var dx1=this.x-centerGeometry.x;var dy1=this.y-centerGeometry.y;var dx0=dx1-x;var dy0=dy1-y;this.x=oldX;this.y=oldY;var a0=Math.atan2(dy0,dx0);var a1=Math.atan2(dy1,dx1);var angle=a1-a0;angle*=180/Math.PI;control._angle=(control._angle+angle)%360;var diff=control.rotation%constrain;if(Math.abs(control._angle)>=constrain||diff!==0){angle=Math.round(control._angle/constrain)*constrain-
61134 diff;control._angle=0;control.box.geometry.rotate(angle,centerGeometry);control.transformFeature({rotation:angle});}};var handles=new Array(8);var rotationHandles=new Array(4);var geom,handle,rotationHandle;for(var i=0;i<8;++i){geom=box.geometry.components[i];handle=new OpenLayers.Feature.Vector(geom.clone(),null,typeof this.renderIntent=="string"?null:this.renderIntent);if(i%2==0){rotationHandle=new OpenLayers.Feature.Vector(geom.clone(),null,typeof this.rotationHandleSymbolizer=="string"?null:this.rotationHandleSymbolizer);rotationHandle.geometry.move=rotationHandleMoveFn;geom._rotationHandle=rotationHandle;rotationHandles[i/2]=rotationHandle;}
61135 geom.move=vertexMoveFn;geom.resize=vertexResizeFn;geom.rotate=vertexRotateFn;handle.geometry.move=handleMoveFn;geom._handle=handle;handles[i]=handle;}
61136 this.box=box;this.rotationHandles=rotationHandles;this.handles=handles;},createControl:function(){var control=this;this.dragControl=new OpenLayers.Control.DragFeature(this.layer,{documentDrag:true,moveFeature:function(pixel){if(this.feature===control.feature){this.feature=control.box;}
61137 OpenLayers.Control.DragFeature.prototype.moveFeature.apply(this,arguments);},onDrag:function(feature,pixel){if(feature===control.box){control.transformFeature({center:control.center});control.drawHandles();}},onStart:function(feature,pixel){var eligible=!control.geometryTypes||OpenLayers.Util.indexOf(control.geometryTypes,feature.geometry.CLASS_NAME)!==-1;var i=OpenLayers.Util.indexOf(control.handles,feature);i+=OpenLayers.Util.indexOf(control.rotationHandles,feature);if(feature!==control.feature&&feature!==control.box&&i==-2&&eligible){control.setFeature(feature);}},onComplete:function(feature,pixel){control.events.triggerEvent("transformcomplete",{feature:control.feature});}});},drawHandles:function(){var layer=this.layer;for(var i=0;i<8;++i){if(this.rotate&&i%2===0){layer.drawFeature(this.rotationHandles[i/2],this.rotationHandleSymbolizer);}
61138 layer.drawFeature(this.handles[i],this.renderIntent);}},transformFeature:function(mods){if(!this._setfeature){this.scale*=(mods.scale||1);this.ratio*=(mods.ratio||1);var oldRotation=this.rotation;this.rotation=(this.rotation+(mods.rotation||0))%360;if(this.events.triggerEvent("beforetransform",mods)!==false){var feature=this.feature;var geom=feature.geometry;var center=this.center;geom.rotate(-oldRotation,center);if(mods.scale||mods.ratio){geom.resize(mods.scale,center,mods.ratio);}else if(mods.center){feature.move(mods.center.getBounds().getCenterLonLat());}
61139 geom.rotate(this.rotation,center);this.layer.drawFeature(feature);feature.toState(OpenLayers.State.UPDATE);this.events.triggerEvent("transform",mods);}}
61140 this.layer.drawFeature(this.box,this.renderIntent);this.drawHandles();},destroy:function(){var geom;for(var i=0;i<8;++i){geom=this.box.geometry.components[i];geom._handle.destroy();geom._handle=null;geom._rotationHandle&&geom._rotationHandle.destroy();geom._rotationHandle=null;}
61141 this.box.destroy();this.box=null;this.layer=null;this.dragControl.destroy();OpenLayers.Control.prototype.destroy.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.TransformFeature"});OpenLayers.Format.GPX=OpenLayers.Class(OpenLayers.Format.XML,{extractWaypoints:true,extractTracks:true,extractRoutes:true,extractAttributes:true,initialize:function(options){this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
61142 var features=[];if(this.extractTracks){var tracks=doc.getElementsByTagName("trk");for(var i=0,len=tracks.length;i<len;i++){var attrs={};if(this.extractAttributes){attrs=this.parseAttributes(tracks[i]);}
61143 var segs=this.getElementsByTagNameNS(tracks[i],tracks[i].namespaceURI,"trkseg");for(var j=0,seglen=segs.length;j<seglen;j++){var track=this.extractSegment(segs[j],"trkpt");features.push(new OpenLayers.Feature.Vector(track,attrs));}}}
61144 if(this.extractRoutes){var routes=doc.getElementsByTagName("rte");for(var k=0,klen=routes.length;k<klen;k++){var attrs={};if(this.extractAttributes){attrs=this.parseAttributes(routes[k]);}
61145 var route=this.extractSegment(routes[k],"rtept");features.push(new OpenLayers.Feature.Vector(route,attrs));}}
61146 if(this.extractWaypoints){var waypoints=doc.getElementsByTagName("wpt");for(var l=0,len=waypoints.length;l<len;l++){var attrs={};if(this.extractAttributes){attrs=this.parseAttributes(waypoints[l]);}
61147 var wpt=new OpenLayers.Geometry.Point(waypoints[l].getAttribute("lon"),waypoints[l].getAttribute("lat"));features.push(new OpenLayers.Feature.Vector(wpt,attrs));}}
61148 if(this.internalProjection&&this.externalProjection){for(var g=0,featLength=features.length;g<featLength;g++){features[g].geometry.transform(this.externalProjection,this.internalProjection);}}
61149 return features;},extractSegment:function(segment,segmentType){var points=this.getElementsByTagNameNS(segment,segment.namespaceURI,segmentType);var point_features=[];for(var i=0,len=points.length;i<len;i++){point_features.push(new OpenLayers.Geometry.Point(points[i].getAttribute("lon"),points[i].getAttribute("lat")));}
61150 return new OpenLayers.Geometry.LineString(point_features);},parseAttributes:function(node){var attributes={};var attrNode=node.firstChild;while(attrNode){if(attrNode.nodeType==1){var value=attrNode.firstChild;if(value.nodeType==3||value.nodeType==4){name=(attrNode.prefix)?attrNode.nodeName.split(":")[1]:attrNode.nodeName;if(name!="trkseg"&&name!="rtept"){attributes[name]=value.nodeValue;}}}
61151 attrNode=attrNode.nextSibling;}
61152 return attributes;},CLASS_NAME:"OpenLayers.Format.GPX"});OpenLayers.Geometry.LinearRing=OpenLayers.Class(OpenLayers.Geometry.LineString,{componentTypes:["OpenLayers.Geometry.Point"],initialize:function(points){OpenLayers.Geometry.LineString.prototype.initialize.apply(this,arguments);},addComponent:function(point,index){var added=false;var lastPoint=this.components.pop();if(index!=null||!point.equals(lastPoint)){added=OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,arguments);}
61153 var firstPoint=this.components[0];OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,[firstPoint]);return added;},removeComponent:function(point){if(this.components.length>4){this.components.pop();OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,arguments);var firstPoint=this.components[0];OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,[firstPoint]);}},move:function(x,y){for(var i=0,len=this.components.length;i<len-1;i++){this.components[i].move(x,y);}},rotate:function(angle,origin){for(var i=0,len=this.components.length;i<len-1;++i){this.components[i].rotate(angle,origin);}},resize:function(scale,origin,ratio){for(var i=0,len=this.components.length;i<len-1;++i){this.components[i].resize(scale,origin,ratio);}
61154 return this;},transform:function(source,dest){if(source&&dest){for(var i=0,len=this.components.length;i<len-1;i++){var component=this.components[i];component.transform(source,dest);}
61155 this.bounds=null;}
61156 return this;},getCentroid:function(){if(this.components&&(this.components.length>2)){var sumX=0.0;var sumY=0.0;for(var i=0;i<this.components.length-1;i++){var b=this.components[i];var c=this.components[i+1];sumX+=(b.x+c.x)*(b.x*c.y-c.x*b.y);sumY+=(b.y+c.y)*(b.x*c.y-c.x*b.y);}
61157 var area=-1*this.getArea();var x=sumX/(6*area);var y=sumY/(6*area);return new OpenLayers.Geometry.Point(x,y);}else{return null;}},getArea:function(){var area=0.0;if(this.components&&(this.components.length>2)){var sum=0.0;for(var i=0,len=this.components.length;i<len-1;i++){var b=this.components[i];var c=this.components[i+1];sum+=(b.x+c.x)*(c.y-b.y);}
61158 area=-sum/2.0;}
61159 return area;},getGeodesicArea:function(projection){var ring=this;if(projection){var gg=new OpenLayers.Projection("EPSG:4326");if(!gg.equals(projection)){ring=this.clone().transform(projection,gg);}}
61160 var area=0.0;var len=ring.components&&ring.components.length;if(len>2){var p1,p2;for(var i=0;i<len-1;i++){p1=ring.components[i];p2=ring.components[i+1];area+=OpenLayers.Util.rad(p2.x-p1.x)*(2+Math.sin(OpenLayers.Util.rad(p1.y))+
61161 Math.sin(OpenLayers.Util.rad(p2.y)));}
61162 area=area*6378137.0*6378137.0/2.0;}
61163 return area;},containsPoint:function(point){var approx=OpenLayers.Number.limitSigDigs;var digs=14;var px=approx(point.x,digs);var py=approx(point.y,digs);function getX(y,x1,y1,x2,y2){return(((x1-x2)*y)+((x2*y1)-(x1*y2)))/(y1-y2);}
61164 var numSeg=this.components.length-1;var start,end,x1,y1,x2,y2,cx,cy;var crosses=0;for(var i=0;i<numSeg;++i){start=this.components[i];x1=approx(start.x,digs);y1=approx(start.y,digs);end=this.components[i+1];x2=approx(end.x,digs);y2=approx(end.y,digs);if(y1==y2){if(py==y1){if(x1<=x2&&(px>=x1&&px<=x2)||x1>=x2&&(px<=x1&&px>=x2)){crosses=-1;break;}}
61165 continue;}
61166 cx=approx(getX(py,x1,y1,x2,y2),digs);if(cx==px){if(y1<y2&&(py>=y1&&py<=y2)||y1>y2&&(py<=y1&&py>=y2)){crosses=-1;break;}}
61167 if(cx<=px){continue;}
61168 if(x1!=x2&&(cx<Math.min(x1,x2)||cx>Math.max(x1,x2))){continue;}
61169 if(y1<y2&&(py>=y1&&py<y2)||y1>y2&&(py<y1&&py>=y2)){++crosses;}}
61170 var contained=(crosses==-1)?1:!!(crosses&1);return contained;},intersects:function(geometry){var intersect=false;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){intersect=this.containsPoint(geometry);}else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LineString"){intersect=geometry.intersects(this);}else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LinearRing"){intersect=OpenLayers.Geometry.LineString.prototype.intersects.apply(this,[geometry]);}else{for(var i=0,len=geometry.components.length;i<len;++i){intersect=geometry.components[i].intersects(this);if(intersect){break;}}}
61171 return intersect;},getVertices:function(nodes){return(nodes===true)?[]:this.components.slice(0,this.components.length-1);},CLASS_NAME:"OpenLayers.Geometry.LinearRing"});OpenLayers.Geometry.MultiLineString=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.LineString"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},split:function(geometry,options){var results=null;var mutual=options&&options.mutual;var splits,sourceLine,sourceLines,sourceSplit,targetSplit;var sourceParts=[];var targetParts=[geometry];for(var i=0,len=this.components.length;i<len;++i){sourceLine=this.components[i];sourceSplit=false;for(var j=0;j<targetParts.length;++j){splits=sourceLine.split(targetParts[j],options);if(splits){if(mutual){sourceLines=splits[0];for(var k=0,klen=sourceLines.length;k<klen;++k){if(k===0&&sourceParts.length){sourceParts[sourceParts.length-1].addComponent(sourceLines[k]);}else{sourceParts.push(new OpenLayers.Geometry.MultiLineString([sourceLines[k]]));}}
61172 sourceSplit=true;splits=splits[1];}
61173 if(splits.length){splits.unshift(j,1);Array.prototype.splice.apply(targetParts,splits);break;}}}
61174 if(!sourceSplit){if(sourceParts.length){sourceParts[sourceParts.length-1].addComponent(sourceLine.clone());}else{sourceParts=[new OpenLayers.Geometry.MultiLineString(sourceLine.clone())];}}}
61175 if(sourceParts&&sourceParts.length>1){sourceSplit=true;}else{sourceParts=[];}
61176 if(targetParts&&targetParts.length>1){targetSplit=true;}else{targetParts=[];}
61177 if(sourceSplit||targetSplit){if(mutual){results=[sourceParts,targetParts];}else{results=targetParts;}}
61178 return results;},splitWith:function(geometry,options){var results=null;var mutual=options&&options.mutual;var splits,targetLine,sourceLines,sourceSplit,targetSplit,sourceParts,targetParts;if(geometry instanceof OpenLayers.Geometry.LineString){targetParts=[];sourceParts=[geometry];for(var i=0,len=this.components.length;i<len;++i){targetSplit=false;targetLine=this.components[i];for(var j=0;j<sourceParts.length;++j){splits=sourceParts[j].split(targetLine,options);if(splits){if(mutual){sourceLines=splits[0];if(sourceLines.length){sourceLines.unshift(j,1);Array.prototype.splice.apply(sourceParts,sourceLines);j+=sourceLines.length-2;}
61179 splits=splits[1];if(splits.length===0){splits=[targetLine.clone()];}}
61180 for(var k=0,klen=splits.length;k<klen;++k){if(k===0&&targetParts.length){targetParts[targetParts.length-1].addComponent(splits[k]);}else{targetParts.push(new OpenLayers.Geometry.MultiLineString([splits[k]]));}}
61181 targetSplit=true;}}
61182 if(!targetSplit){if(targetParts.length){targetParts[targetParts.length-1].addComponent(targetLine.clone());}else{targetParts=[new OpenLayers.Geometry.MultiLineString([targetLine.clone()])];}}}}else{results=geometry.split(this);}
61183 if(sourceParts&&sourceParts.length>1){sourceSplit=true;}else{sourceParts=[];}
61184 if(targetParts&&targetParts.length>1){targetSplit=true;}else{targetParts=[];}
61185 if(sourceSplit||targetSplit){if(mutual){results=[sourceParts,targetParts];}else{results=targetParts;}}
61186 return results;},CLASS_NAME:"OpenLayers.Geometry.MultiLineString"});OpenLayers.Handler.Path=OpenLayers.Class(OpenLayers.Handler.Point,{line:null,freehand:false,freehandToggle:'shiftKey',initialize:function(control,callbacks,options){OpenLayers.Handler.Point.prototype.initialize.apply(this,arguments);},createFeature:function(pixel){var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.line=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([this.point.geometry]));this.callback("create",[this.point.geometry,this.getSketch()]);this.point.geometry.clearBounds();this.layer.addFeatures([this.line,this.point],{silent:true});},destroyFeature:function(){OpenLayers.Handler.Point.prototype.destroyFeature.apply(this);this.line=null;},removePoint:function(){if(this.point){this.layer.removeFeatures([this.point]);}},addPoint:function(pixel){this.layer.removeFeatures([this.point]);var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.line.geometry.addComponent(this.point.geometry,this.line.geometry.components.length);this.callback("point",[this.point.geometry,this.getGeometry()]);this.callback("modify",[this.point.geometry,this.getSketch()]);this.drawFeature();},freehandMode:function(evt){return(this.freehandToggle&&evt[this.freehandToggle])?!this.freehand:this.freehand;},modifyFeature:function(pixel){var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point.geometry.x=lonlat.lon;this.point.geometry.y=lonlat.lat;this.callback("modify",[this.point.geometry,this.getSketch()]);this.point.geometry.clearBounds();this.drawFeature();},drawFeature:function(){this.layer.drawFeature(this.line,this.style);this.layer.drawFeature(this.point,this.style);},getSketch:function(){return this.line;},getGeometry:function(){var geometry=this.line&&this.line.geometry;if(geometry&&this.multi){geometry=new OpenLayers.Geometry.MultiLineString([geometry]);}
61187 return geometry;},mousedown:function(evt){if(this.lastDown&&this.lastDown.equals(evt.xy)){return false;}
61188 if(this.lastDown==null){if(this.persist){this.destroyFeature();}
61189 this.createFeature(evt.xy);}else if((this.lastUp==null)||!this.lastUp.equals(evt.xy)){this.addPoint(evt.xy);}
61190 this.mouseDown=true;this.lastDown=evt.xy;this.drawing=true;return false;},mousemove:function(evt){if(this.drawing){if(this.mouseDown&&this.freehandMode(evt)){this.addPoint(evt.xy);}else{this.modifyFeature(evt.xy);}}
61191 return true;},mouseup:function(evt){this.mouseDown=false;if(this.drawing){if(this.freehandMode(evt)){this.removePoint();this.finalize();}else{if(this.lastUp==null){this.addPoint(evt.xy);}
61192 this.lastUp=evt.xy;}
61193 return false;}
61194 return true;},dblclick:function(evt){if(!this.freehandMode(evt)){var index=this.line.geometry.components.length-1;this.line.geometry.removeComponent(this.line.geometry.components[index]);this.removePoint();this.finalize();}
61195 return false;},CLASS_NAME:"OpenLayers.Handler.Path"});OpenLayers.Control.Split=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforesplit","split","aftersplit"],layer:null,source:null,sourceOptions:null,tolerance:null,edge:true,deferDelete:false,mutual:true,targetFilter:null,sourceFilter:null,handler:null,initialize:function(options){Array.prototype.push.apply(this.EVENT_TYPES,OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.options=options||{};if(this.options.source){this.setSource(this.options.source);}},setSource:function(layer){if(this.active){this.deactivate();if(this.handler){this.handler.destroy();delete this.handler;}
61196 this.source=layer;this.activate();}else{this.source=layer;}},activate:function(){var activated=OpenLayers.Control.prototype.activate.call(this);if(activated){if(!this.source){if(!this.handler){this.handler=new OpenLayers.Handler.Path(this,{done:function(geometry){this.onSketchComplete({feature:new OpenLayers.Feature.Vector(geometry)});}},{layerOptions:this.sourceOptions});}
61197 this.handler.activate();}else if(this.source.events){this.source.events.on({sketchcomplete:this.onSketchComplete,afterfeaturemodified:this.afterFeatureModified,scope:this});}}
61198 return activated;},deactivate:function(){var deactivated=OpenLayers.Control.prototype.deactivate.call(this);if(deactivated){if(this.source&&this.source.events){this.layer.events.un({sketchcomplete:this.onSketchComplete,afterfeaturemodified:this.afterFeatureModified,scope:this});}}
61199 return deactivated;},onSketchComplete:function(event){this.feature=null;return!this.considerSplit(event.feature);},afterFeatureModified:function(event){if(event.modified){var feature=event.feature;if(feature.geometry instanceof OpenLayers.Geometry.LineString||feature.geometry instanceof OpenLayers.Geometry.MultiLineString){this.feature=event.feature;this.considerSplit(event.feature);}}},removeByGeometry:function(features,geometry){for(var i=0,len=features.length;i<len;++i){if(features[i].geometry===geometry){features.splice(i,1);break;}}},isEligible:function(target){return(target.state!==OpenLayers.State.DELETE)&&(target.geometry instanceof OpenLayers.Geometry.LineString||target.geometry instanceof OpenLayers.Geometry.MultiLineString)&&(this.feature!==target)&&(!this.targetFilter||this.targetFilter.evaluate(target.attributes));},considerSplit:function(feature){var sourceSplit=false;var targetSplit=false;if(!this.sourceFilter||this.sourceFilter.evaluate(feature.attributes)){var features=this.layer&&this.layer.features||[];var target,results,proceed;var additions=[],removals=[];var mutual=(this.layer===this.source)&&this.mutual;var options={edge:this.edge,tolerance:this.tolerance,mutual:mutual};var sourceParts=[feature.geometry];var targetFeature,targetParts;var source,parts;for(var i=0,len=features.length;i<len;++i){targetFeature=features[i];if(this.isEligible(targetFeature)){targetParts=[targetFeature.geometry];for(var j=0;j<sourceParts.length;++j){source=sourceParts[j];for(var k=0;k<targetParts.length;++k){target=targetParts[k];if(source.getBounds().intersectsBounds(target.getBounds())){results=source.split(target,options);if(results){proceed=this.events.triggerEvent("beforesplit",{source:feature,target:targetFeature});if(proceed!==false){if(mutual){parts=results[0];if(parts.length>1){parts.unshift(j,1);Array.prototype.splice.apply(sourceParts,parts);j+=parts.length-3;}
61200 results=results[1];}
61201 if(results.length>1){results.unshift(k,1);Array.prototype.splice.apply(targetParts,results);k+=results.length-3;}}}}}}
61202 if(targetParts&&targetParts.length>1){this.geomsToFeatures(targetFeature,targetParts);this.events.triggerEvent("split",{original:targetFeature,features:targetParts});Array.prototype.push.apply(additions,targetParts);removals.push(targetFeature);targetSplit=true;}}}
61203 if(sourceParts&&sourceParts.length>1){this.geomsToFeatures(feature,sourceParts);this.events.triggerEvent("split",{original:feature,features:sourceParts});Array.prototype.push.apply(additions,sourceParts);removals.push(feature);sourceSplit=true;}
61204 if(sourceSplit||targetSplit){if(this.deferDelete){var feat,destroys=[];for(var i=0,len=removals.length;i<len;++i){feat=removals[i];if(feat.state===OpenLayers.State.INSERT){destroys.push(feat);}else{feat.state=OpenLayers.State.DELETE;this.layer.drawFeature(feat);}}
61205 this.layer.destroyFeatures(destroys,{silent:true});for(var i=0,len=additions.length;i<len;++i){additions[i].state=OpenLayers.State.INSERT;}}else{this.layer.destroyFeatures(removals,{silent:true});}
61206 this.layer.addFeatures(additions,{silent:true});this.events.triggerEvent("aftersplit",{source:feature,features:additions});}}
61207 return sourceSplit;},geomsToFeatures:function(feature,geoms){var clone=feature.clone();delete clone.geometry;var newFeature;for(var i=0,len=geoms.length;i<len;++i){newFeature=clone.clone();newFeature.geometry=geoms[i];newFeature.state=OpenLayers.State.INSERT;geoms[i]=newFeature;}},destroy:function(){if(this.active){this.deactivate();}
61208 OpenLayers.Control.prototype.destroy.call(this);},CLASS_NAME:"OpenLayers.Control.Split"});OpenLayers.Geometry.Polygon=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.LinearRing"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},getArea:function(){var area=0.0;if(this.components&&(this.components.length>0)){area+=Math.abs(this.components[0].getArea());for(var i=1,len=this.components.length;i<len;i++){area-=Math.abs(this.components[i].getArea());}}
61209 return area;},getGeodesicArea:function(projection){var area=0.0;if(this.components&&(this.components.length>0)){area+=Math.abs(this.components[0].getGeodesicArea(projection));for(var i=1,len=this.components.length;i<len;i++){area-=Math.abs(this.components[i].getGeodesicArea(projection));}}
61210 return area;},containsPoint:function(point){var numRings=this.components.length;var contained=false;if(numRings>0){contained=this.components[0].containsPoint(point);if(contained!==1){if(contained&&numRings>1){var hole;for(var i=1;i<numRings;++i){hole=this.components[i].containsPoint(point);if(hole){if(hole===1){contained=1;}else{contained=false;}
61211 break;}}}}}
61212 return contained;},intersects:function(geometry){var intersect=false;var i,len;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){intersect=this.containsPoint(geometry);}else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LineString"||geometry.CLASS_NAME=="OpenLayers.Geometry.LinearRing"){for(i=0,len=this.components.length;i<len;++i){intersect=geometry.intersects(this.components[i]);if(intersect){break;}}
61213 if(!intersect){for(i=0,len=geometry.components.length;i<len;++i){intersect=this.containsPoint(geometry.components[i]);if(intersect){break;}}}}else{for(i=0,len=geometry.components.length;i<len;++i){intersect=this.intersects(geometry.components[i]);if(intersect){break;}}}
61214 if(!intersect&&geometry.CLASS_NAME=="OpenLayers.Geometry.Polygon"){var ring=this.components[0];for(i=0,len=ring.components.length;i<len;++i){intersect=geometry.containsPoint(ring.components[i]);if(intersect){break;}}}
61215 return intersect;},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var result;if(!edge&&this.intersects(geometry)){result=0;}else{result=OpenLayers.Geometry.Collection.prototype.distanceTo.apply(this,[geometry,options]);}
61216 return result;},CLASS_NAME:"OpenLayers.Geometry.Polygon"});OpenLayers.Geometry.Polygon.createRegularPolygon=function(origin,radius,sides,rotation){var angle=Math.PI*((1/sides)-(1/2));if(rotation){angle+=(rotation/180)*Math.PI;}
61217 var rotatedAngle,x,y;var points=[];for(var i=0;i<sides;++i){rotatedAngle=angle+(i*2*Math.PI/sides);x=origin.x+(radius*Math.cos(rotatedAngle));y=origin.y+(radius*Math.sin(rotatedAngle));points.push(new OpenLayers.Geometry.Point(x,y));}
61218 var ring=new OpenLayers.Geometry.LinearRing(points);return new OpenLayers.Geometry.Polygon([ring]);};OpenLayers.Format.GeoRSS=OpenLayers.Class(OpenLayers.Format.XML,{rssns:"http://backend.userland.com/rss2",featureNS:"http://mapserver.gis.umn.edu/mapserver",georssns:"http://www.georss.org/georss",geons:"http://www.w3.org/2003/01/geo/wgs84_pos#",featureTitle:"Untitled",featureDescription:"No Description",gmlParser:null,xy:false,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},createGeometryFromItem:function(item){var point=this.getElementsByTagNameNS(item,this.georssns,"point");var lat=this.getElementsByTagNameNS(item,this.geons,'lat');var lon=this.getElementsByTagNameNS(item,this.geons,'long');var line=this.getElementsByTagNameNS(item,this.georssns,"line");var polygon=this.getElementsByTagNameNS(item,this.georssns,"polygon");var where=this.getElementsByTagNameNS(item,this.georssns,"where");var box=this.getElementsByTagNameNS(item,this.georssns,"box");if(point.length>0||(lat.length>0&&lon.length>0)){var location;if(point.length>0){location=OpenLayers.String.trim(point[0].firstChild.nodeValue).split(/\s+/);if(location.length!=2){location=OpenLayers.String.trim(point[0].firstChild.nodeValue).split(/\s*,\s*/);}}else{location=[parseFloat(lat[0].firstChild.nodeValue),parseFloat(lon[0].firstChild.nodeValue)];}
61219 var geometry=new OpenLayers.Geometry.Point(parseFloat(location[1]),parseFloat(location[0]));}else if(line.length>0){var coords=OpenLayers.String.trim(this.concatChildValues(line[0])).split(/\s+/);var components=[];var point;for(var i=0,len=coords.length;i<len;i+=2){point=new OpenLayers.Geometry.Point(parseFloat(coords[i+1]),parseFloat(coords[i]));components.push(point);}
61220 geometry=new OpenLayers.Geometry.LineString(components);}else if(polygon.length>0){var coords=OpenLayers.String.trim(this.concatChildValues(polygon[0])).split(/\s+/);var components=[];var point;for(var i=0,len=coords.length;i<len;i+=2){point=new OpenLayers.Geometry.Point(parseFloat(coords[i+1]),parseFloat(coords[i]));components.push(point);}
61221 geometry=new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);}else if(where.length>0){if(!this.gmlParser){this.gmlParser=new OpenLayers.Format.GML({'xy':this.xy});}
61222 var feature=this.gmlParser.parseFeature(where[0]);geometry=feature.geometry;}else if(box.length>0){var coords=OpenLayers.String.trim(box[0].firstChild.nodeValue).split(/\s+/);var components=[];var point;if(coords.length>3){point=new OpenLayers.Geometry.Point(parseFloat(coords[1]),parseFloat(coords[0]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[1]),parseFloat(coords[2]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[3]),parseFloat(coords[2]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[3]),parseFloat(coords[0]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[1]),parseFloat(coords[0]));components.push(point);}
61223 geometry=new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);}
61224 if(geometry&&this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}
61225 return geometry;},createFeatureFromItem:function(item){var geometry=this.createGeometryFromItem(item);var title=this.getChildValue(item,"*","title",this.featureTitle);var description=this.getChildValue(item,"*","description",this.getChildValue(item,"*","content",this.getChildValue(item,"*","summary",this.featureDescription)));var link=this.getChildValue(item,"*","link");if(!link){try{link=this.getElementsByTagNameNS(item,"*","link")[0].getAttribute("href");}catch(e){link=null;}}
61226 var id=this.getChildValue(item,"*","id",null);var data={"title":title,"description":description,"link":link};var feature=new OpenLayers.Feature.Vector(geometry,data);feature.fid=id;return feature;},getChildValue:function(node,nsuri,name,def){var value;var eles=this.getElementsByTagNameNS(node,nsuri,name);if(eles&&eles[0]&&eles[0].firstChild&&eles[0].firstChild.nodeValue){value=eles[0].firstChild.nodeValue;}else{value=(def==undefined)?"":def;}
61227 return value;},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
61228 var itemlist=null;itemlist=this.getElementsByTagNameNS(doc,'*','item');if(itemlist.length==0){itemlist=this.getElementsByTagNameNS(doc,'*','entry');}
61229 var numItems=itemlist.length;var features=new Array(numItems);for(var i=0;i<numItems;i++){features[i]=this.createFeatureFromItem(itemlist[i]);}
61230 return features;},write:function(features){var georss;if(features instanceof Array){georss=this.createElementNS(this.rssns,"rss");for(var i=0,len=features.length;i<len;i++){georss.appendChild(this.createFeatureXML(features[i]));}}else{georss=this.createFeatureXML(features);}
61231 return OpenLayers.Format.XML.prototype.write.apply(this,[georss]);},createFeatureXML:function(feature){var geometryNode=this.buildGeometryNode(feature.geometry);var featureNode=this.createElementNS(this.rssns,"item");var titleNode=this.createElementNS(this.rssns,"title");titleNode.appendChild(this.createTextNode(feature.attributes.title?feature.attributes.title:""));var descNode=this.createElementNS(this.rssns,"description");descNode.appendChild(this.createTextNode(feature.attributes.description?feature.attributes.description:""));featureNode.appendChild(titleNode);featureNode.appendChild(descNode);if(feature.attributes.link){var linkNode=this.createElementNS(this.rssns,"link");linkNode.appendChild(this.createTextNode(feature.attributes.link));featureNode.appendChild(linkNode);}
61232 for(var attr in feature.attributes){if(attr=="link"||attr=="title"||attr=="description"){continue;}
61233 var attrText=this.createTextNode(feature.attributes[attr]);var nodename=attr;if(attr.search(":")!=-1){nodename=attr.split(":")[1];}
61234 var attrContainer=this.createElementNS(this.featureNS,"feature:"+nodename);attrContainer.appendChild(attrText);featureNode.appendChild(attrContainer);}
61235 featureNode.appendChild(geometryNode);return featureNode;},buildGeometryNode:function(geometry){if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
61236 var node;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Polygon"){node=this.createElementNS(this.georssns,'georss:polygon');node.appendChild(this.buildCoordinatesNode(geometry.components[0]));}
61237 else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LineString"){node=this.createElementNS(this.georssns,'georss:line');node.appendChild(this.buildCoordinatesNode(geometry));}
61238 else if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){node=this.createElementNS(this.georssns,'georss:point');node.appendChild(this.buildCoordinatesNode(geometry));}else{throw"Couldn't parse "+geometry.CLASS_NAME;}
61239 return node;},buildCoordinatesNode:function(geometry){var points=null;if(geometry.components){points=geometry.components;}
61240 var path;if(points){var numPoints=points.length;var parts=new Array(numPoints);for(var i=0;i<numPoints;i++){parts[i]=points[i].y+" "+points[i].x;}
61241 path=parts.join(" ");}else{path=geometry.y+" "+geometry.x;}
61242 return this.createTextNode(path);},CLASS_NAME:"OpenLayers.Format.GeoRSS"});OpenLayers.Format.KML=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{kml:"http://www.opengis.net/kml/2.2",gx:"http://www.google.com/kml/ext/2.2"},kmlns:"http://earth.google.com/kml/2.0",placemarksDesc:"No description available",foldersName:"OpenLayers export",foldersDesc:"Exported on "+new Date(),extractAttributes:true,extractStyles:false,extractTracks:false,trackAttributes:null,internalns:null,features:null,styles:null,styleBaseUrl:"",fetched:null,maxDepth:0,initialize:function(options){this.regExes={trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g),kmlColor:(/(\w{2})(\w{2})(\w{2})(\w{2})/),kmlIconPalette:(/root:\/\/icons\/palette-(\d+)(\.\w+)/),straightBracket:(/\$\[(.*?)\]/g)};this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){this.features=[];this.styles={};this.fetched={};var options={depth:0,styleBaseUrl:this.styleBaseUrl};return this.parseData(data,options);},parseData:function(data,options){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61243 var types=["Link","NetworkLink","Style","StyleMap","Placemark"];for(var i=0,len=types.length;i<len;++i){var type=types[i];var nodes=this.getElementsByTagNameNS(data,"*",type);if(nodes.length==0){continue;}
61244 switch(type.toLowerCase()){case"link":case"networklink":this.parseLinks(nodes,options);break;case"style":if(this.extractStyles){this.parseStyles(nodes,options);}
61245 break;case"stylemap":if(this.extractStyles){this.parseStyleMaps(nodes,options);}
61246 break;case"placemark":this.parseFeatures(nodes,options);break;}}
61247 return this.features;},parseLinks:function(nodes,options){if(options.depth>=this.maxDepth){return false;}
61248 var newOptions=OpenLayers.Util.extend({},options);newOptions.depth++;for(var i=0,len=nodes.length;i<len;i++){var href=this.parseProperty(nodes[i],"*","href");if(href&&!this.fetched[href]){this.fetched[href]=true;var data=this.fetchLink(href);if(data){this.parseData(data,newOptions);}}}},fetchLink:function(href){var request=OpenLayers.Request.GET({url:href,async:false});if(request){return request.responseText;}},parseStyles:function(nodes,options){for(var i=0,len=nodes.length;i<len;i++){var style=this.parseStyle(nodes[i]);if(style){var styleName=(options.styleBaseUrl||"")+"#"+style.id;this.styles[styleName]=style;}}},parseKmlColor:function(kmlColor){var color=null;if(kmlColor){var matches=kmlColor.match(this.regExes.kmlColor);if(matches){color={color:'#'+matches[4]+matches[3]+matches[2],opacity:parseInt(matches[1],16)/255};}}
61249 return color;},parseStyle:function(node){var style={};var types=["LineStyle","PolyStyle","IconStyle","BalloonStyle","LabelStyle"];var type,nodeList,geometry,parser;for(var i=0,len=types.length;i<len;++i){type=types[i];styleTypeNode=this.getElementsByTagNameNS(node,"*",type)[0];if(!styleTypeNode){continue;}
61250 switch(type.toLowerCase()){case"linestyle":var kmlColor=this.parseProperty(styleTypeNode,"*","color");var color=this.parseKmlColor(kmlColor);if(color){style["strokeColor"]=color.color;style["strokeOpacity"]=color.opacity;}
61251 var width=this.parseProperty(styleTypeNode,"*","width");if(width){style["strokeWidth"]=width;}
61252 break;case"polystyle":var kmlColor=this.parseProperty(styleTypeNode,"*","color");var color=this.parseKmlColor(kmlColor);if(color){style["fillOpacity"]=color.opacity;style["fillColor"]=color.color;}
61253 var fill=this.parseProperty(styleTypeNode,"*","fill");if(fill=="0"){style["fillColor"]="none";}
61254 var outline=this.parseProperty(styleTypeNode,"*","outline");if(outline=="0"){style["strokeWidth"]="0";}
61255 break;case"iconstyle":var scale=parseFloat(this.parseProperty(styleTypeNode,"*","scale")||1);var width=32*scale;var height=32*scale;var iconNode=this.getElementsByTagNameNS(styleTypeNode,"*","Icon")[0];if(iconNode){var href=this.parseProperty(iconNode,"*","href");if(href){var w=this.parseProperty(iconNode,"*","w");var h=this.parseProperty(iconNode,"*","h");var google="http://maps.google.com/mapfiles/kml";if(OpenLayers.String.startsWith(href,google)&&!w&&!h){w=64;h=64;scale=scale/2;}
61256 w=w||h;h=h||w;if(w){width=parseInt(w)*scale;}
61257 if(h){height=parseInt(h)*scale;}
61258 var matches=href.match(this.regExes.kmlIconPalette);if(matches){var palette=matches[1];var file_extension=matches[2];var x=this.parseProperty(iconNode,"*","x");var y=this.parseProperty(iconNode,"*","y");var posX=x?x/32:0;var posY=y?(7-y/32):7;var pos=posY*8+posX;href="http://maps.google.com/mapfiles/kml/pal"
61259 +palette+"/icon"+pos+file_extension;}
61260 style["graphicOpacity"]=1;style["externalGraphic"]=href;}}
61261 var hotSpotNode=this.getElementsByTagNameNS(styleTypeNode,"*","hotSpot")[0];if(hotSpotNode){var x=parseFloat(hotSpotNode.getAttribute("x"));var y=parseFloat(hotSpotNode.getAttribute("y"));var xUnits=hotSpotNode.getAttribute("xunits");if(xUnits=="pixels"){style["graphicXOffset"]=-x*scale;}
61262 else if(xUnits=="insetPixels"){style["graphicXOffset"]=-width+(x*scale);}
61263 else if(xUnits=="fraction"){style["graphicXOffset"]=-width*x;}
61264 var yUnits=hotSpotNode.getAttribute("yunits");if(yUnits=="pixels"){style["graphicYOffset"]=-height+(y*scale)+1;}
61265 else if(yUnits=="insetPixels"){style["graphicYOffset"]=-(y*scale)+1;}
61266 else if(yUnits=="fraction"){style["graphicYOffset"]=-height*(1-y)+1;}}
61267 style["graphicWidth"]=width;style["graphicHeight"]=height;break;case"balloonstyle":var balloonStyle=OpenLayers.Util.getXmlNodeValue(styleTypeNode);if(balloonStyle){style["balloonStyle"]=balloonStyle.replace(this.regExes.straightBracket,"${$1}");}
61268 break;case"labelstyle":var kmlColor=this.parseProperty(styleTypeNode,"*","color");var color=this.parseKmlColor(kmlColor);if(color){style["fontColor"]=color.color;style["fontOpacity"]=color.opacity;}
61269 break;default:}}
61270 if(!style["strokeColor"]&&style["fillColor"]){style["strokeColor"]=style["fillColor"];}
61271 var id=node.getAttribute("id");if(id&&style){style.id=id;}
61272 return style;},parseStyleMaps:function(nodes,options){for(var i=0,len=nodes.length;i<len;i++){var node=nodes[i];var pairs=this.getElementsByTagNameNS(node,"*","Pair");var id=node.getAttribute("id");for(var j=0,jlen=pairs.length;j<jlen;j++){var pair=pairs[j];var key=this.parseProperty(pair,"*","key");var styleUrl=this.parseProperty(pair,"*","styleUrl");if(styleUrl&&key=="normal"){this.styles[(options.styleBaseUrl||"")+"#"+id]=this.styles[(options.styleBaseUrl||"")+styleUrl];}
61273 if(styleUrl&&key=="highlight"){}}}},parseFeatures:function(nodes,options){var features=[];for(var i=0,len=nodes.length;i<len;i++){var featureNode=nodes[i];var feature=this.parseFeature.apply(this,[featureNode]);if(feature){if(this.extractStyles&&feature.attributes&&feature.attributes.styleUrl){feature.style=this.getStyle(feature.attributes.styleUrl,options);}
61274 if(this.extractStyles){var inlineStyleNode=this.getElementsByTagNameNS(featureNode,"*","Style")[0];if(inlineStyleNode){var inlineStyle=this.parseStyle(inlineStyleNode);if(inlineStyle){feature.style=OpenLayers.Util.extend(feature.style,inlineStyle);}}}
61275 if(this.extractTracks){var tracks=this.getElementsByTagNameNS(featureNode,this.namespaces.gx,"Track");if(tracks&&tracks.length>0){var track=tracks[0];var container={features:[],feature:feature};this.readNode(track,container);if(container.features.length>0){features.push.apply(features,container.features);}}}else{features.push(feature);}}else{throw"Bad Placemark: "+i;}}
61276 this.features=this.features.concat(features);},readers:{"kml":{"when":function(node,container){container.whens.push(OpenLayers.Date.parse(this.getChildValue(node)));},"_trackPointAttribute":function(node,container){var name=node.nodeName.split(":").pop();container.attributes[name].push(this.getChildValue(node));}},"gx":{"Track":function(node,container){var obj={whens:[],points:[],angles:[]};if(this.trackAttributes){var name;obj.attributes={};for(var i=0,ii=this.trackAttributes.length;i<ii;++i){name=this.trackAttributes[i];obj.attributes[name]=[];if(!(name in this.readers.kml)){this.readers.kml[name]=this.readers.kml._trackPointAttribute;}}}
61277 this.readChildNodes(node,obj);if(obj.whens.length!==obj.points.length){throw new Error("gx:Track with unequal number of when ("+obj.whens.length+") and gx:coord ("+obj.points.length+") elements.");}
61278 var hasAngles=obj.angles.length>0;if(hasAngles&&obj.whens.length!==obj.angles.length){throw new Error("gx:Track with unequal number of when ("+obj.whens.length+") and gx:angles ("+obj.angles.length+") elements.");}
61279 var feature,point,angles;for(var i=0,ii=obj.whens.length;i<ii;++i){feature=container.feature.clone();feature.fid=container.feature.fid||container.feature.id;point=obj.points[i];feature.geometry=point;if("z"in point){feature.attributes.altitude=point.z;}
61280 if(this.internalProjection&&this.externalProjection){feature.geometry.transform(this.externalProjection,this.internalProjection);}
61281 if(this.trackAttributes){for(var j=0,jj=this.trackAttributes.length;j<jj;++j){feature.attributes[name]=obj.attributes[this.trackAttributes[j]][i];}}
61282 feature.attributes.when=obj.whens[i];feature.attributes.trackId=container.feature.id;if(hasAngles){angles=obj.angles[i];feature.attributes.heading=parseFloat(angles[0]);feature.attributes.tilt=parseFloat(angles[1]);feature.attributes.roll=parseFloat(angles[2]);}
61283 container.features.push(feature);}},"coord":function(node,container){var str=this.getChildValue(node);var coords=str.replace(this.regExes.trimSpace,"").split(/\s+/);var point=new OpenLayers.Geometry.Point(coords[0],coords[1]);if(coords.length>2){point.z=parseFloat(coords[2]);}
61284 container.points.push(point);},"angles":function(node,container){var str=this.getChildValue(node);var parts=str.replace(this.regExes.trimSpace,"").split(/\s+/);container.angles.push(parts);}}},parseFeature:function(node){var order=["MultiGeometry","Polygon","LineString","Point"];var type,nodeList,geometry,parser;for(var i=0,len=order.length;i<len;++i){type=order[i];this.internalns=node.namespaceURI?node.namespaceURI:this.kmlns;nodeList=this.getElementsByTagNameNS(node,this.internalns,type);if(nodeList.length>0){var parser=this.parseGeometry[type.toLowerCase()];if(parser){geometry=parser.apply(this,[nodeList[0]]);if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}}else{OpenLayers.Console.error(OpenLayers.i18n("unsupportedGeometryType",{'geomType':type}));}
61285 break;}}
61286 var attributes;if(this.extractAttributes){attributes=this.parseAttributes(node);}
61287 var feature=new OpenLayers.Feature.Vector(geometry,attributes);var fid=node.getAttribute("id")||node.getAttribute("name");if(fid!=null){feature.fid=fid;}
61288 return feature;},getStyle:function(styleUrl,options){var styleBaseUrl=OpenLayers.Util.removeTail(styleUrl);var newOptions=OpenLayers.Util.extend({},options);newOptions.depth++;newOptions.styleBaseUrl=styleBaseUrl;if(!this.styles[styleUrl]&&!OpenLayers.String.startsWith(styleUrl,"#")&&newOptions.depth<=this.maxDepth&&!this.fetched[styleBaseUrl]){var data=this.fetchLink(styleBaseUrl);if(data){this.parseData(data,newOptions);}}
61289 var style=OpenLayers.Util.extend({},this.styles[styleUrl]);return style;},parseGeometry:{point:function(node){var nodeList=this.getElementsByTagNameNS(node,this.internalns,"coordinates");var coords=[];if(nodeList.length>0){var coordString=nodeList[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.removeSpace,"");coords=coordString.split(",");}
61290 var point=null;if(coords.length>1){if(coords.length==2){coords[2]=null;}
61291 point=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{throw"Bad coordinate string: "+coordString;}
61292 return point;},linestring:function(node,ring){var nodeList=this.getElementsByTagNameNS(node,this.internalns,"coordinates");var line=null;if(nodeList.length>0){var coordString=this.getChildValue(nodeList[0]);coordString=coordString.replace(this.regExes.trimSpace,"");coordString=coordString.replace(this.regExes.trimComma,",");var pointList=coordString.split(this.regExes.splitSpace);var numPoints=pointList.length;var points=new Array(numPoints);var coords,numCoords;for(var i=0;i<numPoints;++i){coords=pointList[i].split(",");numCoords=coords.length;if(numCoords>1){if(coords.length==2){coords[2]=null;}
61293 points[i]=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{throw"Bad LineString point coordinates: "+
61294 pointList[i];}}
61295 if(numPoints){if(ring){line=new OpenLayers.Geometry.LinearRing(points);}else{line=new OpenLayers.Geometry.LineString(points);}}else{throw"Bad LineString coordinates: "+coordString;}}
61296 return line;},polygon:function(node){var nodeList=this.getElementsByTagNameNS(node,this.internalns,"LinearRing");var numRings=nodeList.length;var components=new Array(numRings);if(numRings>0){var ring;for(var i=0,len=nodeList.length;i<len;++i){ring=this.parseGeometry.linestring.apply(this,[nodeList[i],true]);if(ring){components[i]=ring;}else{throw"Bad LinearRing geometry: "+i;}}}
61297 return new OpenLayers.Geometry.Polygon(components);},multigeometry:function(node){var child,parser;var parts=[];var children=node.childNodes;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){var type=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;var parser=this.parseGeometry[type.toLowerCase()];if(parser){parts.push(parser.apply(this,[child]));}}}
61298 return new OpenLayers.Geometry.Collection(parts);}},parseAttributes:function(node){var attributes={};var edNodes=node.getElementsByTagName("ExtendedData");if(edNodes.length){attributes=this.parseExtendedData(edNodes[0]);}
61299 var child,grandchildren,grandchild;var children=node.childNodes;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){grandchildren=child.childNodes;if(grandchildren.length>=1&&grandchildren.length<=3){var grandchild;switch(grandchildren.length){case 1:grandchild=grandchildren[0];break;case 2:var c1=grandchildren[0];var c2=grandchildren[1];grandchild=(c1.nodeType==3||c1.nodeType==4)?c1:c2;break;case 3:default:grandchild=grandchildren[1];break;}
61300 if(grandchild.nodeType==3||grandchild.nodeType==4){var name=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;var value=OpenLayers.Util.getXmlNodeValue(grandchild);if(value){value=value.replace(this.regExes.trimSpace,"");attributes[name]=value;}}}}}
61301 return attributes;},parseExtendedData:function(node){var attributes={};var i,len,data,key;var dataNodes=node.getElementsByTagName("Data");for(i=0,len=dataNodes.length;i<len;i++){data=dataNodes[i];key=data.getAttribute("name");var ed={};var valueNode=data.getElementsByTagName("value");if(valueNode.length){ed['value']=this.getChildValue(valueNode[0]);}
61302 var nameNode=data.getElementsByTagName("displayName");if(nameNode.length){ed['displayName']=this.getChildValue(nameNode[0]);}
61303 attributes[key]=ed;}
61304 var simpleDataNodes=node.getElementsByTagName("SimpleData");for(i=0,len=simpleDataNodes.length;i<len;i++){var ed={};data=simpleDataNodes[i];key=data.getAttribute("name");ed['value']=this.getChildValue(data);ed['displayName']=key;attributes[key]=ed;}
61305 return attributes;},parseProperty:function(xmlNode,namespace,tagName){var value;var nodeList=this.getElementsByTagNameNS(xmlNode,namespace,tagName);try{value=OpenLayers.Util.getXmlNodeValue(nodeList[0]);}catch(e){value=null;}
61306 return value;},write:function(features){if(!(features instanceof Array)){features=[features];}
61307 var kml=this.createElementNS(this.kmlns,"kml");var folder=this.createFolderXML();for(var i=0,len=features.length;i<len;++i){folder.appendChild(this.createPlacemarkXML(features[i]));}
61308 kml.appendChild(folder);return OpenLayers.Format.XML.prototype.write.apply(this,[kml]);},createFolderXML:function(){var folder=this.createElementNS(this.kmlns,"Folder");if(this.foldersName){var folderName=this.createElementNS(this.kmlns,"name");var folderNameText=this.createTextNode(this.foldersName);folderName.appendChild(folderNameText);folder.appendChild(folderName);}
61309 if(this.foldersDesc){var folderDesc=this.createElementNS(this.kmlns,"description");var folderDescText=this.createTextNode(this.foldersDesc);folderDesc.appendChild(folderDescText);folder.appendChild(folderDesc);}
61310 return folder;},createPlacemarkXML:function(feature){var placemarkName=this.createElementNS(this.kmlns,"name");var name=feature.style&&feature.style.label?feature.style.label:feature.attributes.name||feature.id;placemarkName.appendChild(this.createTextNode(name));var placemarkDesc=this.createElementNS(this.kmlns,"description");var desc=feature.attributes.description||this.placemarksDesc;placemarkDesc.appendChild(this.createTextNode(desc));var placemarkNode=this.createElementNS(this.kmlns,"Placemark");if(feature.fid!=null){placemarkNode.setAttribute("id",feature.fid);}
61311 placemarkNode.appendChild(placemarkName);placemarkNode.appendChild(placemarkDesc);var geometryNode=this.buildGeometryNode(feature.geometry);placemarkNode.appendChild(geometryNode);return placemarkNode;},buildGeometryNode:function(geometry){if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
61312 var className=geometry.CLASS_NAME;var type=className.substring(className.lastIndexOf(".")+1);var builder=this.buildGeometry[type.toLowerCase()];var node=null;if(builder){node=builder.apply(this,[geometry]);}
61313 return node;},buildGeometry:{point:function(geometry){var kml=this.createElementNS(this.kmlns,"Point");kml.appendChild(this.buildCoordinatesNode(geometry));return kml;},multipoint:function(geometry){return this.buildGeometry.collection.apply(this,[geometry]);},linestring:function(geometry){var kml=this.createElementNS(this.kmlns,"LineString");kml.appendChild(this.buildCoordinatesNode(geometry));return kml;},multilinestring:function(geometry){return this.buildGeometry.collection.apply(this,[geometry]);},linearring:function(geometry){var kml=this.createElementNS(this.kmlns,"LinearRing");kml.appendChild(this.buildCoordinatesNode(geometry));return kml;},polygon:function(geometry){var kml=this.createElementNS(this.kmlns,"Polygon");var rings=geometry.components;var ringMember,ringGeom,type;for(var i=0,len=rings.length;i<len;++i){type=(i==0)?"outerBoundaryIs":"innerBoundaryIs";ringMember=this.createElementNS(this.kmlns,type);ringGeom=this.buildGeometry.linearring.apply(this,[rings[i]]);ringMember.appendChild(ringGeom);kml.appendChild(ringMember);}
61314 return kml;},multipolygon:function(geometry){return this.buildGeometry.collection.apply(this,[geometry]);},collection:function(geometry){var kml=this.createElementNS(this.kmlns,"MultiGeometry");var child;for(var i=0,len=geometry.components.length;i<len;++i){child=this.buildGeometryNode.apply(this,[geometry.components[i]]);if(child){kml.appendChild(child);}}
61315 return kml;}},buildCoordinatesNode:function(geometry){var coordinatesNode=this.createElementNS(this.kmlns,"coordinates");var path;var points=geometry.components;if(points){var point;var numPoints=points.length;var parts=new Array(numPoints);for(var i=0;i<numPoints;++i){point=points[i];parts[i]=point.x+","+point.y;}
61316 path=parts.join(" ");}else{path=geometry.x+","+geometry.y;}
61317 var txtNode=this.createTextNode(path);coordinatesNode.appendChild(txtNode);return coordinatesNode;},CLASS_NAME:"OpenLayers.Format.KML"});OpenLayers.Format.OSM=OpenLayers.Class(OpenLayers.Format.XML,{checkTags:false,interestingTagsExclude:null,areaTags:null,initialize:function(options){var layer_defaults={'interestingTagsExclude':['source','source_ref','source:ref','history','attribution','created_by'],'areaTags':['area','building','leisure','tourism','ruins','historic','landuse','military','natural','sport']};layer_defaults=OpenLayers.Util.extend(layer_defaults,options);var interesting={};for(var i=0;i<layer_defaults.interestingTagsExclude.length;i++){interesting[layer_defaults.interestingTagsExclude[i]]=true;}
61318 layer_defaults.interestingTagsExclude=interesting;var area={};for(var i=0;i<layer_defaults.areaTags.length;i++){area[layer_defaults.areaTags[i]]=true;}
61319 layer_defaults.areaTags=area;this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[layer_defaults]);},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
61320 var nodes=this.getNodes(doc);var ways=this.getWays(doc);var feat_list=new Array(ways.length);for(var i=0;i<ways.length;i++){var point_list=new Array(ways[i].nodes.length);var poly=this.isWayArea(ways[i])?1:0;for(var j=0;j<ways[i].nodes.length;j++){var node=nodes[ways[i].nodes[j]];var point=new OpenLayers.Geometry.Point(node.lon,node.lat);point.osm_id=parseInt(ways[i].nodes[j]);point_list[j]=point;node.used=true;}
61321 var geometry=null;if(poly){geometry=new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(point_list));}else{geometry=new OpenLayers.Geometry.LineString(point_list);}
61322 if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}
61323 var feat=new OpenLayers.Feature.Vector(geometry,ways[i].tags);feat.osm_id=parseInt(ways[i].id);feat.fid="way."+feat.osm_id;feat_list[i]=feat;}
61324 for(var node_id in nodes){var node=nodes[node_id];if(!node.used||this.checkTags){var tags=null;if(this.checkTags){var result=this.getTags(node.node,true);if(node.used&&!result[1]){continue;}
61325 tags=result[0];}else{tags=this.getTags(node.node);}
61326 var feat=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(node['lon'],node['lat']),tags);if(this.internalProjection&&this.externalProjection){feat.geometry.transform(this.externalProjection,this.internalProjection);}
61327 feat.osm_id=parseInt(node_id);feat.fid="node."+feat.osm_id;feat_list.push(feat);}
61328 node.node=null;}
61329 return feat_list;},getNodes:function(doc){var node_list=doc.getElementsByTagName("node");var nodes={};for(var i=0;i<node_list.length;i++){var node=node_list[i];var id=node.getAttribute("id");nodes[id]={'lat':node.getAttribute("lat"),'lon':node.getAttribute("lon"),'node':node};}
61330 return nodes;},getWays:function(doc){var way_list=doc.getElementsByTagName("way");var return_ways=[];for(var i=0;i<way_list.length;i++){var way=way_list[i];var way_object={id:way.getAttribute("id")};way_object.tags=this.getTags(way);var node_list=way.getElementsByTagName("nd");way_object.nodes=new Array(node_list.length);for(var j=0;j<node_list.length;j++){way_object.nodes[j]=node_list[j].getAttribute("ref");}
61331 return_ways.push(way_object);}
61332 return return_ways;},getTags:function(dom_node,interesting_tags){var tag_list=dom_node.getElementsByTagName("tag");var tags={};var interesting=false;for(var j=0;j<tag_list.length;j++){var key=tag_list[j].getAttribute("k");tags[key]=tag_list[j].getAttribute("v");if(interesting_tags){if(!this.interestingTagsExclude[key]){interesting=true;}}}
61333 return interesting_tags?[tags,interesting]:tags;},isWayArea:function(way){var poly_shaped=false;var poly_tags=false;if(way.nodes[0]==way.nodes[way.nodes.length-1]){poly_shaped=true;}
61334 if(this.checkTags){for(var key in way.tags){if(this.areaTags[key]){poly_tags=true;break;}}}
61335 return poly_shaped&&(this.checkTags?poly_tags:true);},write:function(features){if(!(features instanceof Array)){features=[features];}
61336 this.osm_id=1;this.created_nodes={};var root_node=this.createElementNS(null,"osm");root_node.setAttribute("version","0.5");root_node.setAttribute("generator","OpenLayers "+OpenLayers.VERSION_NUMBER);for(var i=features.length-1;i>=0;i--){var nodes=this.createFeatureNodes(features[i]);for(var j=0;j<nodes.length;j++){root_node.appendChild(nodes[j]);}}
61337 return OpenLayers.Format.XML.prototype.write.apply(this,[root_node]);},createFeatureNodes:function(feature){var nodes=[];var className=feature.geometry.CLASS_NAME;var type=className.substring(className.lastIndexOf(".")+1);type=type.toLowerCase();var builder=this.createXML[type];if(builder){nodes=builder.apply(this,[feature]);}
61338 return nodes;},createXML:{'point':function(point){var id=null;var geometry=point.geometry?point.geometry:point;var already_exists=false;if(point.osm_id){id=point.osm_id;if(this.created_nodes[id]){already_exists=true;}}else{id=-this.osm_id;this.osm_id++;}
61339 if(already_exists){node=this.created_nodes[id];}else{var node=this.createElementNS(null,"node");}
61340 this.created_nodes[id]=node;node.setAttribute("id",id);node.setAttribute("lon",geometry.x);node.setAttribute("lat",geometry.y);if(point.attributes){this.serializeTags(point,node);}
61341 this.setState(point,node);return already_exists?[]:[node];},linestring:function(feature){var nodes=[];var geometry=feature.geometry;if(feature.osm_id){id=feature.osm_id;}else{id=-this.osm_id;this.osm_id++;}
61342 var way=this.createElementNS(null,"way");way.setAttribute("id",id);for(var i=0;i<geometry.components.length;i++){var node=this.createXML['point'].apply(this,[geometry.components[i]]);if(node.length){node=node[0];var node_ref=node.getAttribute("id");nodes.push(node);}else{node_ref=geometry.components[i].osm_id;node=this.created_nodes[node_ref];}
61343 this.setState(feature,node);var nd_dom=this.createElementNS(null,"nd");nd_dom.setAttribute("ref",node_ref);way.appendChild(nd_dom);}
61344 this.serializeTags(feature,way);nodes.push(way);return nodes;},polygon:function(feature){var attrs=OpenLayers.Util.extend({'area':'yes'},feature.attributes);var feat=new OpenLayers.Feature.Vector(feature.geometry.components[0],attrs);feat.osm_id=feature.osm_id;return this.createXML['linestring'].apply(this,[feat]);}},serializeTags:function(feature,node){for(var key in feature.attributes){var tag=this.createElementNS(null,"tag");tag.setAttribute("k",key);tag.setAttribute("v",feature.attributes[key]);node.appendChild(tag);}},setState:function(feature,node){if(feature.state){var state=null;switch(feature.state){case OpenLayers.State.UPDATE:state="modify";case OpenLayers.State.DELETE:state="delete";}
61345 if(state){node.setAttribute("action",state);}}},CLASS_NAME:"OpenLayers.Format.OSM"});OpenLayers.Geometry.MultiPolygon=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.Polygon"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Geometry.MultiPolygon"});OpenLayers.Handler.Polygon=OpenLayers.Class(OpenLayers.Handler.Path,{polygon:null,initialize:function(control,callbacks,options){OpenLayers.Handler.Path.prototype.initialize.apply(this,arguments);},createFeature:function(pixel){var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.line=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LinearRing([this.point.geometry]));this.polygon=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon([this.line.geometry]));this.callback("create",[this.point.geometry,this.getSketch()]);this.point.geometry.clearBounds();this.layer.addFeatures([this.polygon,this.point],{silent:true});},destroyFeature:function(){OpenLayers.Handler.Path.prototype.destroyFeature.apply(this);this.polygon=null;},drawFeature:function(){this.layer.drawFeature(this.polygon,this.style);this.layer.drawFeature(this.point,this.style);},getSketch:function(){return this.polygon;},getGeometry:function(){var geometry=this.polygon&&this.polygon.geometry;if(geometry&&this.multi){geometry=new OpenLayers.Geometry.MultiPolygon([geometry]);}
61346 return geometry;},dblclick:function(evt){if(!this.freehandMode(evt)){var index=this.line.geometry.components.length-2;this.line.geometry.removeComponent(this.line.geometry.components[index]);this.removePoint();this.finalize();}
61347 return false;},CLASS_NAME:"OpenLayers.Handler.Polygon"});OpenLayers.Control.EditingToolbar=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(layer,options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.Navigation()]);var controls=[new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Point,{'displayClass':'olControlDrawFeaturePoint'}),new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Path,{'displayClass':'olControlDrawFeaturePath'}),new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Polygon,{'displayClass':'olControlDrawFeaturePolygon'})];this.addControls(controls);},draw:function(){var div=OpenLayers.Control.Panel.prototype.draw.apply(this,arguments);this.activateControl(this.controls[0]);return div;},CLASS_NAME:"OpenLayers.Control.EditingToolbar"});OpenLayers.Control.SLDSelect=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["selected"],clearOnDeactivate:false,layers:null,callbacks:null,selectionSymbolizer:{'Polygon':{fillColor:'#FF0000',stroke:false},'Line':{strokeColor:'#FF0000',strokeWidth:2},'Point':{graphicName:'square',fillColor:'#FF0000',pointRadius:5}},layerOptions:null,handlerOptions:null,sketchStyle:null,wfsCache:{},layerCache:{},initialize:function(handler,options){this.EVENT_TYPES=OpenLayers.Control.SLDSelect.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.callbacks=OpenLayers.Util.extend({done:this.select,click:this.select},this.callbacks);this.handlerOptions=this.handlerOptions||{};this.layerOptions=OpenLayers.Util.applyDefaults(this.layerOptions,{displayInLayerSwitcher:false});if(this.sketchStyle){this.handlerOptions.layerOptions=OpenLayers.Util.applyDefaults(this.handlerOptions.layerOptions,{styleMap:new OpenLayers.StyleMap({"default":this.sketchStyle})});}
61348 this.handler=new handler(this,this.callbacks,this.handlerOptions);},destroy:function(){for(var key in this.layerCache){delete this.layerCache[key];}
61349 for(var key in this.wfsCache){delete this.wfsCache[key];}
61350 OpenLayers.Control.prototype.destroy.apply(this,arguments);},coupleLayerVisiblity:function(evt){this.setVisibility(evt.object.getVisibility());},createSelectionLayer:function(source){var selectionLayer;if(!this.layerCache[source.id]){selectionLayer=new OpenLayers.Layer.WMS.Post(source.name,source.url,source.params,OpenLayers.Util.applyDefaults(this.layerOptions,source.getOptions()));this.layerCache[source.id]=selectionLayer;if(this.layerOptions.displayInLayerSwitcher===false){source.events.on({"visibilitychanged":this.coupleLayerVisiblity,scope:selectionLayer});}
61351 this.map.addLayer(selectionLayer);}else{selectionLayer=this.layerCache[source.id];}
61352 return selectionLayer;},createSLD:function(layer,filters,geometryAttributes){var sld={version:"1.0.0",namedLayers:{}};var layerNames=[layer.params.LAYERS].join(",").split(",");for(var i=0,len=layerNames.length;i<len;i++){var name=layerNames[i];sld.namedLayers[name]={name:name,userStyles:[]};var symbolizer=this.selectionSymbolizer;var geometryAttribute=geometryAttributes[i];if(geometryAttribute.type.indexOf('Polygon')>=0){symbolizer={Polygon:this.selectionSymbolizer['Polygon']};}else if(geometryAttribute.type.indexOf('LineString')>=0){symbolizer={Line:this.selectionSymbolizer['Line']};}else if(geometryAttribute.type.indexOf('Point')>=0){symbolizer={Point:this.selectionSymbolizer['Point']};}
61353 var filter=filters[i];sld.namedLayers[name].userStyles.push({name:'default',rules:[new OpenLayers.Rule({symbolizer:symbolizer,filter:filter,maxScaleDenominator:layer.options.minScale})]});}
61354 return new OpenLayers.Format.SLD().write(sld);},parseDescribeLayer:function(request){var format=new OpenLayers.Format.WMSDescribeLayer();var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
61355 var describeLayer=format.read(doc);var typeNames=[];var url=null;for(var i=0,len=describeLayer.length;i<len;i++){if(describeLayer[i].owsType=="WFS"){typeNames.push(describeLayer[i].typeName);url=describeLayer[i].owsURL;}}
61356 var options={url:url,params:{SERVICE:"WFS",TYPENAME:typeNames.toString(),REQUEST:"DescribeFeatureType",VERSION:"1.0.0"},callback:function(request){var format=new OpenLayers.Format.WFSDescribeFeatureType();var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
61357 var describeFeatureType=format.read(doc);this.control.wfsCache[this.layer.id]=describeFeatureType;this.control._queue&&this.control.applySelection();},scope:this};OpenLayers.Request.GET(options);},getGeometryAttributes:function(layer){var result=[];var cache=this.wfsCache[layer.id];for(var i=0,len=cache.featureTypes.length;i<len;i++){var typeName=cache.featureTypes[i];var properties=typeName.properties;for(var j=0,lenj=properties.length;j<lenj;j++){var property=properties[j];var type=property.type;if((type.indexOf('LineString')>=0)||(type.indexOf('GeometryAssociationType')>=0)||(type.indexOf('GeometryPropertyType')>=0)||(type.indexOf('Point')>=0)||(type.indexOf('Polygon')>=0)){result.push(property);}}}
61358 return result;},activate:function(){var activated=OpenLayers.Control.prototype.activate.call(this);if(activated){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer&&!this.wfsCache[layer.id]){var options={url:layer.url,params:{SERVICE:"WMS",VERSION:layer.params.VERSION,LAYERS:layer.params.LAYERS,REQUEST:"DescribeLayer"},callback:this.parseDescribeLayer,scope:{layer:layer,control:this}};OpenLayers.Request.GET(options);}}}
61359 return activated;},deactivate:function(){var deactivated=OpenLayers.Control.prototype.deactivate.call(this);if(deactivated){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer&&this.clearOnDeactivate===true){var layerCache=this.layerCache;var selectionLayer=layerCache[layer.id];if(selectionLayer){layer.events.un({"visibilitychanged":this.coupleLayerVisiblity,scope:selectionLayer});selectionLayer.destroy();delete layerCache[layer.id];}}}}
61360 return deactivated;},setLayers:function(layers){if(this.active){this.deactivate();this.layers=layers;this.activate();}else{this.layers=layers;}},createFilter:function(geometryAttribute,geometry){var filter=null;if(this.handler instanceof OpenLayers.Handler.RegularPolygon){if(this.handler.irregular===true){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.BBOX,property:geometryAttribute.name,value:geometry.getBounds()});}else{filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}}else if(this.handler instanceof OpenLayers.Handler.Polygon){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}else if(this.handler instanceof OpenLayers.Handler.Path){if(geometryAttribute.type.indexOf('Point')>=0){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.DWITHIN,property:geometryAttribute.name,distance:this.map.getExtent().getWidth()*0.01,distanceUnits:this.map.getUnits(),value:geometry});}else{filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}}else if(this.handler instanceof OpenLayers.Handler.Click){if(geometryAttribute.type.indexOf('Polygon')>=0){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}else{filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.DWITHIN,property:geometryAttribute.name,distance:this.map.getExtent().getWidth()*0.01,distanceUnits:this.map.getUnits(),value:geometry});}}
61361 return filter;},select:function(geometry){this._queue=function(){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];var geometryAttributes=this.getGeometryAttributes(layer);var filters=[];for(var j=0,lenj=geometryAttributes.length;j<lenj;j++){var geometryAttribute=geometryAttributes[j];if(geometryAttribute!==null){if(!(geometry instanceof OpenLayers.Geometry)){var point=this.map.getLonLatFromPixel(geometry.xy);geometry=new OpenLayers.Geometry.Point(point.lon,point.lat);}
61362 var filter=this.createFilter(geometryAttribute,geometry);if(filter!==null){filters.push(filter);}}}
61363 var selectionLayer=this.createSelectionLayer(layer);var sld=this.createSLD(layer,filters,geometryAttributes);this.events.triggerEvent("selected",{layer:layer,filters:filters});selectionLayer.mergeNewParams({SLD_BODY:sld});delete this._queue;}};this.applySelection();},applySelection:function(){var canApply=true;for(var i=0,len=this.layers.length;i<len;i++){if(!this.wfsCache[this.layers[i].id]){canApply=false;break;}}
61364 canApply&&this._queue.call(this);},CLASS_NAME:"OpenLayers.Control.SLDSelect"});OpenLayers.Format.ArcXML=OpenLayers.Class(OpenLayers.Format.XML,{fontStyleKeys:['antialiasing','blockout','font','fontcolor','fontsize','fontstyle','glowing','interval','outline','printmode','shadow','transparency'],request:null,response:null,initialize:function(options){this.request=new OpenLayers.Format.ArcXML.Request();this.response=new OpenLayers.Format.ArcXML.Response();if(options){if(options.requesttype=="feature"){this.request.get_image=null;var qry=this.request.get_feature.query;this.addCoordSys(qry.featurecoordsys,options.featureCoordSys);this.addCoordSys(qry.filtercoordsys,options.filterCoordSys);if(options.polygon){qry.isspatial=true;qry.spatialfilter.polygon=options.polygon;}else if(options.envelope){qry.isspatial=true;qry.spatialfilter.envelope={minx:0,miny:0,maxx:0,maxy:0};this.parseEnvelope(qry.spatialfilter.envelope,options.envelope);}}else if(options.requesttype=="image"){this.request.get_feature=null;var props=this.request.get_image.properties;this.parseEnvelope(props.envelope,options.envelope);this.addLayers(props.layerlist,options.layers);this.addImageSize(props.imagesize,options.tileSize);this.addCoordSys(props.featurecoordsys,options.featureCoordSys);this.addCoordSys(props.filtercoordsys,options.filterCoordSys);}else{this.request=null;}}
61365 OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},parseEnvelope:function(env,arr){if(arr&&arr.length==4){env.minx=arr[0];env.miny=arr[1];env.maxx=arr[2];env.maxy=arr[3];}},addLayers:function(ll,lyrs){for(var lind=0,len=lyrs.length;lind<len;lind++){ll.push(lyrs[lind]);}},addImageSize:function(imsize,olsize){if(olsize!==null){imsize.width=olsize.w;imsize.height=olsize.h;imsize.printwidth=olsize.w;imsize.printheight=olsize.h;}},addCoordSys:function(featOrFilt,fsys){if(typeof fsys=="string"){featOrFilt.id=parseInt(fsys);featOrFilt.string=fsys;}
61366 else if(typeof fsys=="object"&&fsys.proj!==null){featOrFilt.id=fsys.proj.srsProjNumber;featOrFilt.string=fsys.proj.srsCode;}else{featOrFilt=fsys;}},iserror:function(data){var ret=null;if(!data){ret=(this.response.error!=='');}else{data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);var errorNodes=data.documentElement.getElementsByTagName("ERROR");ret=(errorNodes!==null&&errorNodes.length>0);}
61367 return ret;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61368 var arcNode=null;if(data&&data.documentElement){if(data.documentElement.nodeName=="ARCXML"){arcNode=data.documentElement;}else{arcNode=data.documentElement.getElementsByTagName("ARCXML")[0];}}
61369 if(!arcNode||arcNode.firstChild.nodeName==='parsererror'){var error,source;try{error=data.firstChild.nodeValue;source=data.firstChild.childNodes[1].firstChild.nodeValue;}catch(err){}
61370 throw{message:"Error parsing the ArcXML request",error:error,source:source};}
61371 var response=this.parseResponse(arcNode);return response;},write:function(request){if(!request){request=this.request;}
61372 var root=this.createElementNS("","ARCXML");root.setAttribute("version","1.1");var reqElem=this.createElementNS("","REQUEST");if(request.get_image!=null){var getElem=this.createElementNS("","GET_IMAGE");reqElem.appendChild(getElem);var propElem=this.createElementNS("","PROPERTIES");getElem.appendChild(propElem);var props=request.get_image.properties;if(props.featurecoordsys!=null){var feat=this.createElementNS("","FEATURECOORDSYS");propElem.appendChild(feat);if(props.featurecoordsys.id===0){feat.setAttribute("string",props.featurecoordsys['string']);}
61373 else{feat.setAttribute("id",props.featurecoordsys.id);}}
61374 if(props.filtercoordsys!=null){var filt=this.createElementNS("","FILTERCOORDSYS");propElem.appendChild(filt);if(props.filtercoordsys.id===0){filt.setAttribute("string",props.filtercoordsys.string);}
61375 else{filt.setAttribute("id",props.filtercoordsys.id);}}
61376 if(props.envelope!=null){var env=this.createElementNS("","ENVELOPE");propElem.appendChild(env);env.setAttribute("minx",props.envelope.minx);env.setAttribute("miny",props.envelope.miny);env.setAttribute("maxx",props.envelope.maxx);env.setAttribute("maxy",props.envelope.maxy);}
61377 var imagesz=this.createElementNS("","IMAGESIZE");propElem.appendChild(imagesz);imagesz.setAttribute("height",props.imagesize.height);imagesz.setAttribute("width",props.imagesize.width);if(props.imagesize.height!=props.imagesize.printheight||props.imagesize.width!=props.imagesize.printwidth){imagesz.setAttribute("printheight",props.imagesize.printheight);imagesz.setArrtibute("printwidth",props.imagesize.printwidth);}
61378 if(props.background!=null){var backgrnd=this.createElementNS("","BACKGROUND");propElem.appendChild(backgrnd);backgrnd.setAttribute("color",props.background.color.r+","+
61379 props.background.color.g+","+
61380 props.background.color.b);if(props.background.transcolor!==null){backgrnd.setAttribute("transcolor",props.background.transcolor.r+","+
61381 props.background.transcolor.g+","+
61382 props.background.transcolor.b);}}
61383 if(props.layerlist!=null&&props.layerlist.length>0){var layerlst=this.createElementNS("","LAYERLIST");propElem.appendChild(layerlst);for(var ld=0;ld<props.layerlist.length;ld++){var ldef=this.createElementNS("","LAYERDEF");layerlst.appendChild(ldef);ldef.setAttribute("id",props.layerlist[ld].id);ldef.setAttribute("visible",props.layerlist[ld].visible);if(typeof props.layerlist[ld].query=="object"){var query=props.layerlist[ld].query;if(query.where.length<0){continue;}
61384 var queryElem=null;if(typeof query.spatialfilter=="boolean"&&query.spatialfilter){queryElem=this.createElementNS("","SPATIALQUERY");}
61385 else{queryElem=this.createElementNS("","QUERY");}
61386 queryElem.setAttribute("where",query.where);if(typeof query.accuracy=="number"&&query.accuracy>0){queryElem.setAttribute("accuracy",query.accuracy);}
61387 if(typeof query.featurelimit=="number"&&query.featurelimit<2000){queryElem.setAttribute("featurelimit",query.featurelimit);}
61388 if(typeof query.subfields=="string"&&query.subfields!="#ALL#"){queryElem.setAttribute("subfields",query.subfields);}
61389 if(typeof query.joinexpression=="string"&&query.joinexpression.length>0){queryElem.setAttribute("joinexpression",query.joinexpression);}
61390 if(typeof query.jointables=="string"&&query.jointables.length>0){queryElem.setAttribute("jointables",query.jointables);}
61391 ldef.appendChild(queryElem);}
61392 if(typeof props.layerlist[ld].renderer=="object"){this.addRenderer(ldef,props.layerlist[ld].renderer);}}}}else if(request.get_feature!=null){var getElem=this.createElementNS("","GET_FEATURES");getElem.setAttribute("outputmode","newxml");getElem.setAttribute("checkesc","true");if(request.get_feature.geometry){getElem.setAttribute("geometry",request.get_feature.geometry);}
61393 else{getElem.setAttribute("geometry","false");}
61394 if(request.get_feature.compact){getElem.setAttribute("compact",request.get_feature.compact);}
61395 if(request.get_feature.featurelimit=="number"){getElem.setAttribute("featurelimit",request.get_feature.featurelimit);}
61396 getElem.setAttribute("globalenvelope","true");reqElem.appendChild(getElem);if(request.get_feature.layer!=null&&request.get_feature.layer.length>0){var lyrElem=this.createElementNS("","LAYER");lyrElem.setAttribute("id",request.get_feature.layer);getElem.appendChild(lyrElem);}
61397 var fquery=request.get_feature.query;if(fquery!=null){var qElem=null;if(fquery.isspatial){qElem=this.createElementNS("","SPATIALQUERY");}else{qElem=this.createElementNS("","QUERY");}
61398 getElem.appendChild(qElem);if(typeof fquery.accuracy=="number"){qElem.setAttribute("accuracy",fquery.accuracy);}
61399 if(fquery.featurecoordsys!=null){var fcsElem1=this.createElementNS("","FEATURECOORDSYS");if(fquery.featurecoordsys.id==0){fcsElem1.setAttribute("string",fquery.featurecoordsys.string);}else{fcsElem1.setAttribute("id",fquery.featurecoordsys.id);}
61400 qElem.appendChild(fcsElem1);}
61401 if(fquery.filtercoordsys!=null){var fcsElem2=this.createElementNS("","FILTERCOORDSYS");if(fquery.filtercoordsys.id===0){fcsElem2.setAttribute("string",fquery.filtercoordsys.string);}else{fcsElem2.setAttribute("id",fquery.filtercoordsys.id);}
61402 qElem.appendChild(fcsElem2);}
61403 if(fquery.buffer>0){var bufElem=this.createElementNS("","BUFFER");bufElem.setAttribute("distance",fquery.buffer);qElem.appendChild(bufElem);}
61404 if(fquery.isspatial){var spfElem=this.createElementNS("","SPATIALFILTER");spfElem.setAttribute("relation",fquery.spatialfilter.relation);qElem.appendChild(spfElem);if(fquery.spatialfilter.envelope){var envElem=this.createElementNS("","ENVELOPE");envElem.setAttribute("minx",fquery.spatialfilter.envelope.minx);envElem.setAttribute("miny",fquery.spatialfilter.envelope.miny);envElem.setAttribute("maxx",fquery.spatialfilter.envelope.maxx);envElem.setAttribute("maxy",fquery.spatialfilter.envelope.maxy);spfElem.appendChild(envElem);}else if(typeof fquery.spatialfilter.polygon=="object"){spfElem.appendChild(this.writePolygonGeometry(fquery.spatialfilter.polygon));}}
61405 if(fquery.where!=null&&fquery.where.length>0){qElem.setAttribute("where",fquery.where);}}}
61406 root.appendChild(reqElem);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},addGroupRenderer:function(ldef,toprenderer){var topRelem=this.createElementNS("","GROUPRENDERER");ldef.appendChild(topRelem);for(var rind=0;rind<toprenderer.length;rind++){var renderer=toprenderer[rind];this.addRenderer(topRelem,renderer);}},addRenderer:function(topRelem,renderer){if(renderer instanceof Array){this.addGroupRenderer(topRelem,renderer);}else{var renderElem=this.createElementNS("",renderer.type.toUpperCase()+"RENDERER");topRelem.appendChild(renderElem);if(renderElem.tagName=="VALUEMAPRENDERER"){this.addValueMapRenderer(renderElem,renderer);}else if(renderElem.tagName=="VALUEMAPLABELRENDERER"){this.addValueMapLabelRenderer(renderElem,renderer);}else if(renderElem.tagName=="SIMPLELABELRENDERER"){this.addSimpleLabelRenderer(renderElem,renderer);}else if(renderElem.tagName=="SCALEDEPENDENTRENDERER"){this.addScaleDependentRenderer(renderElem,renderer);}}},addScaleDependentRenderer:function(renderElem,renderer){if(typeof renderer.lower=="string"||typeof renderer.lower=="number"){renderElem.setAttribute("lower",renderer.lower);}
61407 if(typeof renderer.upper=="string"||typeof renderer.upper=="number"){renderElem.setAttribute("upper",renderer.upper);}
61408 this.addRenderer(renderElem,renderer.renderer);},addValueMapLabelRenderer:function(renderElem,renderer){renderElem.setAttribute("lookupfield",renderer.lookupfield);renderElem.setAttribute("labelfield",renderer.labelfield);if(typeof renderer.exacts=="object"){for(var ext=0,extlen=renderer.exacts.length;ext<extlen;ext++){var exact=renderer.exacts[ext];var eelem=this.createElementNS("","EXACT");if(typeof exact.value=="string"){eelem.setAttribute("value",exact.value);}
61409 if(typeof exact.label=="string"){eelem.setAttribute("label",exact.label);}
61410 if(typeof exact.method=="string"){eelem.setAttribute("method",exact.method);}
61411 renderElem.appendChild(eelem);if(typeof exact.symbol=="object"){var selem=null;if(exact.symbol.type=="text"){selem=this.createElementNS("","TEXTSYMBOL");}
61412 if(selem!=null){var keys=this.fontStyleKeys;for(var i=0,len=keys.length;i<len;i++){var key=keys[i];if(exact.symbol[key]){selem.setAttribute(key,exact.symbol[key]);}}
61413 eelem.appendChild(selem);}}}}},addValueMapRenderer:function(renderElem,renderer){renderElem.setAttribute("lookupfield",renderer.lookupfield);if(typeof renderer.ranges=="object"){for(var rng=0,rnglen=renderer.ranges.length;rng<rnglen;rng++){var range=renderer.ranges[rng];var relem=this.createElementNS("","RANGE");relem.setAttribute("lower",range.lower);relem.setAttribute("upper",range.upper);renderElem.appendChild(relem);if(typeof range.symbol=="object"){var selem=null;if(range.symbol.type=="simplepolygon"){selem=this.createElementNS("","SIMPLEPOLYGONSYMBOL");}
61414 if(selem!=null){if(typeof range.symbol.boundarycolor=="string"){selem.setAttribute("boundarycolor",range.symbol.boundarycolor);}
61415 if(typeof range.symbol.fillcolor=="string"){selem.setAttribute("fillcolor",range.symbol.fillcolor);}
61416 if(typeof range.symbol.filltransparency=="number"){selem.setAttribute("filltransparency",range.symbol.filltransparency);}
61417 relem.appendChild(selem);}}}}else if(typeof renderer.exacts=="object"){for(var ext=0,extlen=renderer.exacts.length;ext<extlen;ext++){var exact=renderer.exacts[ext];var eelem=this.createElementNS("","EXACT");if(typeof exact.value=="string"){eelem.setAttribute("value",exact.value);}
61418 if(typeof exact.label=="string"){eelem.setAttribute("label",exact.label);}
61419 if(typeof exact.method=="string"){eelem.setAttribute("method",exact.method);}
61420 renderElem.appendChild(eelem);if(typeof exact.symbol=="object"){var selem=null;if(exact.symbol.type=="simplemarker"){selem=this.createElementNS("","SIMPLEMARKERSYMBOL");}
61421 if(selem!=null){if(typeof exact.symbol.antialiasing=="string"){selem.setAttribute("antialiasing",exact.symbol.antialiasing);}
61422 if(typeof exact.symbol.color=="string"){selem.setAttribute("color",exact.symbol.color);}
61423 if(typeof exact.symbol.outline=="string"){selem.setAttribute("outline",exact.symbol.outline);}
61424 if(typeof exact.symbol.overlap=="string"){selem.setAttribute("overlap",exact.symbol.overlap);}
61425 if(typeof exact.symbol.shadow=="string"){selem.setAttribute("shadow",exact.symbol.shadow);}
61426 if(typeof exact.symbol.transparency=="number"){selem.setAttribute("transparency",exact.symbol.transparency);}
61427 if(typeof exact.symbol.usecentroid=="string"){selem.setAttribute("usecentroid",exact.symbol.usecentroid);}
61428 if(typeof exact.symbol.width=="number"){selem.setAttribute("width",exact.symbol.width);}
61429 eelem.appendChild(selem);}}}}},addSimpleLabelRenderer:function(renderElem,renderer){renderElem.setAttribute("field",renderer.field);var keys=['featureweight','howmanylabels','labelbufferratio','labelpriorities','labelweight','linelabelposition','rotationalangles'];for(var i=0,len=keys.length;i<len;i++){var key=keys[i];if(renderer[key]){renderElem.setAttribute(key,renderer[key]);}}
61430 if(renderer.symbol.type=="text"){var symbol=renderer.symbol;var selem=this.createElementNS("","TEXTSYMBOL");renderElem.appendChild(selem);var keys=this.fontStyleKeys;for(var i=0,len=keys.length;i<len;i++){var key=keys[i];if(symbol[key]){selem.setAttribute(key,renderer[key]);}}}},writePolygonGeometry:function(polygon){if(!(polygon instanceof OpenLayers.Geometry.Polygon)){throw{message:'Cannot write polygon geometry to ArcXML with an '+
61431 polygon.CLASS_NAME+' object.',geometry:polygon};}
61432 var polyElem=this.createElementNS("","POLYGON");for(var ln=0,lnlen=polygon.components.length;ln<lnlen;ln++){var ring=polygon.components[ln];var ringElem=this.createElementNS("","RING");for(var rn=0,rnlen=ring.components.length;rn<rnlen;rn++){var point=ring.components[rn];var pointElem=this.createElementNS("","POINT");pointElem.setAttribute("x",point.x);pointElem.setAttribute("y",point.y);ringElem.appendChild(pointElem);}
61433 polyElem.appendChild(ringElem);}
61434 return polyElem;},parseResponse:function(data){if(typeof data=="string"){var newData=new OpenLayers.Format.XML();data=newData.read(data);}
61435 var response=new OpenLayers.Format.ArcXML.Response();var errorNode=data.getElementsByTagName("ERROR");if(errorNode!=null&&errorNode.length>0){response.error=this.getChildValue(errorNode,"Unknown error.");}else{var responseNode=data.getElementsByTagName("RESPONSE");if(responseNode==null||responseNode.length==0){response.error="No RESPONSE tag found in ArcXML response.";return response;}
61436 var rtype=responseNode[0].firstChild.nodeName;if(rtype=="#text"){rtype=responseNode[0].firstChild.nextSibling.nodeName;}
61437 if(rtype=="IMAGE"){var envelopeNode=data.getElementsByTagName("ENVELOPE");var outputNode=data.getElementsByTagName("OUTPUT");if(envelopeNode==null||envelopeNode.length==0){response.error="No ENVELOPE tag found in ArcXML response.";}else if(outputNode==null||outputNode.length==0){response.error="No OUTPUT tag found in ArcXML response.";}else{var envAttr=this.parseAttributes(envelopeNode[0]);var outputAttr=this.parseAttributes(outputNode[0]);if(typeof outputAttr.type=="string"){response.image={envelope:envAttr,output:{type:outputAttr.type,data:this.getChildValue(outputNode[0])}};}else{response.image={envelope:envAttr,output:outputAttr};}}}else if(rtype=="FEATURES"){var features=responseNode[0].getElementsByTagName("FEATURES");var featureCount=features[0].getElementsByTagName("FEATURECOUNT");response.features.featurecount=featureCount[0].getAttribute("count");if(response.features.featurecount>0){var envelope=features[0].getElementsByTagName("ENVELOPE");response.features.envelope=this.parseAttributes(envelope[0],typeof(0));var featureList=features[0].getElementsByTagName("FEATURE");for(var fn=0;fn<featureList.length;fn++){var feature=new OpenLayers.Feature.Vector();var fields=featureList[fn].getElementsByTagName("FIELD");for(var fdn=0;fdn<fields.length;fdn++){var fieldName=fields[fdn].getAttribute("name");var fieldValue=fields[fdn].getAttribute("value");feature.attributes[fieldName]=fieldValue;}
61438 var geom=featureList[fn].getElementsByTagName("POLYGON");if(geom.length>0){var ring=geom[0].getElementsByTagName("RING");var polys=[];for(var rn=0;rn<ring.length;rn++){var linearRings=[];linearRings.push(this.parsePointGeometry(ring[rn]));var holes=ring[rn].getElementsByTagName("HOLE");for(var hn=0;hn<holes.length;hn++){linearRings.push(this.parsePointGeometry(holes[hn]));}
61439 holes=null;polys.push(new OpenLayers.Geometry.Polygon(linearRings));linearRings=null;}
61440 ring=null;if(polys.length==1){feature.geometry=polys[0];}else
61441 {feature.geometry=new OpenLayers.Geometry.MultiPolygon(polys);}}
61442 response.features.feature.push(feature);}}}else{response.error="Unidentified response type.";}}
61443 return response;},parseAttributes:function(node,type){var attributes={};for(var attr=0;attr<node.attributes.length;attr++){if(type=="number"){attributes[node.attributes[attr].nodeName]=parseFloat(node.attributes[attr].nodeValue);}else{attributes[node.attributes[attr].nodeName]=node.attributes[attr].nodeValue;}}
61444 return attributes;},parsePointGeometry:function(node){var ringPoints=[];var coords=node.getElementsByTagName("COORDS");if(coords.length>0){var coordArr=this.getChildValue(coords[0]);coordArr=coordArr.split(/;/);for(var cn=0;cn<coordArr.length;cn++){var coordItems=coordArr[cn].split(/ /);ringPoints.push(new OpenLayers.Geometry.Point(parseFloat(coordItems[0]),parseFloat(coordItems[1])));}
61445 coords=null;}else{var point=node.getElementsByTagName("POINT");if(point.length>0){for(var pn=0;pn<point.length;pn++){ringPoints.push(new OpenLayers.Geometry.Point(parseFloat(point[pn].getAttribute("x")),parseFloat(point[pn].getAttribute("y"))));}}
61446 point=null;}
61447 return new OpenLayers.Geometry.LinearRing(ringPoints);},CLASS_NAME:"OpenLayers.Format.ArcXML"});OpenLayers.Format.ArcXML.Request=OpenLayers.Class({initialize:function(params){var defaults={get_image:{properties:{background:null,draw:true,envelope:{minx:0,miny:0,maxx:0,maxy:0},featurecoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},filtercoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},imagesize:{height:0,width:0,dpi:96,printheight:0,printwidth:0,scalesymbols:false},layerlist:[],output:{baseurl:"",legendbaseurl:"",legendname:"",legendpath:"",legendurl:"",name:"",path:"",type:"jpg",url:""}}},get_feature:{layer:"",query:{isspatial:false,featurecoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},filtercoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},buffer:0,where:"",spatialfilter:{relation:"envelope_intersection",envelope:null}}},environment:{separators:{cs:" ",ts:";"}},layer:[],workspaces:[]};return OpenLayers.Util.extend(this,defaults);},CLASS_NAME:"OpenLayers.Format.ArcXML.Request"});OpenLayers.Format.ArcXML.Response=OpenLayers.Class({initialize:function(params){var defaults={image:{envelope:null,output:''},features:{featurecount:0,envelope:null,feature:[]},error:''};return OpenLayers.Util.extend(this,defaults);},CLASS_NAME:"OpenLayers.Format.ArcXML.Response"});OpenLayers.Format.GML=OpenLayers.Class(OpenLayers.Format.XML,{featureNS:"http://mapserver.gis.umn.edu/mapserver",featurePrefix:"feature",featureName:"featureMember",layerName:"features",geometryName:"geometry",collectionName:"FeatureCollection",gmlns:"http://www.opengis.net/gml",extractAttributes:true,xy:true,initialize:function(options){this.regExes={trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)};OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61448 var featureNodes=this.getElementsByTagNameNS(data.documentElement,this.gmlns,this.featureName);var features=[];for(var i=0;i<featureNodes.length;i++){var feature=this.parseFeature(featureNodes[i]);if(feature){features.push(feature);}}
61449 return features;},parseFeature:function(node){var order=["MultiPolygon","Polygon","MultiLineString","LineString","MultiPoint","Point","Envelope"];var type,nodeList,geometry,parser;for(var i=0;i<order.length;++i){type=order[i];nodeList=this.getElementsByTagNameNS(node,this.gmlns,type);if(nodeList.length>0){parser=this.parseGeometry[type.toLowerCase()];if(parser){geometry=parser.apply(this,[nodeList[0]]);if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}}else{OpenLayers.Console.error(OpenLayers.i18n("unsupportedGeometryType",{'geomType':type}));}
61450 break;}}
61451 var bounds;var boxNodes=this.getElementsByTagNameNS(node,this.gmlns,"Box");for(i=0;i<boxNodes.length;++i){var boxNode=boxNodes[i];var box=this.parseGeometry["box"].apply(this,[boxNode]);var parentNode=boxNode.parentNode;var parentName=parentNode.localName||parentNode.nodeName.split(":").pop();if(parentName==="boundedBy"){bounds=box;}else{geometry=box.toGeometry();}}
61452 var attributes;if(this.extractAttributes){attributes=this.parseAttributes(node);}
61453 var feature=new OpenLayers.Feature.Vector(geometry,attributes);feature.bounds=bounds;feature.gml={featureType:node.firstChild.nodeName.split(":")[1],featureNS:node.firstChild.namespaceURI,featureNSPrefix:node.firstChild.prefix};var childNode=node.firstChild;var fid;while(childNode){if(childNode.nodeType==1){fid=childNode.getAttribute("fid")||childNode.getAttribute("id");if(fid){break;}}
61454 childNode=childNode.nextSibling;}
61455 feature.fid=fid;return feature;},parseGeometry:{point:function(node){var nodeList,coordString;var coords=[];var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"pos");if(nodeList.length>0){coordString=nodeList[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);}
61456 if(coords.length==0){nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coordinates");if(nodeList.length>0){coordString=nodeList[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.removeSpace,"");coords=coordString.split(",");}}
61457 if(coords.length==0){nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coord");if(nodeList.length>0){var xList=this.getElementsByTagNameNS(nodeList[0],this.gmlns,"X");var yList=this.getElementsByTagNameNS(nodeList[0],this.gmlns,"Y");if(xList.length>0&&yList.length>0){coords=[xList[0].firstChild.nodeValue,yList[0].firstChild.nodeValue];}}}
61458 if(coords.length==2){coords[2]=null;}
61459 if(this.xy){return new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}
61460 else{return new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}},multipoint:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"Point");var components=[];if(nodeList.length>0){var point;for(var i=0;i<nodeList.length;++i){point=this.parseGeometry.point.apply(this,[nodeList[i]]);if(point){components.push(point);}}}
61461 return new OpenLayers.Geometry.MultiPoint(components);},linestring:function(node,ring){var nodeList,coordString;var coords=[];var points=[];nodeList=this.getElementsByTagNameNS(node,this.gmlns,"posList");if(nodeList.length>0){coordString=this.getChildValue(nodeList[0]);coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);var dim=parseInt(nodeList[0].getAttribute("dimension"));var j,x,y,z;for(var i=0;i<coords.length/dim;++i){j=i*dim;x=coords[j];y=coords[j+1];z=(dim==2)?null:coords[j+2];if(this.xy){points.push(new OpenLayers.Geometry.Point(x,y,z));}else{points.push(new OpenLayers.Geometry.Point(y,x,z));}}}
61462 if(coords.length==0){nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coordinates");if(nodeList.length>0){coordString=this.getChildValue(nodeList[0]);coordString=coordString.replace(this.regExes.trimSpace,"");coordString=coordString.replace(this.regExes.trimComma,",");var pointList=coordString.split(this.regExes.splitSpace);for(var i=0;i<pointList.length;++i){coords=pointList[i].split(",");if(coords.length==2){coords[2]=null;}
61463 if(this.xy){points.push(new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]));}else{points.push(new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]));}}}}
61464 var line=null;if(points.length!=0){if(ring){line=new OpenLayers.Geometry.LinearRing(points);}else{line=new OpenLayers.Geometry.LineString(points);}}
61465 return line;},multilinestring:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"LineString");var components=[];if(nodeList.length>0){var line;for(var i=0;i<nodeList.length;++i){line=this.parseGeometry.linestring.apply(this,[nodeList[i]]);if(line){components.push(line);}}}
61466 return new OpenLayers.Geometry.MultiLineString(components);},polygon:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"LinearRing");var components=[];if(nodeList.length>0){var ring;for(var i=0;i<nodeList.length;++i){ring=this.parseGeometry.linestring.apply(this,[nodeList[i],true]);if(ring){components.push(ring);}}}
61467 return new OpenLayers.Geometry.Polygon(components);},multipolygon:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"Polygon");var components=[];if(nodeList.length>0){var polygon;for(var i=0;i<nodeList.length;++i){polygon=this.parseGeometry.polygon.apply(this,[nodeList[i]]);if(polygon){components.push(polygon);}}}
61468 return new OpenLayers.Geometry.MultiPolygon(components);},envelope:function(node){var components=[];var coordString;var envelope;var lpoint=this.getElementsByTagNameNS(node,this.gmlns,"lowerCorner");if(lpoint.length>0){var coords=[];if(lpoint.length>0){coordString=lpoint[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);}
61469 if(coords.length==2){coords[2]=null;}
61470 if(this.xy){var lowerPoint=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{var lowerPoint=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}}
61471 var upoint=this.getElementsByTagNameNS(node,this.gmlns,"upperCorner");if(upoint.length>0){var coords=[];if(upoint.length>0){coordString=upoint[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);}
61472 if(coords.length==2){coords[2]=null;}
61473 if(this.xy){var upperPoint=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{var upperPoint=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}}
61474 if(lowerPoint&&upperPoint){components.push(new OpenLayers.Geometry.Point(lowerPoint.x,lowerPoint.y));components.push(new OpenLayers.Geometry.Point(upperPoint.x,lowerPoint.y));components.push(new OpenLayers.Geometry.Point(upperPoint.x,upperPoint.y));components.push(new OpenLayers.Geometry.Point(lowerPoint.x,upperPoint.y));components.push(new OpenLayers.Geometry.Point(lowerPoint.x,lowerPoint.y));var ring=new OpenLayers.Geometry.LinearRing(components);envelope=new OpenLayers.Geometry.Polygon([ring]);}
61475 return envelope;},box:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coordinates");var coordString;var coords,beginPoint=null,endPoint=null;if(nodeList.length>0){coordString=nodeList[0].firstChild.nodeValue;coords=coordString.split(" ");if(coords.length==2){beginPoint=coords[0].split(",");endPoint=coords[1].split(",");}}
61476 if(beginPoint!==null&&endPoint!==null){return new OpenLayers.Bounds(parseFloat(beginPoint[0]),parseFloat(beginPoint[1]),parseFloat(endPoint[0]),parseFloat(endPoint[1]));}}},parseAttributes:function(node){var attributes={};var childNode=node.firstChild;var children,i,child,grandchildren,grandchild,name,value;while(childNode){if(childNode.nodeType==1){children=childNode.childNodes;for(i=0;i<children.length;++i){child=children[i];if(child.nodeType==1){grandchildren=child.childNodes;if(grandchildren.length==1){grandchild=grandchildren[0];if(grandchild.nodeType==3||grandchild.nodeType==4){name=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;value=grandchild.nodeValue.replace(this.regExes.trimSpace,"");attributes[name]=value;}}else{attributes[child.nodeName.split(":").pop()]=null;}}}
61477 break;}
61478 childNode=childNode.nextSibling;}
61479 return attributes;},write:function(features){if(!(features instanceof Array)){features=[features];}
61480 var gml=this.createElementNS("http://www.opengis.net/wfs","wfs:"+this.collectionName);for(var i=0;i<features.length;i++){gml.appendChild(this.createFeatureXML(features[i]));}
61481 return OpenLayers.Format.XML.prototype.write.apply(this,[gml]);},createFeatureXML:function(feature){var geometry=feature.geometry;var geometryNode=this.buildGeometryNode(geometry);var geomContainer=this.createElementNS(this.featureNS,this.featurePrefix+":"+
61482 this.geometryName);geomContainer.appendChild(geometryNode);var featureNode=this.createElementNS(this.gmlns,"gml:"+this.featureName);var featureContainer=this.createElementNS(this.featureNS,this.featurePrefix+":"+
61483 this.layerName);var fid=feature.fid||feature.id;featureContainer.setAttribute("fid",fid);featureContainer.appendChild(geomContainer);for(var attr in feature.attributes){var attrText=this.createTextNode(feature.attributes[attr]);var nodename=attr.substring(attr.lastIndexOf(":")+1);var attrContainer=this.createElementNS(this.featureNS,this.featurePrefix+":"+
61484 nodename);attrContainer.appendChild(attrText);featureContainer.appendChild(attrContainer);}
61485 featureNode.appendChild(featureContainer);return featureNode;},buildGeometryNode:function(geometry){if(this.externalProjection&&this.internalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
61486 var className=geometry.CLASS_NAME;var type=className.substring(className.lastIndexOf(".")+1);var builder=this.buildGeometry[type.toLowerCase()];return builder.apply(this,[geometry]);},buildGeometry:{point:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:Point");gml.appendChild(this.buildCoordinatesNode(geometry));return gml;},multipoint:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:MultiPoint");var points=geometry.components;var pointMember,pointGeom;for(var i=0;i<points.length;i++){pointMember=this.createElementNS(this.gmlns,"gml:pointMember");pointGeom=this.buildGeometry.point.apply(this,[points[i]]);pointMember.appendChild(pointGeom);gml.appendChild(pointMember);}
61487 return gml;},linestring:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:LineString");gml.appendChild(this.buildCoordinatesNode(geometry));return gml;},multilinestring:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:MultiLineString");var lines=geometry.components;var lineMember,lineGeom;for(var i=0;i<lines.length;++i){lineMember=this.createElementNS(this.gmlns,"gml:lineStringMember");lineGeom=this.buildGeometry.linestring.apply(this,[lines[i]]);lineMember.appendChild(lineGeom);gml.appendChild(lineMember);}
61488 return gml;},linearring:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:LinearRing");gml.appendChild(this.buildCoordinatesNode(geometry));return gml;},polygon:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:Polygon");var rings=geometry.components;var ringMember,ringGeom,type;for(var i=0;i<rings.length;++i){type=(i==0)?"outerBoundaryIs":"innerBoundaryIs";ringMember=this.createElementNS(this.gmlns,"gml:"+type);ringGeom=this.buildGeometry.linearring.apply(this,[rings[i]]);ringMember.appendChild(ringGeom);gml.appendChild(ringMember);}
61489 return gml;},multipolygon:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:MultiPolygon");var polys=geometry.components;var polyMember,polyGeom;for(var i=0;i<polys.length;++i){polyMember=this.createElementNS(this.gmlns,"gml:polygonMember");polyGeom=this.buildGeometry.polygon.apply(this,[polys[i]]);polyMember.appendChild(polyGeom);gml.appendChild(polyMember);}
61490 return gml;},bounds:function(bounds){var gml=this.createElementNS(this.gmlns,"gml:Box");gml.appendChild(this.buildCoordinatesNode(bounds));return gml;}},buildCoordinatesNode:function(geometry){var coordinatesNode=this.createElementNS(this.gmlns,"gml:coordinates");coordinatesNode.setAttribute("decimal",".");coordinatesNode.setAttribute("cs",",");coordinatesNode.setAttribute("ts"," ");var parts=[];if(geometry instanceof OpenLayers.Bounds){parts.push(geometry.left+","+geometry.bottom);parts.push(geometry.right+","+geometry.top);}else{var points=(geometry.components)?geometry.components:[geometry];for(var i=0;i<points.length;i++){parts.push(points[i].x+","+points[i].y);}}
61491 var txtNode=this.createTextNode(parts.join(" "));coordinatesNode.appendChild(txtNode);return coordinatesNode;},CLASS_NAME:"OpenLayers.Format.GML"});OpenLayers.Format.GeoJSON=OpenLayers.Class(OpenLayers.Format.JSON,{ignoreExtraDims:false,initialize:function(options){OpenLayers.Format.JSON.prototype.initialize.apply(this,[options]);},read:function(json,type,filter){type=(type)?type:"FeatureCollection";var results=null;var obj=null;if(typeof json=="string"){obj=OpenLayers.Format.JSON.prototype.read.apply(this,[json,filter]);}else{obj=json;}
61492 if(!obj){OpenLayers.Console.error("Bad JSON: "+json);}else if(typeof(obj.type)!="string"){OpenLayers.Console.error("Bad GeoJSON - no type: "+json);}else if(this.isValidType(obj,type)){switch(type){case"Geometry":try{results=this.parseGeometry(obj);}catch(err){OpenLayers.Console.error(err);}
61493 break;case"Feature":try{results=this.parseFeature(obj);results.type="Feature";}catch(err){OpenLayers.Console.error(err);}
61494 break;case"FeatureCollection":results=[];switch(obj.type){case"Feature":try{results.push(this.parseFeature(obj));}catch(err){results=null;OpenLayers.Console.error(err);}
61495 break;case"FeatureCollection":for(var i=0,len=obj.features.length;i<len;++i){try{results.push(this.parseFeature(obj.features[i]));}catch(err){results=null;OpenLayers.Console.error(err);}}
61496 break;default:try{var geom=this.parseGeometry(obj);results.push(new OpenLayers.Feature.Vector(geom));}catch(err){results=null;OpenLayers.Console.error(err);}}
61497 break;}}
61498 return results;},isValidType:function(obj,type){var valid=false;switch(type){case"Geometry":if(OpenLayers.Util.indexOf(["Point","MultiPoint","LineString","MultiLineString","Polygon","MultiPolygon","Box","GeometryCollection"],obj.type)==-1){OpenLayers.Console.error("Unsupported geometry type: "+
61499 obj.type);}else{valid=true;}
61500 break;case"FeatureCollection":valid=true;break;default:if(obj.type==type){valid=true;}else{OpenLayers.Console.error("Cannot convert types from "+
61501 obj.type+" to "+type);}}
61502 return valid;},parseFeature:function(obj){var feature,geometry,attributes,bbox;attributes=(obj.properties)?obj.properties:{};bbox=(obj.geometry&&obj.geometry.bbox)||obj.bbox;try{geometry=this.parseGeometry(obj.geometry);}catch(err){throw err;}
61503 feature=new OpenLayers.Feature.Vector(geometry,attributes);if(bbox){feature.bounds=OpenLayers.Bounds.fromArray(bbox);}
61504 if(obj.id){feature.fid=obj.id;}
61505 return feature;},parseGeometry:function(obj){if(obj==null){return null;}
61506 var geometry,collection=false;if(obj.type=="GeometryCollection"){if(!(obj.geometries instanceof Array)){throw"GeometryCollection must have geometries array: "+obj;}
61507 var numGeom=obj.geometries.length;var components=new Array(numGeom);for(var i=0;i<numGeom;++i){components[i]=this.parseGeometry.apply(this,[obj.geometries[i]]);}
61508 geometry=new OpenLayers.Geometry.Collection(components);collection=true;}else{if(!(obj.coordinates instanceof Array)){throw"Geometry must have coordinates array: "+obj;}
61509 if(!this.parseCoords[obj.type.toLowerCase()]){throw"Unsupported geometry type: "+obj.type;}
61510 try{geometry=this.parseCoords[obj.type.toLowerCase()].apply(this,[obj.coordinates]);}catch(err){throw err;}}
61511 if(this.internalProjection&&this.externalProjection&&!collection){geometry.transform(this.externalProjection,this.internalProjection);}
61512 return geometry;},parseCoords:{"point":function(array){if(this.ignoreExtraDims==false&&array.length!=2){throw"Only 2D points are supported: "+array;}
61513 return new OpenLayers.Geometry.Point(array[0],array[1]);},"multipoint":function(array){var points=[];var p=null;for(var i=0,len=array.length;i<len;++i){try{p=this.parseCoords["point"].apply(this,[array[i]]);}catch(err){throw err;}
61514 points.push(p);}
61515 return new OpenLayers.Geometry.MultiPoint(points);},"linestring":function(array){var points=[];var p=null;for(var i=0,len=array.length;i<len;++i){try{p=this.parseCoords["point"].apply(this,[array[i]]);}catch(err){throw err;}
61516 points.push(p);}
61517 return new OpenLayers.Geometry.LineString(points);},"multilinestring":function(array){var lines=[];var l=null;for(var i=0,len=array.length;i<len;++i){try{l=this.parseCoords["linestring"].apply(this,[array[i]]);}catch(err){throw err;}
61518 lines.push(l);}
61519 return new OpenLayers.Geometry.MultiLineString(lines);},"polygon":function(array){var rings=[];var r,l;for(var i=0,len=array.length;i<len;++i){try{l=this.parseCoords["linestring"].apply(this,[array[i]]);}catch(err){throw err;}
61520 r=new OpenLayers.Geometry.LinearRing(l.components);rings.push(r);}
61521 return new OpenLayers.Geometry.Polygon(rings);},"multipolygon":function(array){var polys=[];var p=null;for(var i=0,len=array.length;i<len;++i){try{p=this.parseCoords["polygon"].apply(this,[array[i]]);}catch(err){throw err;}
61522 polys.push(p);}
61523 return new OpenLayers.Geometry.MultiPolygon(polys);},"box":function(array){if(array.length!=2){throw"GeoJSON box coordinates must have 2 elements";}
61524 return new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([new OpenLayers.Geometry.Point(array[0][0],array[0][1]),new OpenLayers.Geometry.Point(array[1][0],array[0][1]),new OpenLayers.Geometry.Point(array[1][0],array[1][1]),new OpenLayers.Geometry.Point(array[0][0],array[1][1]),new OpenLayers.Geometry.Point(array[0][0],array[0][1])])]);}},write:function(obj,pretty){var geojson={"type":null};if(obj instanceof Array){geojson.type="FeatureCollection";var numFeatures=obj.length;geojson.features=new Array(numFeatures);for(var i=0;i<numFeatures;++i){var element=obj[i];if(!element instanceof OpenLayers.Feature.Vector){var msg="FeatureCollection only supports collections "+"of features: "+element;throw msg;}
61525 geojson.features[i]=this.extract.feature.apply(this,[element]);}}else if(obj.CLASS_NAME.indexOf("OpenLayers.Geometry")==0){geojson=this.extract.geometry.apply(this,[obj]);}else if(obj instanceof OpenLayers.Feature.Vector){geojson=this.extract.feature.apply(this,[obj]);if(obj.layer&&obj.layer.projection){geojson.crs=this.createCRSObject(obj);}}
61526 return OpenLayers.Format.JSON.prototype.write.apply(this,[geojson,pretty]);},createCRSObject:function(object){var proj=object.layer.projection.toString();var crs={};if(proj.match(/epsg:/i)){var code=parseInt(proj.substring(proj.indexOf(":")+1));if(code==4326){crs={"type":"OGC","properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}};}else{crs={"type":"EPSG","properties":{"code":code}};}}
61527 return crs;},extract:{'feature':function(feature){var geom=this.extract.geometry.apply(this,[feature.geometry]);return{"type":"Feature","id":feature.fid==null?feature.id:feature.fid,"properties":feature.attributes,"geometry":geom};},'geometry':function(geometry){if(geometry==null){return null;}
61528 if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
61529 var geometryType=geometry.CLASS_NAME.split('.')[2];var data=this.extract[geometryType.toLowerCase()].apply(this,[geometry]);var json;if(geometryType=="Collection"){json={"type":"GeometryCollection","geometries":data};}else{json={"type":geometryType,"coordinates":data};}
61530 return json;},'point':function(point){return[point.x,point.y];},'multipoint':function(multipoint){var array=[];for(var i=0,len=multipoint.components.length;i<len;++i){array.push(this.extract.point.apply(this,[multipoint.components[i]]));}
61531 return array;},'linestring':function(linestring){var array=[];for(var i=0,len=linestring.components.length;i<len;++i){array.push(this.extract.point.apply(this,[linestring.components[i]]));}
61532 return array;},'multilinestring':function(multilinestring){var array=[];for(var i=0,len=multilinestring.components.length;i<len;++i){array.push(this.extract.linestring.apply(this,[multilinestring.components[i]]));}
61533 return array;},'polygon':function(polygon){var array=[];for(var i=0,len=polygon.components.length;i<len;++i){array.push(this.extract.linestring.apply(this,[polygon.components[i]]));}
61534 return array;},'multipolygon':function(multipolygon){var array=[];for(var i=0,len=multipolygon.components.length;i<len;++i){array.push(this.extract.polygon.apply(this,[multipolygon.components[i]]));}
61535 return array;},'collection':function(collection){var len=collection.components.length;var array=new Array(len);for(var i=0;i<len;++i){array[i]=this.extract.geometry.apply(this,[collection.components[i]]);}
61536 return array;}},CLASS_NAME:"OpenLayers.Format.GeoJSON"});OpenLayers.Format.ArcXML.Features=OpenLayers.Class(OpenLayers.Format.XML,{initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){var axl=new OpenLayers.Format.ArcXML();var parsed=axl.read(data);return parsed.features.feature;}});if(!OpenLayers.Format.GML){OpenLayers.Format.GML={};}
61537 OpenLayers.Format.GML.Base=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",wfs:"http://www.opengis.net/wfs"},defaultPrefix:"gml",schemaLocation:null,featureType:null,featureNS:null,geometryName:"geometry",extractAttributes:true,srsName:null,xy:true,geometryTypes:null,singleFeatureType:null,regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.setGeometryTypes();if(options&&options.featureNS){this.setNamespace("feature",options.featureNS);}
61538 this.singleFeatureType=!options||(typeof options.featureType==="string");},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61539 if(data&&data.nodeType==9){data=data.documentElement;}
61540 var features=[];this.readNode(data,{features:features});if(features.length==0){var elements=this.getElementsByTagNameNS(data,this.namespaces.gml,"featureMember");if(elements.length){for(var i=0,len=elements.length;i<len;++i){this.readNode(elements[i],{features:features});}}else{var elements=this.getElementsByTagNameNS(data,this.namespaces.gml,"featureMembers");if(elements.length){this.readNode(elements[0],{features:features});}}}
61541 return features;},readers:{"gml":{"featureMember":function(node,obj){this.readChildNodes(node,obj);},"featureMembers":function(node,obj){this.readChildNodes(node,obj);},"name":function(node,obj){obj.name=this.getChildValue(node);},"boundedBy":function(node,obj){var container={};this.readChildNodes(node,container);if(container.components&&container.components.length>0){obj.bounds=container.components[0];}},"Point":function(node,container){var obj={points:[]};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
61542 container.components.push(obj.points[0]);},"coordinates":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");str=str.replace(this.regExes.trimComma,",");var pointList=str.split(this.regExes.splitSpace);var coords;var numPoints=pointList.length;var points=new Array(numPoints);for(var i=0;i<numPoints;++i){coords=pointList[i].split(",");if(this.xy){points[i]=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{points[i]=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}}
61543 obj.points=points;},"coord":function(node,obj){var coord={};this.readChildNodes(node,coord);if(!obj.points){obj.points=[];}
61544 obj.points.push(new OpenLayers.Geometry.Point(coord.x,coord.y,coord.z));},"X":function(node,coord){coord.x=this.getChildValue(node);},"Y":function(node,coord){coord.y=this.getChildValue(node);},"Z":function(node,coord){coord.z=this.getChildValue(node);},"MultiPoint":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.MultiPoint(obj.components)];},"pointMember":function(node,obj){this.readChildNodes(node,obj);},"LineString":function(node,container){var obj={};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
61545 container.components.push(new OpenLayers.Geometry.LineString(obj.points));},"MultiLineString":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.MultiLineString(obj.components)];},"lineStringMember":function(node,obj){this.readChildNodes(node,obj);},"Polygon":function(node,container){var obj={outer:null,inner:[]};this.readChildNodes(node,obj);obj.inner.unshift(obj.outer);if(!container.components){container.components=[];}
61546 container.components.push(new OpenLayers.Geometry.Polygon(obj.inner));},"LinearRing":function(node,obj){var container={};this.readChildNodes(node,container);obj.components=[new OpenLayers.Geometry.LinearRing(container.points)];},"MultiPolygon":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.MultiPolygon(obj.components)];},"polygonMember":function(node,obj){this.readChildNodes(node,obj);},"GeometryCollection":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.Collection(obj.components)];},"geometryMember":function(node,obj){this.readChildNodes(node,obj);}},"feature":{"*":function(node,obj){var name;var local=node.localName||node.nodeName.split(":").pop();if(obj.features){if(!this.singleFeatureType&&(OpenLayers.Util.indexOf(this.featureType,local)!==-1)){name="_typeName";}else if(local===this.featureType){name="_typeName";}}else{if(node.childNodes.length==0||(node.childNodes.length==1&&node.firstChild.nodeType==3)){if(this.extractAttributes){name="_attribute";}}else{name="_geometry";}}
61547 if(name){this.readers.feature[name].apply(this,[node,obj]);}},"_typeName":function(node,obj){var container={components:[],attributes:{}};this.readChildNodes(node,container);if(container.name){container.attributes.name=container.name;}
61548 var feature=new OpenLayers.Feature.Vector(container.components[0],container.attributes);if(!this.singleFeatureType){feature.type=node.nodeName.split(":").pop();feature.namespace=node.namespaceURI;}
61549 var fid=node.getAttribute("fid")||this.getAttributeNS(node,this.namespaces["gml"],"id");if(fid){feature.fid=fid;}
61550 if(this.internalProjection&&this.externalProjection&&feature.geometry){feature.geometry.transform(this.externalProjection,this.internalProjection);}
61551 if(container.bounds){feature.bounds=container.bounds;}
61552 obj.features.push(feature);},"_geometry":function(node,obj){this.readChildNodes(node,obj);},"_attribute":function(node,obj){var local=node.localName||node.nodeName.split(":").pop();var value=this.getChildValue(node);obj.attributes[local]=value;}},"wfs":{"FeatureCollection":function(node,obj){this.readChildNodes(node,obj);}}},write:function(features){var name;if(features instanceof Array){name="featureMembers";}else{name="featureMember";}
61553 var root=this.writeNode("gml:"+name,features);this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},writers:{"gml":{"featureMember":function(feature){var node=this.createElementNSPlus("gml:featureMember");this.writeNode("feature:_typeName",feature,node);return node;},"MultiPoint":function(geometry){var node=this.createElementNSPlus("gml:MultiPoint");for(var i=0;i<geometry.components.length;++i){this.writeNode("pointMember",geometry.components[i],node);}
61554 return node;},"pointMember":function(geometry){var node=this.createElementNSPlus("gml:pointMember");this.writeNode("Point",geometry,node);return node;},"MultiLineString":function(geometry){var node=this.createElementNSPlus("gml:MultiLineString");for(var i=0;i<geometry.components.length;++i){this.writeNode("lineStringMember",geometry.components[i],node);}
61555 return node;},"lineStringMember":function(geometry){var node=this.createElementNSPlus("gml:lineStringMember");this.writeNode("LineString",geometry,node);return node;},"MultiPolygon":function(geometry){var node=this.createElementNSPlus("gml:MultiPolygon");for(var i=0;i<geometry.components.length;++i){this.writeNode("polygonMember",geometry.components[i],node);}
61556 return node;},"polygonMember":function(geometry){var node=this.createElementNSPlus("gml:polygonMember");this.writeNode("Polygon",geometry,node);return node;},"GeometryCollection":function(geometry){var node=this.createElementNSPlus("gml:GeometryCollection");for(var i=0,len=geometry.components.length;i<len;++i){this.writeNode("geometryMember",geometry.components[i],node);}
61557 return node;},"geometryMember":function(geometry){var node=this.createElementNSPlus("gml:geometryMember");var child=this.writeNode("feature:_geometry",geometry);node.appendChild(child.firstChild);return node;}},"feature":{"_typeName":function(feature){var node=this.createElementNSPlus("feature:"+this.featureType,{attributes:{fid:feature.fid}});if(feature.geometry){this.writeNode("feature:_geometry",feature.geometry,node);}
61558 for(var name in feature.attributes){var value=feature.attributes[name];if(value!=null){this.writeNode("feature:_attribute",{name:name,value:value},node);}}
61559 return node;},"_geometry":function(geometry){if(this.externalProjection&&this.internalProjection){geometry=geometry.clone().transform(this.internalProjection,this.externalProjection);}
61560 var node=this.createElementNSPlus("feature:"+this.geometryName);var type=this.geometryTypes[geometry.CLASS_NAME];var child=this.writeNode("gml:"+type,geometry,node);if(this.srsName){child.setAttribute("srsName",this.srsName);}
61561 return node;},"_attribute":function(obj){return this.createElementNSPlus("feature:"+obj.name,{value:obj.value});}},"wfs":{"FeatureCollection":function(features){var node=this.createElementNSPlus("wfs:FeatureCollection");for(var i=0,len=features.length;i<len;++i){this.writeNode("gml:featureMember",features[i],node);}
61562 return node;}}},setGeometryTypes:function(){this.geometryTypes={"OpenLayers.Geometry.Point":"Point","OpenLayers.Geometry.MultiPoint":"MultiPoint","OpenLayers.Geometry.LineString":"LineString","OpenLayers.Geometry.MultiLineString":"MultiLineString","OpenLayers.Geometry.Polygon":"Polygon","OpenLayers.Geometry.MultiPolygon":"MultiPolygon","OpenLayers.Geometry.Collection":"GeometryCollection"};},CLASS_NAME:"OpenLayers.Format.GML.Base"});OpenLayers.Format.WFS=OpenLayers.Class(OpenLayers.Format.GML,{layer:null,wfsns:"http://www.opengis.net/wfs",ogcns:"http://www.opengis.net/ogc",initialize:function(options,layer){OpenLayers.Format.GML.prototype.initialize.apply(this,[options]);this.layer=layer;if(this.layer.featureNS){this.featureNS=this.layer.featureNS;}
61563 if(this.layer.options.geometry_column){this.geometryName=this.layer.options.geometry_column;}
61564 if(this.layer.options.typename){this.featureName=this.layer.options.typename;}},write:function(features){var transaction=this.createElementNS(this.wfsns,'wfs:Transaction');transaction.setAttribute("version","1.0.0");transaction.setAttribute("service","WFS");for(var i=0;i<features.length;i++){switch(features[i].state){case OpenLayers.State.INSERT:transaction.appendChild(this.insert(features[i]));break;case OpenLayers.State.UPDATE:transaction.appendChild(this.update(features[i]));break;case OpenLayers.State.DELETE:transaction.appendChild(this.remove(features[i]));break;}}
61565 return OpenLayers.Format.XML.prototype.write.apply(this,[transaction]);},createFeatureXML:function(feature){var geometryNode=this.buildGeometryNode(feature.geometry);var geomContainer=this.createElementNS(this.featureNS,"feature:"+this.geometryName);geomContainer.appendChild(geometryNode);var featureContainer=this.createElementNS(this.featureNS,"feature:"+this.featureName);featureContainer.appendChild(geomContainer);for(var attr in feature.attributes){var attrText=this.createTextNode(feature.attributes[attr]);var nodename=attr;if(attr.search(":")!=-1){nodename=attr.split(":")[1];}
61566 var attrContainer=this.createElementNS(this.featureNS,"feature:"+nodename);attrContainer.appendChild(attrText);featureContainer.appendChild(attrContainer);}
61567 return featureContainer;},insert:function(feature){var insertNode=this.createElementNS(this.wfsns,'wfs:Insert');insertNode.appendChild(this.createFeatureXML(feature));return insertNode;},update:function(feature){if(!feature.fid){OpenLayers.Console.userError(OpenLayers.i18n("noFID"));}
61568 var updateNode=this.createElementNS(this.wfsns,'wfs:Update');updateNode.setAttribute("typeName",this.featurePrefix+':'+this.featureName);updateNode.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);var propertyNode=this.createElementNS(this.wfsns,'wfs:Property');var nameNode=this.createElementNS(this.wfsns,'wfs:Name');var txtNode=this.createTextNode(this.geometryName);nameNode.appendChild(txtNode);propertyNode.appendChild(nameNode);var valueNode=this.createElementNS(this.wfsns,'wfs:Value');var geometryNode=this.buildGeometryNode(feature.geometry);if(feature.layer){geometryNode.setAttribute("srsName",feature.layer.projection.getCode());}
61569 valueNode.appendChild(geometryNode);propertyNode.appendChild(valueNode);updateNode.appendChild(propertyNode);for(var propName in feature.attributes){propertyNode=this.createElementNS(this.wfsns,'wfs:Property');nameNode=this.createElementNS(this.wfsns,'wfs:Name');nameNode.appendChild(this.createTextNode(propName));propertyNode.appendChild(nameNode);valueNode=this.createElementNS(this.wfsns,'wfs:Value');valueNode.appendChild(this.createTextNode(feature.attributes[propName]));propertyNode.appendChild(valueNode);updateNode.appendChild(propertyNode);}
61570 var filterNode=this.createElementNS(this.ogcns,'ogc:Filter');var filterIdNode=this.createElementNS(this.ogcns,'ogc:FeatureId');filterIdNode.setAttribute("fid",feature.fid);filterNode.appendChild(filterIdNode);updateNode.appendChild(filterNode);return updateNode;},remove:function(feature){if(!feature.fid){OpenLayers.Console.userError(OpenLayers.i18n("noFID"));return false;}
61571 var deleteNode=this.createElementNS(this.wfsns,'wfs:Delete');deleteNode.setAttribute("typeName",this.featurePrefix+':'+this.featureName);deleteNode.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);var filterNode=this.createElementNS(this.ogcns,'ogc:Filter');var filterIdNode=this.createElementNS(this.ogcns,'ogc:FeatureId');filterIdNode.setAttribute("fid",feature.fid);filterNode.appendChild(filterIdNode);deleteNode.appendChild(filterNode);return deleteNode;},destroy:function(){this.layer=null;},CLASS_NAME:"OpenLayers.Format.WFS"});OpenLayers.Layer.ArcIMS=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{ClientVersion:"9.2",ServiceName:''},tileSize:null,featureCoordSys:"4326",filterCoordSys:"4326",layers:null,async:true,name:"ArcIMS",isBaseLayer:true,DEFAULT_OPTIONS:{tileSize:new OpenLayers.Size(512,512),featureCoordSys:"4326",filterCoordSys:"4326",layers:null,isBaseLayer:true,async:true,name:"ArcIMS"},initialize:function(name,url,options){this.tileSize=new OpenLayers.Size(512,512);this.params=OpenLayers.Util.applyDefaults({ServiceName:options.serviceName},this.DEFAULT_PARAMS);this.options=OpenLayers.Util.applyDefaults(options,this.DEFAULT_OPTIONS);OpenLayers.Layer.Grid.prototype.initialize.apply(this,[name,url,this.params,options]);if(this.transparent){if(!this.isBaseLayer){this.isBaseLayer=false;}
61572 if(this.format=="image/jpeg"){this.format=OpenLayers.Util.alphaHack()?"image/gif":"image/png";}}
61573 if(this.options.layers===null){this.options.layers=[];}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},getURL:function(bounds){var url="";bounds=this.adjustBounds(bounds);var axlReq=new OpenLayers.Format.ArcXML(OpenLayers.Util.extend(this.options,{requesttype:"image",envelope:bounds.toArray(),tileSize:this.tileSize}));var req=new OpenLayers.Request.POST({url:this.getFullRequestString(),data:axlReq.write(),async:false});if(req!=null){var doc=req.responseXML;if(!doc||!doc.documentElement){doc=req.responseText;}
61574 var axlResp=new OpenLayers.Format.ArcXML();var arcxml=axlResp.read(doc);url=this.getUrlOrImage(arcxml.image.output);}
61575 return url;},getURLasync:function(bounds,scope,prop,callback){bounds=this.adjustBounds(bounds);var axlReq=new OpenLayers.Format.ArcXML(OpenLayers.Util.extend(this.options,{requesttype:"image",envelope:bounds.toArray(),tileSize:this.tileSize}));OpenLayers.Request.POST({url:this.getFullRequestString(),async:true,data:axlReq.write(),callback:function(req){var doc=req.responseXML;if(!doc||!doc.documentElement){doc=req.responseText;}
61576 var axlResp=new OpenLayers.Format.ArcXML();var arcxml=axlResp.read(doc);scope[prop]=this.getUrlOrImage(arcxml.image.output);callback.apply(scope);},scope:this});},getUrlOrImage:function(output){var ret="";if(output.url){ret=output.url;}else if(output.data){ret="data:image/"+output.type+";base64,"+output.data;}
61577 return ret;},setLayerQuery:function(id,querydef){for(var lyr=0;lyr<this.options.layers.length;lyr++){if(id==this.options.layers[lyr].id){this.options.layers[lyr].query=querydef;return;}}
61578 this.options.layers.push({id:id,visible:true,query:querydef});},getFeatureInfo:function(geometry,layer,options){var buffer=options.buffer||1;var callback=options.callback||function(){};var scope=options.scope||window;var requestOptions={};OpenLayers.Util.extend(requestOptions,this.options);requestOptions.requesttype="feature";if(geometry instanceof OpenLayers.LonLat){requestOptions.polygon=null;requestOptions.envelope=[geometry.lon-buffer,geometry.lat-buffer,geometry.lon+buffer,geometry.lat+buffer];}else if(geometry instanceof OpenLayers.Geometry.Polygon){requestOptions.envelope=null;requestOptions.polygon=geometry;}
61579 var arcxml=new OpenLayers.Format.ArcXML(requestOptions);OpenLayers.Util.extend(arcxml.request.get_feature,options);arcxml.request.get_feature.layer=layer.id;if(typeof layer.query.accuracy=="number"){arcxml.request.get_feature.query.accuracy=layer.query.accuracy;}else{var mapCenter=this.map.getCenter();var viewPx=this.map.getViewPortPxFromLonLat(mapCenter);viewPx.x++;var mapOffCenter=this.map.getLonLatFromPixel(viewPx);arcxml.request.get_feature.query.accuracy=mapOffCenter.lon-mapCenter.lon;}
61580 arcxml.request.get_feature.query.where=layer.query.where;arcxml.request.get_feature.query.spatialfilter.relation="area_intersection";OpenLayers.Request.POST({url:this.getFullRequestString({'CustomService':'Query'}),data:arcxml.write(),callback:function(request){var response=arcxml.parseResponse(request.responseText);if(!arcxml.iserror()){callback.call(scope,response.features);}else{callback.call(scope,null);}}});},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.ArcIMS(this.name,this.url,this.getOptions());}
61581 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.ArcIMS"});OpenLayers.Format.GML.v2=OpenLayers.Class(OpenLayers.Format.GML.Base,{schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd",initialize:function(options){OpenLayers.Format.GML.Base.prototype.initialize.apply(this,[options]);},readers:{"gml":OpenLayers.Util.applyDefaults({"outerBoundaryIs":function(node,container){var obj={};this.readChildNodes(node,obj);container.outer=obj.components[0];},"innerBoundaryIs":function(node,container){var obj={};this.readChildNodes(node,obj);container.inner.push(obj.components[0]);},"Box":function(node,container){var obj={};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
61582 var min=obj.points[0];var max=obj.points[1];container.components.push(new OpenLayers.Bounds(min.x,min.y,max.x,max.y));}},OpenLayers.Format.GML.Base.prototype.readers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.readers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.readers["wfs"]},write:function(features){var name;if(features instanceof Array){name="wfs:FeatureCollection";}else{name="gml:featureMember";}
61583 var root=this.writeNode(name,features);this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},writers:{"gml":OpenLayers.Util.applyDefaults({"Point":function(geometry){var node=this.createElementNSPlus("gml:Point");this.writeNode("coordinates",[geometry],node);return node;},"coordinates":function(points){var numPoints=points.length;var parts=new Array(numPoints);var point;for(var i=0;i<numPoints;++i){point=points[i];if(this.xy){parts[i]=point.x+","+point.y;}else{parts[i]=point.y+","+point.x;}
61584 if(point.z!=undefined){parts[i]+=","+point.z;}}
61585 return this.createElementNSPlus("gml:coordinates",{attributes:{decimal:".",cs:",",ts:" "},value:(numPoints==1)?parts[0]:parts.join(" ")});},"LineString":function(geometry){var node=this.createElementNSPlus("gml:LineString");this.writeNode("coordinates",geometry.components,node);return node;},"Polygon":function(geometry){var node=this.createElementNSPlus("gml:Polygon");this.writeNode("outerBoundaryIs",geometry.components[0],node);for(var i=1;i<geometry.components.length;++i){this.writeNode("innerBoundaryIs",geometry.components[i],node);}
61586 return node;},"outerBoundaryIs":function(ring){var node=this.createElementNSPlus("gml:outerBoundaryIs");this.writeNode("LinearRing",ring,node);return node;},"innerBoundaryIs":function(ring){var node=this.createElementNSPlus("gml:innerBoundaryIs");this.writeNode("LinearRing",ring,node);return node;},"LinearRing":function(ring){var node=this.createElementNSPlus("gml:LinearRing");this.writeNode("coordinates",ring.components,node);return node;},"Box":function(bounds){var node=this.createElementNSPlus("gml:Box");this.writeNode("coordinates",[{x:bounds.left,y:bounds.bottom},{x:bounds.right,y:bounds.top}],node);if(this.srsName){node.setAttribute("srsName",this.srsName);}
61587 return node;}},OpenLayers.Format.GML.Base.prototype.writers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.writers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.writers["wfs"]},CLASS_NAME:"OpenLayers.Format.GML.v2"});OpenLayers.Format.GML.v3=OpenLayers.Class(OpenLayers.Format.GML.Base,{schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/1.0.0/gmlsf.xsd",curve:false,multiCurve:true,surface:false,multiSurface:true,initialize:function(options){OpenLayers.Format.GML.Base.prototype.initialize.apply(this,[options]);},readers:{"gml":OpenLayers.Util.applyDefaults({"featureMembers":function(node,obj){this.readChildNodes(node,obj);},"Curve":function(node,container){var obj={points:[]};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
61588 container.components.push(new OpenLayers.Geometry.LineString(obj.points));},"segments":function(node,obj){this.readChildNodes(node,obj);},"LineStringSegment":function(node,container){var obj={};this.readChildNodes(node,obj);if(obj.points){Array.prototype.push.apply(container.points,obj.points);}},"pos":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");var coords=str.split(this.regExes.splitSpace);var point;if(this.xy){point=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{point=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}
61589 obj.points=[point];},"posList":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");var coords=str.split(this.regExes.splitSpace);var dim=parseInt(node.getAttribute("dimension"))||2;var j,x,y,z;var numPoints=coords.length/dim;var points=new Array(numPoints);for(var i=0,len=coords.length;i<len;i+=dim){x=coords[i];y=coords[i+1];z=(dim==2)?undefined:coords[i+2];if(this.xy){points[i/dim]=new OpenLayers.Geometry.Point(x,y,z);}else{points[i/dim]=new OpenLayers.Geometry.Point(y,x,z);}}
61590 obj.points=points;},"Surface":function(node,obj){this.readChildNodes(node,obj);},"patches":function(node,obj){this.readChildNodes(node,obj);},"PolygonPatch":function(node,obj){this.readers.gml.Polygon.apply(this,[node,obj]);},"exterior":function(node,container){var obj={};this.readChildNodes(node,obj);container.outer=obj.components[0];},"interior":function(node,container){var obj={};this.readChildNodes(node,obj);container.inner.push(obj.components[0]);},"MultiCurve":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);if(obj.components.length>0){container.components=[new OpenLayers.Geometry.MultiLineString(obj.components)];}},"curveMember":function(node,obj){this.readChildNodes(node,obj);},"MultiSurface":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);if(obj.components.length>0){container.components=[new OpenLayers.Geometry.MultiPolygon(obj.components)];}},"surfaceMember":function(node,obj){this.readChildNodes(node,obj);},"surfaceMembers":function(node,obj){this.readChildNodes(node,obj);},"pointMembers":function(node,obj){this.readChildNodes(node,obj);},"lineStringMembers":function(node,obj){this.readChildNodes(node,obj);},"polygonMembers":function(node,obj){this.readChildNodes(node,obj);},"geometryMembers":function(node,obj){this.readChildNodes(node,obj);},"Envelope":function(node,container){var obj={points:new Array(2)};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
61591 var min=obj.points[0];var max=obj.points[1];container.components.push(new OpenLayers.Bounds(min.x,min.y,max.x,max.y));},"lowerCorner":function(node,container){var obj={};this.readers.gml.pos.apply(this,[node,obj]);container.points[0]=obj.points[0];},"upperCorner":function(node,container){var obj={};this.readers.gml.pos.apply(this,[node,obj]);container.points[1]=obj.points[0];}},OpenLayers.Format.GML.Base.prototype.readers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.readers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.readers["wfs"]},write:function(features){var name;if(features instanceof Array){name="featureMembers";}else{name="featureMember";}
61592 var root=this.writeNode("gml:"+name,features);this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},writers:{"gml":OpenLayers.Util.applyDefaults({"featureMembers":function(features){var node=this.createElementNSPlus("gml:featureMembers");for(var i=0,len=features.length;i<len;++i){this.writeNode("feature:_typeName",features[i],node);}
61593 return node;},"Point":function(geometry){var node=this.createElementNSPlus("gml:Point");this.writeNode("pos",geometry,node);return node;},"pos":function(point){var pos=(this.xy)?(point.x+" "+point.y):(point.y+" "+point.x);return this.createElementNSPlus("gml:pos",{value:pos});},"LineString":function(geometry){var node=this.createElementNSPlus("gml:LineString");this.writeNode("posList",geometry.components,node);return node;},"Curve":function(geometry){var node=this.createElementNSPlus("gml:Curve");this.writeNode("segments",geometry,node);return node;},"segments":function(geometry){var node=this.createElementNSPlus("gml:segments");this.writeNode("LineStringSegment",geometry,node);return node;},"LineStringSegment":function(geometry){var node=this.createElementNSPlus("gml:LineStringSegment");this.writeNode("posList",geometry.components,node);return node;},"posList":function(points){var len=points.length;var parts=new Array(len);var point;for(var i=0;i<len;++i){point=points[i];if(this.xy){parts[i]=point.x+" "+point.y;}else{parts[i]=point.y+" "+point.x;}}
61594 return this.createElementNSPlus("gml:posList",{value:parts.join(" ")});},"Surface":function(geometry){var node=this.createElementNSPlus("gml:Surface");this.writeNode("patches",geometry,node);return node;},"patches":function(geometry){var node=this.createElementNSPlus("gml:patches");this.writeNode("PolygonPatch",geometry,node);return node;},"PolygonPatch":function(geometry){var node=this.createElementNSPlus("gml:PolygonPatch",{attributes:{interpolation:"planar"}});this.writeNode("exterior",geometry.components[0],node);for(var i=1,len=geometry.components.length;i<len;++i){this.writeNode("interior",geometry.components[i],node);}
61595 return node;},"Polygon":function(geometry){var node=this.createElementNSPlus("gml:Polygon");this.writeNode("exterior",geometry.components[0],node);for(var i=1,len=geometry.components.length;i<len;++i){this.writeNode("interior",geometry.components[i],node);}
61596 return node;},"exterior":function(ring){var node=this.createElementNSPlus("gml:exterior");this.writeNode("LinearRing",ring,node);return node;},"interior":function(ring){var node=this.createElementNSPlus("gml:interior");this.writeNode("LinearRing",ring,node);return node;},"LinearRing":function(ring){var node=this.createElementNSPlus("gml:LinearRing");this.writeNode("posList",ring.components,node);return node;},"MultiCurve":function(geometry){var node=this.createElementNSPlus("gml:MultiCurve");for(var i=0,len=geometry.components.length;i<len;++i){this.writeNode("curveMember",geometry.components[i],node);}
61597 return node;},"curveMember":function(geometry){var node=this.createElementNSPlus("gml:curveMember");if(this.curve){this.writeNode("Curve",geometry,node);}else{this.writeNode("LineString",geometry,node);}
61598 return node;},"MultiSurface":function(geometry){var node=this.createElementNSPlus("gml:MultiSurface");for(var i=0,len=geometry.components.length;i<len;++i){this.writeNode("surfaceMember",geometry.components[i],node);}
61599 return node;},"surfaceMember":function(polygon){var node=this.createElementNSPlus("gml:surfaceMember");if(this.surface){this.writeNode("Surface",polygon,node);}else{this.writeNode("Polygon",polygon,node);}
61600 return node;},"Envelope":function(bounds){var node=this.createElementNSPlus("gml:Envelope");this.writeNode("lowerCorner",bounds,node);this.writeNode("upperCorner",bounds,node);if(this.srsName){node.setAttribute("srsName",this.srsName);}
61601 return node;},"lowerCorner":function(bounds){var pos=(this.xy)?(bounds.left+" "+bounds.bottom):(bounds.bottom+" "+bounds.left);return this.createElementNSPlus("gml:lowerCorner",{value:pos});},"upperCorner":function(bounds){var pos=(this.xy)?(bounds.right+" "+bounds.top):(bounds.top+" "+bounds.right);return this.createElementNSPlus("gml:upperCorner",{value:pos});}},OpenLayers.Format.GML.Base.prototype.writers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.writers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.writers["wfs"]},setGeometryTypes:function(){this.geometryTypes={"OpenLayers.Geometry.Point":"Point","OpenLayers.Geometry.MultiPoint":"MultiPoint","OpenLayers.Geometry.LineString":(this.curve===true)?"Curve":"LineString","OpenLayers.Geometry.MultiLineString":(this.multiCurve===false)?"MultiLineString":"MultiCurve","OpenLayers.Geometry.Polygon":(this.surface===true)?"Surface":"Polygon","OpenLayers.Geometry.MultiPolygon":(this.multiSurface===false)?"MultiPolygon":"MultiSurface","OpenLayers.Geometry.Collection":"GeometryCollection"};},CLASS_NAME:"OpenLayers.Format.GML.v3"});OpenLayers.Format.Atom=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{atom:"http://www.w3.org/2005/Atom",georss:"http://www.georss.org/georss"},feedTitle:"untitled",defaultEntryTitle:"untitled",gmlParser:null,xy:false,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
61602 return this.parseFeatures(doc);},write:function(features){var doc;if(features instanceof Array){doc=this.createElementNSPlus("atom:feed");doc.appendChild(this.createElementNSPlus("atom:title",{value:this.feedTitle}));for(var i=0,ii=features.length;i<ii;i++){doc.appendChild(this.buildEntryNode(features[i]));}}
61603 else{doc=this.buildEntryNode(features);}
61604 return OpenLayers.Format.XML.prototype.write.apply(this,[doc]);},buildContentNode:function(content){var node=this.createElementNSPlus("atom:content",{attributes:{type:content.type||null}});if(content.src){node.setAttribute("src",content.src);}else{if(content.type=="text"||content.type==null){node.appendChild(this.createTextNode(content.value));}else if(content.type=="html"){if(typeof content.value!="string"){throw"HTML content must be in form of an escaped string";}
61605 node.appendChild(this.createTextNode(content.value));}else if(content.type=="xhtml"){node.appendChild(content.value);}else if(content.type=="xhtml"||content.type.match(/(\+|\/)xml$/)){node.appendChild(content.value);}
61606 else{node.appendChild(this.createTextNode(content.value));}}
61607 return node;},buildEntryNode:function(feature){var attrib=feature.attributes;var atomAttrib=attrib.atom||{};var entryNode=this.createElementNSPlus("atom:entry");if(atomAttrib.authors){var authors=atomAttrib.authors instanceof Array?atomAttrib.authors:[atomAttrib.authors];for(var i=0,ii=authors.length;i<ii;i++){entryNode.appendChild(this.buildPersonConstructNode("author",authors[i]));}}
61608 if(atomAttrib.categories){var categories=atomAttrib.categories instanceof Array?atomAttrib.categories:[atomAttrib.categories];var category;for(var i=0,ii=categories.length;i<ii;i++){category=categories[i];entryNode.appendChild(this.createElementNSPlus("atom:category",{attributes:{term:category.term,scheme:category.scheme||null,label:category.label||null}}));}}
61609 if(atomAttrib.content){entryNode.appendChild(this.buildContentNode(atomAttrib.content));}
61610 if(atomAttrib.contributors){var contributors=atomAttrib.contributors instanceof Array?atomAttrib.contributors:[atomAttrib.contributors];for(var i=0,ii=contributors.length;i<ii;i++){entryNode.appendChild(this.buildPersonConstructNode("contributor",contributors[i]));}}
61611 if(feature.fid){entryNode.appendChild(this.createElementNSPlus("atom:id",{value:feature.fid}));}
61612 if(atomAttrib.links){var links=atomAttrib.links instanceof Array?atomAttrib.links:[atomAttrib.links];var link;for(var i=0,ii=links.length;i<ii;i++){link=links[i];entryNode.appendChild(this.createElementNSPlus("atom:link",{attributes:{href:link.href,rel:link.rel||null,type:link.type||null,hreflang:link.hreflang||null,title:link.title||null,length:link.length||null}}));}}
61613 if(atomAttrib.published){entryNode.appendChild(this.createElementNSPlus("atom:published",{value:atomAttrib.published}));}
61614 if(atomAttrib.rights){entryNode.appendChild(this.createElementNSPlus("atom:rights",{value:atomAttrib.rights}));}
61615 if(atomAttrib.summary||attrib.description){entryNode.appendChild(this.createElementNSPlus("atom:summary",{value:atomAttrib.summary||attrib.description}));}
61616 entryNode.appendChild(this.createElementNSPlus("atom:title",{value:atomAttrib.title||attrib.title||this.defaultEntryTitle}));if(atomAttrib.updated){entryNode.appendChild(this.createElementNSPlus("atom:updated",{value:atomAttrib.updated}));}
61617 if(feature.geometry){var whereNode=this.createElementNSPlus("georss:where");whereNode.appendChild(this.buildGeometryNode(feature.geometry));entryNode.appendChild(whereNode);}
61618 return entryNode;},initGmlParser:function(){this.gmlParser=new OpenLayers.Format.GML.v3({xy:this.xy,featureNS:"http://example.com#feature",internalProjection:this.internalProjection,externalProjection:this.externalProjection});},buildGeometryNode:function(geometry){if(!this.gmlParser){this.initGmlParser();}
61619 var node=this.gmlParser.writeNode("feature:_geometry",geometry);return node.firstChild;},buildPersonConstructNode:function(name,value){var oNames=["uri","email"];var personNode=this.createElementNSPlus("atom:"+name);personNode.appendChild(this.createElementNSPlus("atom:name",{value:value.name}));for(var i=0,ii=oNames.length;i<ii;i++){if(value[oNames[i]]){personNode.appendChild(this.createElementNSPlus("atom:"+oNames[i],{value:value[oNames[i]]}));}}
61620 return personNode;},getFirstChildValue:function(node,nsuri,name,def){var value;var nodes=this.getElementsByTagNameNS(node,nsuri,name);if(nodes&&nodes.length>0){value=this.getChildValue(nodes[0],def);}else{value=def;}
61621 return value;},parseFeature:function(node){var atomAttrib={};var value=null;var nodes=null;var attval=null;var atomns=this.namespaces.atom;this.parsePersonConstructs(node,"author",atomAttrib);nodes=this.getElementsByTagNameNS(node,atomns,"category");if(nodes.length>0){atomAttrib.categories=[];}
61622 for(var i=0,ii=nodes.length;i<ii;i++){value={};value.term=nodes[i].getAttribute("term");attval=nodes[i].getAttribute("scheme");if(attval){value.scheme=attval;}
61623 attval=nodes[i].getAttribute("label");if(attval){value.label=attval;}
61624 atomAttrib.categories.push(value);}
61625 nodes=this.getElementsByTagNameNS(node,atomns,"content");if(nodes.length>0){value={};attval=nodes[0].getAttribute("type");if(attval){value.type=attval;}
61626 attval=nodes[0].getAttribute("src");if(attval){value.src=attval;}else{if(value.type=="text"||value.type=="html"||value.type==null){value.value=this.getFirstChildValue(node,atomns,"content",null);}else if(value.type=="xhtml"||value.type.match(/(\+|\/)xml$/)){value.value=this.getChildEl(nodes[0]);}else{value.value=this.getFirstChildValue(node,atomns,"content",null);}
61627 atomAttrib.content=value;}}
61628 this.parsePersonConstructs(node,"contributor",atomAttrib);atomAttrib.id=this.getFirstChildValue(node,atomns,"id",null);nodes=this.getElementsByTagNameNS(node,atomns,"link");if(nodes.length>0){atomAttrib.links=new Array(nodes.length);}
61629 var oAtts=["rel","type","hreflang","title","length"];for(var i=0,ii=nodes.length;i<ii;i++){value={};value.href=nodes[i].getAttribute("href");for(var j=0,jj=oAtts.length;j<jj;j++){attval=nodes[i].getAttribute(oAtts[j]);if(attval){value[oAtts[j]]=attval;}}
61630 atomAttrib.links[i]=value;}
61631 value=this.getFirstChildValue(node,atomns,"published",null);if(value){atomAttrib.published=value;}
61632 value=this.getFirstChildValue(node,atomns,"rights",null);if(value){atomAttrib.rights=value;}
61633 value=this.getFirstChildValue(node,atomns,"summary",null);if(value){atomAttrib.summary=value;}
61634 atomAttrib.title=this.getFirstChildValue(node,atomns,"title",null);atomAttrib.updated=this.getFirstChildValue(node,atomns,"updated",null);var featureAttrib={title:atomAttrib.title,description:atomAttrib.summary,atom:atomAttrib};var geometry=this.parseLocations(node)[0];var feature=new OpenLayers.Feature.Vector(geometry,featureAttrib);feature.fid=atomAttrib.id;return feature;},parseFeatures:function(node){var features=[];var entries=this.getElementsByTagNameNS(node,this.namespaces.atom,"entry");if(entries.length==0){entries=[node];}
61635 for(var i=0,ii=entries.length;i<ii;i++){features.push(this.parseFeature(entries[i]));}
61636 return features;},parseLocations:function(node){var georssns=this.namespaces.georss;var locations={components:[]};var where=this.getElementsByTagNameNS(node,georssns,"where");if(where&&where.length>0){if(!this.gmlParser){this.initGmlParser();}
61637 for(var i=0,ii=where.length;i<ii;i++){this.gmlParser.readChildNodes(where[i],locations);}}
61638 var components=locations.components;var point=this.getElementsByTagNameNS(node,georssns,"point");if(point&&point.length>0){for(var i=0,ii=point.length;i<ii;i++){var xy=OpenLayers.String.trim(point[i].firstChild.nodeValue).split(/\s+/);if(xy.length!=2){xy=OpenLayers.String.trim(point[i].firstChild.nodeValue).split(/\s*,\s*/);}
61639 components.push(new OpenLayers.Geometry.Point(parseFloat(xy[1]),parseFloat(xy[0])));}}
61640 var line=this.getElementsByTagNameNS(node,georssns,"line");if(line&&line.length>0){var coords;var p;var points;for(var i=0,ii=line.length;i<ii;i++){coords=OpenLayers.String.trim(line[i].firstChild.nodeValue).split(/\s+/);points=[];for(var j=0,jj=coords.length;j<jj;j+=2){p=new OpenLayers.Geometry.Point(parseFloat(coords[j+1]),parseFloat(coords[j]));points.push(p);}
61641 components.push(new OpenLayers.Geometry.LineString(points));}}
61642 var polygon=this.getElementsByTagNameNS(node,georssns,"polygon");if(polygon&&polygon.length>0){var coords;var p;var points;for(var i=0,ii=polygon.length;i<ii;i++){coords=OpenLayers.String.trim(polygon[i].firstChild.nodeValue).split(/\s+/);points=[];for(var j=0,jj=coords.length;j<jj;j+=2){p=new OpenLayers.Geometry.Point(parseFloat(coords[j+1]),parseFloat(coords[j]));points.push(p);}
61643 components.push(new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]));}}
61644 if(this.internalProjection&&this.externalProjection){for(var i=0,ii=components.length;i<ii;i++){if(components[i]){components[i].transform(this.externalProjection,this.internalProjection);}}}
61645 return components;},parsePersonConstructs:function(node,name,data){var persons=[];var atomns=this.namespaces.atom;var nodes=this.getElementsByTagNameNS(node,atomns,name);var oAtts=["uri","email"];for(var i=0,ii=nodes.length;i<ii;i++){var value={};value.name=this.getFirstChildValue(nodes[i],atomns,"name",null);for(var j=0,jj=oAtts.length;j<jj;j++){var attval=this.getFirstChildValue(nodes[i],atomns,oAtts[j],null);if(attval){value[oAtts[j]]=attval;}}
61646 persons.push(value);}
61647 if(persons.length>0){data[name+"s"]=persons;}},CLASS_NAME:"OpenLayers.Format.Atom"});OpenLayers.Format.Filter.v1_0_0=OpenLayers.Class(OpenLayers.Format.GML.v2,OpenLayers.Format.Filter.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/ogc/filter/1.0.0/filter.xsd",initialize:function(options){OpenLayers.Format.GML.v2.prototype.initialize.apply(this,[options]);},readers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsNotEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.NOT_EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLike":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LIKE});this.readChildNodes(node,filter);var wildCard=node.getAttribute("wildCard");var singleChar=node.getAttribute("singleChar");var esc=node.getAttribute("escape");filter.value2regex(wildCard,singleChar,esc);obj.filters.push(filter);}},OpenLayers.Format.Filter.v1.prototype.readers["ogc"]),"gml":OpenLayers.Format.GML.v2.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.readers["feature"]},writers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsNotEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsNotEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsLike":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLike",{attributes:{wildCard:"*",singleChar:".",escape:"!"}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.regex2value(),node);return node;},"BBOX":function(filter){var node=this.createElementNSPlus("ogc:BBOX");this.writeNode("PropertyName",filter,node);var box=this.writeNode("gml:Box",filter.value,node);if(filter.projection){box.setAttribute("srsName",filter.projection);}
61648 return node;}},OpenLayers.Format.Filter.v1.prototype.writers["ogc"]),"gml":OpenLayers.Format.GML.v2.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.writers["feature"]},writeSpatial:function(filter,name){var node=this.createElementNSPlus("ogc:"+name);this.writeNode("PropertyName",filter,node);var child;if(filter.value instanceof OpenLayers.Geometry){child=this.writeNode("feature:_geometry",filter.value).firstChild;}else{child=this.writeNode("gml:Box",filter.value);}
61649 if(filter.projection){child.setAttribute("srsName",filter.projection);}
61650 node.appendChild(child);return node;},CLASS_NAME:"OpenLayers.Format.Filter.v1_0_0"});OpenLayers.Format.Filter.v1_1_0=OpenLayers.Class(OpenLayers.Format.GML.v3,OpenLayers.Format.Filter.v1,{VERSION:"1.1.0",schemaLocation:"http://www.opengis.net/ogc/filter/1.1.0/filter.xsd",initialize:function(options){OpenLayers.Format.GML.v3.prototype.initialize.apply(this,[options]);},readers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(node,obj){var matchCase=node.getAttribute("matchCase");var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO,matchCase:!(matchCase==="false"||matchCase==="0")});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsNotEqualTo":function(node,obj){var matchCase=node.getAttribute("matchCase");var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.NOT_EQUAL_TO,matchCase:!(matchCase==="false"||matchCase==="0")});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLike":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LIKE});this.readChildNodes(node,filter);var wildCard=node.getAttribute("wildCard");var singleChar=node.getAttribute("singleChar");var esc=node.getAttribute("escapeChar");filter.value2regex(wildCard,singleChar,esc);obj.filters.push(filter);}},OpenLayers.Format.Filter.v1.prototype.readers["ogc"]),"gml":OpenLayers.Format.GML.v3.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.readers["feature"]},writers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsEqualTo",{attributes:{matchCase:filter.matchCase}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsNotEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsNotEqualTo",{attributes:{matchCase:filter.matchCase}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsLike":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLike",{attributes:{wildCard:"*",singleChar:".",escapeChar:"!"}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.regex2value(),node);return node;},"BBOX":function(filter){var node=this.createElementNSPlus("ogc:BBOX");this.writeNode("PropertyName",filter,node);var box=this.writeNode("gml:Envelope",filter.value);if(filter.projection){box.setAttribute("srsName",filter.projection);}
61651 node.appendChild(box);return node;}},OpenLayers.Format.Filter.v1.prototype.writers["ogc"]),"gml":OpenLayers.Format.GML.v3.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.writers["feature"]},writeSpatial:function(filter,name){var node=this.createElementNSPlus("ogc:"+name);this.writeNode("PropertyName",filter,node);var child;if(filter.value instanceof OpenLayers.Geometry){child=this.writeNode("feature:_geometry",filter.value).firstChild;}else{child=this.writeNode("gml:Envelope",filter.value);}
61652 if(filter.projection){child.setAttribute("srsName",filter.projection);}
61653 node.appendChild(child);return node;},CLASS_NAME:"OpenLayers.Format.Filter.v1_1_0"});OpenLayers.Format.SOSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.SOSCapabilities,{namespaces:{ows:"http://www.opengis.net/ows/1.1",sos:"http://www.opengis.net/sos/1.0",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink"},regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61654 if(data&&data.nodeType==9){data=data.documentElement;}
61655 var capabilities={};this.readNode(data,capabilities);return capabilities;},readers:{"gml":OpenLayers.Util.applyDefaults({"name":function(node,obj){obj.name=this.getChildValue(node);},"TimePeriod":function(node,obj){obj.timePeriod={};this.readChildNodes(node,obj.timePeriod);},"beginPosition":function(node,timePeriod){timePeriod.beginPosition=this.getChildValue(node);},"endPosition":function(node,timePeriod){timePeriod.endPosition=this.getChildValue(node);}},OpenLayers.Format.GML.v3.prototype.readers["gml"]),"sos":{"Capabilities":function(node,obj){this.readChildNodes(node,obj);},"Contents":function(node,obj){obj.contents={};this.readChildNodes(node,obj.contents);},"ObservationOfferingList":function(node,contents){contents.offeringList={};this.readChildNodes(node,contents.offeringList);},"ObservationOffering":function(node,offeringList){var id=this.getAttributeNS(node,this.namespaces.gml,"id");offeringList[id]={procedures:[],observedProperties:[],featureOfInterestIds:[],responseFormats:[],resultModels:[],responseModes:[]};this.readChildNodes(node,offeringList[id]);},"time":function(node,offering){offering.time={};this.readChildNodes(node,offering.time);},"procedure":function(node,offering){offering.procedures.push(this.getAttributeNS(node,this.namespaces.xlink,"href"));},"observedProperty":function(node,offering){offering.observedProperties.push(this.getAttributeNS(node,this.namespaces.xlink,"href"));},"featureOfInterest":function(node,offering){offering.featureOfInterestIds.push(this.getAttributeNS(node,this.namespaces.xlink,"href"));},"responseFormat":function(node,offering){offering.responseFormats.push(this.getChildValue(node));},"resultModel":function(node,offering){offering.resultModels.push(this.getChildValue(node));},"responseMode":function(node,offering){offering.responseModes.push(this.getChildValue(node));;}},"ows":OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers["ows"]},CLASS_NAME:"OpenLayers.Format.SOSCapabilities.v1_0_0"});OpenLayers.Format.SOSGetFeatureOfInterest=OpenLayers.Class(OpenLayers.Format.XML,{VERSION:"1.0.0",namespaces:{sos:"http://www.opengis.net/sos/1.0",gml:"http://www.opengis.net/gml",sa:"http://www.opengis.net/sampling/1.0",xsi:"http://www.w3.org/2001/XMLSchema-instance"},schemaLocation:"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd",defaultPrefix:"sos",regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61656 if(data&&data.nodeType==9){data=data.documentElement;}
61657 var info={features:[]};this.readNode(data,info);var features=[];for(var i=0,len=info.features.length;i<len;i++){var container=info.features[i];if(this.internalProjection&&this.externalProjection&&container.components[0]){container.components[0].transform(this.externalProjection,this.internalProjection);}
61658 var feature=new OpenLayers.Feature.Vector(container.components[0],container.attributes);features.push(feature);}
61659 return features;},readers:{"sa":{"SamplingPoint":function(node,obj){if(!obj.attributes){var feature={attributes:{}};obj.features.push(feature);obj=feature;}
61660 obj.attributes.id=this.getAttributeNS(node,this.namespaces.gml,"id");this.readChildNodes(node,obj);},"position":function(node,obj){this.readChildNodes(node,obj);}},"gml":OpenLayers.Util.applyDefaults({"FeatureCollection":function(node,obj){this.readChildNodes(node,obj);},"featureMember":function(node,obj){var feature={attributes:{}};obj.features.push(feature);this.readChildNodes(node,feature);},"name":function(node,obj){obj.attributes.name=this.getChildValue(node);},"pos":function(node,obj){if(!this.externalProjection){this.externalProjection=new OpenLayers.Projection(node.getAttribute("srsName"));}
61661 OpenLayers.Format.GML.v3.prototype.readers.gml.pos.apply(this,[node,obj]);}},OpenLayers.Format.GML.v3.prototype.readers.gml)},writers:{"sos":{"GetFeatureOfInterest":function(options){var node=this.createElementNSPlus("GetFeatureOfInterest",{attributes:{version:this.VERSION,service:'SOS',"xsi:schemaLocation":this.schemaLocation}});for(var i=0,len=options.fois.length;i<len;i++){this.writeNode("FeatureOfInterestId",{foi:options.fois[i]},node);}
61662 return node;},"FeatureOfInterestId":function(options){var node=this.createElementNSPlus("FeatureOfInterestId",{value:options.foi});return node;}}},CLASS_NAME:"OpenLayers.Format.SOSGetFeatureOfInterest"});OpenLayers.Format.SOSGetObservation=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ows:"http://www.opengis.net/ows",gml:"http://www.opengis.net/gml",sos:"http://www.opengis.net/sos/1.0",ogc:"http://www.opengis.net/ogc",om:"http://www.opengis.net/om/1.0",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd",defaultPrefix:"sos",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61663 if(data&&data.nodeType==9){data=data.documentElement;}
61664 var info={measurements:[]};this.readNode(data,info);return info;},write:function(options){var node=this.writeNode("sos:GetObservation",options);node.setAttribute("xmlns:om",this.namespaces.om);this.setAttributeNS(node,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},readers:{"om":{"ObservationCollection":function(node,obj){obj.id=this.getAttributeNS(node,this.namespaces.gml,"id");this.readChildNodes(node,obj);},"member":function(node,observationCollection){this.readChildNodes(node,observationCollection);},"Measurement":function(node,observationCollection){var measurement={};observationCollection.measurements.push(measurement);this.readChildNodes(node,measurement);},"samplingTime":function(node,measurement){var samplingTime={};measurement.samplingTime=samplingTime;this.readChildNodes(node,samplingTime);},"observedProperty":function(node,measurement){measurement.observedProperty=this.getAttributeNS(node,this.namespaces.xlink,"href");this.readChildNodes(node,measurement);},"procedure":function(node,measurement){measurement.procedure=this.getAttributeNS(node,this.namespaces.xlink,"href");this.readChildNodes(node,measurement);},"result":function(node,measurement){var result={};measurement.result=result;if(this.getChildValue(node)!==''){result.value=this.getChildValue(node);result.uom=node.getAttribute("uom");}else{this.readChildNodes(node,result);}}},"gml":OpenLayers.Util.applyDefaults({"TimeInstant":function(node,samplingTime){var timeInstant={};samplingTime.timeInstant=timeInstant;this.readChildNodes(node,timeInstant);},"timePosition":function(node,timeInstant){timeInstant.timePosition=this.getChildValue(node);}},OpenLayers.Format.GML.v3.prototype.readers.gml)},writers:{"sos":{"GetObservation":function(options){var node=this.createElementNSPlus("GetObservation",{attributes:{version:this.VERSION,service:'SOS'}});this.writeNode("offering",options,node);this.writeNode("eventTime",options,node);this.writeNode("procedure",options,node);this.writeNode("observedProperty",options,node);this.writeNode("responseFormat",options,node);this.writeNode("resultModel",options,node);this.writeNode("responseMode",options,node);return node;},"responseFormat":function(options){return this.createElementNSPlus("responseFormat",{value:options.responseFormat});},"procedure":function(options){return this.createElementNSPlus("procedure",{value:options.procedure});},"offering":function(options){return this.createElementNSPlus("offering",{value:options.offering});},"observedProperty":function(options){return this.createElementNSPlus("observedProperty",{value:options.observedProperty});},"eventTime":function(options){var node=this.createElementNSPlus("eventTime");if(options.eventTime==='latest'){this.writeNode("ogc:TM_Equals",options,node);}
61665 return node;},"resultModel":function(options){return this.createElementNSPlus("resultModel",{value:options.resultModel});},"responseMode":function(options){return this.createElementNSPlus("responseMode",{value:options.responseMode});}},"ogc":{"TM_Equals":function(options){var node=this.createElementNSPlus("ogc:TM_Equals");this.writeNode("ogc:PropertyName",{property:"urn:ogc:data:time:iso8601"},node);if(options.eventTime==='latest'){this.writeNode("gml:TimeInstant",{value:'latest'},node);}
61666 return node;},"PropertyName":function(options){return this.createElementNSPlus("ogc:PropertyName",{value:options.property});}},"gml":{"TimeInstant":function(options){var node=this.createElementNSPlus("gml:TimeInstant");this.writeNode("gml:timePosition",options,node);return node;},"timePosition":function(options){var node=this.createElementNSPlus("gml:timePosition",{value:options.value});return node;}}},CLASS_NAME:"OpenLayers.Format.SOSGetObservation"});OpenLayers.Format.CSWGetRecords.v2_0_2=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",csw:"http://www.opengis.net/cat/csw/2.0.2",dc:"http://purl.org/dc/elements/1.1/",dct:"http://purl.org/dc/terms/",ows:"http://www.opengis.net/ows"},defaultPrefix:"csw",version:"2.0.2",schemaLocation:"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd",requestId:null,resultType:null,outputFormat:null,outputSchema:null,startPosition:null,maxRecords:null,DistributedSearch:null,ResponseHandler:null,Query:null,regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61667 if(data&&data.nodeType==9){data=data.documentElement;}
61668 var obj={};this.readNode(data,obj);return obj;},readers:{"csw":{"GetRecordsResponse":function(node,obj){obj.records=[];this.readChildNodes(node,obj);var version=this.getAttributeNS(node,"",'version');if(version!=""){obj.version=version;}},"RequestId":function(node,obj){obj.RequestId=this.getChildValue(node);},"SearchStatus":function(node,obj){obj.SearchStatus={};var timestamp=this.getAttributeNS(node,"",'timestamp');if(timestamp!=""){obj.SearchStatus.timestamp=timestamp;}},"SearchResults":function(node,obj){this.readChildNodes(node,obj);var attrs=node.attributes;var SearchResults={};for(var i=0,len=attrs.length;i<len;++i){if((attrs[i].name=="numberOfRecordsMatched")||(attrs[i].name=="numberOfRecordsReturned")||(attrs[i].name=="nextRecord")){SearchResults[attrs[i].name]=parseInt(attrs[i].nodeValue);}else{SearchResults[attrs[i].name]=attrs[i].nodeValue;}}
61669 obj.SearchResults=SearchResults;},"SummaryRecord":function(node,obj){var record={type:"SummaryRecord"};this.readChildNodes(node,record);obj.records.push(record);},"BriefRecord":function(node,obj){var record={type:"BriefRecord"};this.readChildNodes(node,record);obj.records.push(record);},"DCMIRecord":function(node,obj){var record={type:"DCMIRecord"};this.readChildNodes(node,record);obj.records.push(record);},"Record":function(node,obj){var record={type:"Record"};this.readChildNodes(node,record);obj.records.push(record);}},"dc":{"*":function(node,obj){var name=node.localName||node.nodeName.split(":").pop();if(!(obj[name]instanceof Array)){obj[name]=new Array();}
61670 var dc_element={};var attrs=node.attributes;for(var i=0,len=attrs.length;i<len;++i){dc_element[attrs[i].name]=attrs[i].nodeValue;}
61671 dc_element.value=this.getChildValue(node);obj[name].push(dc_element);}},"dct":{"*":function(node,obj){var name=node.localName||node.nodeName.split(":").pop();if(!(obj[name]instanceof Array)){obj[name]=new Array();}
61672 obj[name].push(this.getChildValue(node));}},"ows":OpenLayers.Util.applyDefaults({"BoundingBox":function(node,obj){if(obj.bounds){obj.BoundingBox=[{crs:obj.projection,value:[obj.bounds.left,obj.bounds.bottom,obj.bounds.right,obj.bounds.top]}];delete obj.projection;delete obj.bounds;}
61673 OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers["ows"]["BoundingBox"].apply(this,arguments);}},OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers["ows"])},write:function(options){var node=this.writeNode("csw:GetRecords",options);return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},writers:{"csw":{"GetRecords":function(options){if(!options){options={};}
61674 var node=this.createElementNSPlus("csw:GetRecords",{attributes:{service:"CSW",version:this.version,requestId:options.requestId||this.requestId,resultType:options.resultType||this.resultType,outputFormat:options.outputFormat||this.outputFormat,outputSchema:options.outputSchema||this.outputSchema,startPosition:options.startPosition||this.startPosition,maxRecords:options.maxRecords||this.maxRecords}});if(options.DistributedSearch||this.DistributedSearch){this.writeNode("csw:DistributedSearch",options.DistributedSearch||this.DistributedSearch,node);}
61675 var ResponseHandler=options.ResponseHandler||this.ResponseHandler;if(ResponseHandler instanceof Array&&ResponseHandler.length>0){for(var i=0,len=ResponseHandler.length;i<len;i++){this.writeNode("csw:ResponseHandler",ResponseHandler[i],node);}}
61676 this.writeNode("Query",options.Query||this.Query,node);return node;},"DistributedSearch":function(options){var node=this.createElementNSPlus("csw:DistributedSearch",{attributes:{hopCount:options.hopCount}});return node;},"ResponseHandler":function(options){var node=this.createElementNSPlus("csw:ResponseHandler",{value:options.value});return node;},"Query":function(options){if(!options){options={};}
61677 var node=this.createElementNSPlus("csw:Query",{attributes:{typeNames:options.typeNames||"csw:Record"}});var ElementName=options.ElementName;if(ElementName instanceof Array&&ElementName.length>0){for(var i=0,len=ElementName.length;i<len;i++){this.writeNode("csw:ElementName",ElementName[i],node);}}else{this.writeNode("csw:ElementSetName",options.ElementSetName||{value:'summary'},node);}
61678 if(options.Constraint){this.writeNode("csw:Constraint",options.Constraint,node);}
61679 return node;},"ElementName":function(options){var node=this.createElementNSPlus("csw:ElementName",{value:options.value});return node;},"ElementSetName":function(options){var node=this.createElementNSPlus("csw:ElementSetName",{attributes:{typeNames:options.typeNames},value:options.value});return node;},"Constraint":function(options){var node=this.createElementNSPlus("csw:Constraint",{attributes:{version:options.version}});if(options.Filter){var format=new OpenLayers.Format.Filter({version:options.version});node.appendChild(format.write(options.Filter));}else if(options.CqlText){var child=this.createElementNSPlus("CqlText",{value:options.CqlText.value});node.appendChild(child);}
61680 return node;}}},CLASS_NAME:"OpenLayers.Format.CSWGetRecords.v2_0_2"});OpenLayers.Format.SLD.v1=OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0,{namespaces:{sld:"http://www.opengis.net/sld",ogc:"http://www.opengis.net/ogc",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"sld",schemaLocation:null,multipleSymbolizers:false,featureTypeCounter:null,defaultSymbolizer:{fillColor:"#808080",fillOpacity:1,strokeColor:"#000000",strokeOpacity:1,strokeWidth:1,strokeDashstyle:"solid",pointRadius:3,graphicName:"square"},initialize:function(options){OpenLayers.Format.Filter.v1_0_0.prototype.initialize.apply(this,[options]);},read:function(data,options){options=OpenLayers.Util.applyDefaults(options,this.options);var sld={namedLayers:options.namedLayersAsArray===true?[]:{}};this.readChildNodes(data,sld);return sld;},readers:OpenLayers.Util.applyDefaults({"sld":{"StyledLayerDescriptor":function(node,sld){sld.version=node.getAttribute("version");this.readChildNodes(node,sld);},"Name":function(node,obj){obj.name=this.getChildValue(node);},"Title":function(node,obj){obj.title=this.getChildValue(node);},"Abstract":function(node,obj){obj.description=this.getChildValue(node);},"NamedLayer":function(node,sld){var layer={userStyles:[],namedStyles:[]};this.readChildNodes(node,layer);for(var i=0,len=layer.userStyles.length;i<len;++i){layer.userStyles[i].layerName=layer.name;}
61681 if(sld.namedLayers instanceof Array){sld.namedLayers.push(layer);}else{sld.namedLayers[layer.name]=layer;}},"NamedStyle":function(node,layer){layer.namedStyles.push(this.getChildName(node.firstChild));},"UserStyle":function(node,layer){var obj={defaultsPerSymbolizer:true,rules:[]};this.featureTypeCounter=-1;this.readChildNodes(node,obj);var style;if(this.multipleSymbolizers){delete obj.defaultsPerSymbolizer;style=new OpenLayers.Style2(obj);}else{style=new OpenLayers.Style(this.defaultSymbolizer,obj);}
61682 layer.userStyles.push(style);},"IsDefault":function(node,style){if(this.getChildValue(node)=="1"){style.isDefault=true;}},"FeatureTypeStyle":function(node,style){++this.featureTypeCounter;var obj={rules:this.multipleSymbolizers?style.rules:[]};this.readChildNodes(node,obj);if(!this.multipleSymbolizers){style.rules=obj.rules;}},"Rule":function(node,obj){var config;if(this.multipleSymbolizers){config={symbolizers:[]};}
61683 var rule=new OpenLayers.Rule(config);this.readChildNodes(node,rule);obj.rules.push(rule);},"ElseFilter":function(node,rule){rule.elseFilter=true;},"MinScaleDenominator":function(node,rule){rule.minScaleDenominator=parseFloat(this.getChildValue(node));},"MaxScaleDenominator":function(node,rule){rule.maxScaleDenominator=parseFloat(this.getChildValue(node));},"TextSymbolizer":function(node,rule){var config={};this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Text(config));}else{rule.symbolizer["Text"]=OpenLayers.Util.applyDefaults(config,rule.symbolizer["Text"]);}},"Label":function(node,symbolizer){var obj={};this.readChildNodes(node,obj);if(obj.property){symbolizer.label="${"+obj.property+"}";}else{var value=this.readOgcExpression(node);if(value){symbolizer.label=value;}}},"Font":function(node,symbolizer){this.readChildNodes(node,symbolizer);},"Halo":function(node,symbolizer){var obj={};this.readChildNodes(node,obj);symbolizer.haloRadius=obj.haloRadius;symbolizer.haloColor=obj.fillColor;symbolizer.haloOpacity=obj.fillOpacity;},"Radius":function(node,symbolizer){var radius=this.readOgcExpression(node);if(radius!=null){symbolizer.haloRadius=radius;}},"RasterSymbolizer":function(node,rule){var config={};this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Raster(config));}else{rule.symbolizer["Raster"]=OpenLayers.Util.applyDefaults(config,rule.symbolizer["Raster"]);}},"Geometry":function(node,obj){obj.geometry={};this.readChildNodes(node,obj.geometry);},"ColorMap":function(node,symbolizer){symbolizer.colorMap=[];this.readChildNodes(node,symbolizer.colorMap);},"ColorMapEntry":function(node,colorMap){var q=node.getAttribute("quantity");var o=node.getAttribute("opacity");colorMap.push({color:node.getAttribute("color"),quantity:q!==null?parseFloat(q):undefined,label:node.getAttribute("label")||undefined,opacity:o!==null?parseFloat(o):undefined});},"LineSymbolizer":function(node,rule){var config={};this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Line(config));}else{rule.symbolizer["Line"]=OpenLayers.Util.applyDefaults(config,rule.symbolizer["Line"]);}},"PolygonSymbolizer":function(node,rule){var config={fill:false,stroke:false};if(!this.multipleSymbolizers){config=rule.symbolizer["Polygon"]||config;}
61684 this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Polygon(config));}else{rule.symbolizer["Polygon"]=config;}},"PointSymbolizer":function(node,rule){var config={fill:false,stroke:false,graphic:false};if(!this.multipleSymbolizers){config=rule.symbolizer["Point"]||config;}
61685 this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Point(config));}else{rule.symbolizer["Point"]=config;}},"Stroke":function(node,symbolizer){symbolizer.stroke=true;this.readChildNodes(node,symbolizer);},"Fill":function(node,symbolizer){symbolizer.fill=true;this.readChildNodes(node,symbolizer);},"CssParameter":function(node,symbolizer){var cssProperty=node.getAttribute("name");var symProperty=this.cssMap[cssProperty];if(symProperty){var value=this.readOgcExpression(node);if(value){symbolizer[symProperty]=value;}}},"Graphic":function(node,symbolizer){symbolizer.graphic=true;var graphic={};this.readChildNodes(node,graphic);var properties=["stroke","strokeColor","strokeWidth","strokeOpacity","strokeLinecap","fill","fillColor","fillOpacity","graphicName","rotation","graphicFormat"];var prop,value;for(var i=0,len=properties.length;i<len;++i){prop=properties[i];value=graphic[prop];if(value!=undefined){symbolizer[prop]=value;}}
61686 if(graphic.opacity!=undefined){symbolizer.graphicOpacity=graphic.opacity;}
61687 if(graphic.size!=undefined){symbolizer.pointRadius=graphic.size/2;}
61688 if(graphic.href!=undefined){symbolizer.externalGraphic=graphic.href;}
61689 if(graphic.rotation!=undefined){symbolizer.rotation=graphic.rotation;}},"ExternalGraphic":function(node,graphic){this.readChildNodes(node,graphic);},"Mark":function(node,graphic){this.readChildNodes(node,graphic);},"WellKnownName":function(node,graphic){graphic.graphicName=this.getChildValue(node);},"Opacity":function(node,obj){var opacity=this.readOgcExpression(node);if(opacity){obj.opacity=opacity;}},"Size":function(node,obj){var size=this.readOgcExpression(node);if(size){obj.size=size;}},"Rotation":function(node,obj){var rotation=this.readOgcExpression(node);if(rotation){obj.rotation=rotation;}},"OnlineResource":function(node,obj){obj.href=this.getAttributeNS(node,this.namespaces.xlink,"href");},"Format":function(node,graphic){graphic.graphicFormat=this.getChildValue(node);}}},OpenLayers.Format.Filter.v1_0_0.prototype.readers),cssMap:{"stroke":"strokeColor","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","stroke-linecap":"strokeLinecap","stroke-dasharray":"strokeDashstyle","fill":"fillColor","fill-opacity":"fillOpacity","font-family":"fontFamily","font-size":"fontSize","font-weight":"fontWeight","font-style":"fontStyle"},getCssProperty:function(sym){var css=null;for(var prop in this.cssMap){if(this.cssMap[prop]==sym){css=prop;break;}}
61690 return css;},getGraphicFormat:function(href){var format,regex;for(var key in this.graphicFormats){if(this.graphicFormats[key].test(href)){format=key;break;}}
61691 return format||this.defautlGraphicFormat;},defaultGraphicFormat:"image/png",graphicFormats:{"image/jpeg":/\.jpe?g$/i,"image/gif":/\.gif$/i,"image/png":/\.png$/i},write:function(sld){return this.writers.sld.StyledLayerDescriptor.apply(this,[sld]);},writers:OpenLayers.Util.applyDefaults({"sld":{"StyledLayerDescriptor":function(sld){var root=this.createElementNSPlus("sld:StyledLayerDescriptor",{attributes:{"version":this.VERSION,"xsi:schemaLocation":this.schemaLocation}});root.setAttribute("xmlns:ogc",this.namespaces.ogc);root.setAttribute("xmlns:gml",this.namespaces.gml);if(sld.name){this.writeNode("Name",sld.name,root);}
61692 if(sld.title){this.writeNode("Title",sld.title,root);}
61693 if(sld.description){this.writeNode("Abstract",sld.description,root);}
61694 if(sld.namedLayers instanceof Array){for(var i=0,len=sld.namedLayers.length;i<len;++i){this.writeNode("NamedLayer",sld.namedLayers[i],root);}}else{for(var name in sld.namedLayers){this.writeNode("NamedLayer",sld.namedLayers[name],root);}}
61695 return root;},"Name":function(name){return this.createElementNSPlus("sld:Name",{value:name});},"Title":function(title){return this.createElementNSPlus("sld:Title",{value:title});},"Abstract":function(description){return this.createElementNSPlus("sld:Abstract",{value:description});},"NamedLayer":function(layer){var node=this.createElementNSPlus("sld:NamedLayer");this.writeNode("Name",layer.name,node);if(layer.namedStyles){for(var i=0,len=layer.namedStyles.length;i<len;++i){this.writeNode("NamedStyle",layer.namedStyles[i],node);}}
61696 if(layer.userStyles){for(var i=0,len=layer.userStyles.length;i<len;++i){this.writeNode("UserStyle",layer.userStyles[i],node);}}
61697 return node;},"NamedStyle":function(name){var node=this.createElementNSPlus("sld:NamedStyle");this.writeNode("Name",name,node);return node;},"UserStyle":function(style){var node=this.createElementNSPlus("sld:UserStyle");if(style.name){this.writeNode("Name",style.name,node);}
61698 if(style.title){this.writeNode("Title",style.title,node);}
61699 if(style.description){this.writeNode("Abstract",style.description,node);}
61700 if(style.isDefault){this.writeNode("IsDefault",style.isDefault,node);}
61701 if(this.multipleSymbolizers&&style.rules){var rulesByZ={0:[]};var zValues=[0];var rule,ruleMap,symbolizer,zIndex,clone;for(var i=0,ii=style.rules.length;i<ii;++i){rule=style.rules[i];if(rule.symbolizers){ruleMap={};for(var j=0,jj=rule.symbolizers.length;j<jj;++j){symbolizer=rule.symbolizers[j];zIndex=symbolizer.zIndex;if(!(zIndex in ruleMap)){clone=rule.clone();clone.symbolizers=[];ruleMap[zIndex]=clone;}
61702 ruleMap[zIndex].symbolizers.push(symbolizer.clone());}
61703 for(zIndex in ruleMap){if(!(zIndex in rulesByZ)){zValues.push(zIndex);rulesByZ[zIndex]=[];}
61704 rulesByZ[zIndex].push(ruleMap[zIndex]);}}else{rulesByZ[0].push(rule.clone());}}
61705 zValues.sort();var rules;for(var i=0,ii=zValues.length;i<ii;++i){rules=rulesByZ[zValues[i]];if(rules.length>0){clone=style.clone();clone.rules=rulesByZ[zValues[i]];this.writeNode("FeatureTypeStyle",clone,node);}}}else{this.writeNode("FeatureTypeStyle",style,node);}
61706 return node;},"IsDefault":function(bool){return this.createElementNSPlus("sld:IsDefault",{value:(bool)?"1":"0"});},"FeatureTypeStyle":function(style){var node=this.createElementNSPlus("sld:FeatureTypeStyle");for(var i=0,len=style.rules.length;i<len;++i){this.writeNode("Rule",style.rules[i],node);}
61707 return node;},"Rule":function(rule){var node=this.createElementNSPlus("sld:Rule");if(rule.name){this.writeNode("Name",rule.name,node);}
61708 if(rule.title){this.writeNode("Title",rule.title,node);}
61709 if(rule.description){this.writeNode("Abstract",rule.description,node);}
61710 if(rule.elseFilter){this.writeNode("ElseFilter",null,node);}else if(rule.filter){this.writeNode("ogc:Filter",rule.filter,node);}
61711 if(rule.minScaleDenominator!=undefined){this.writeNode("MinScaleDenominator",rule.minScaleDenominator,node);}
61712 if(rule.maxScaleDenominator!=undefined){this.writeNode("MaxScaleDenominator",rule.maxScaleDenominator,node);}
61713 var type,symbolizer;if(this.multipleSymbolizers&&rule.symbolizers){var symbolizer;for(var i=0,ii=rule.symbolizers.length;i<ii;++i){symbolizer=rule.symbolizers[i];type=symbolizer.CLASS_NAME.split(".").pop();this.writeNode(type+"Symbolizer",symbolizer,node);}}else{var types=OpenLayers.Style.SYMBOLIZER_PREFIXES;for(var i=0,len=types.length;i<len;++i){type=types[i];symbolizer=rule.symbolizer[type];if(symbolizer){this.writeNode(type+"Symbolizer",symbolizer,node);}}}
61714 return node;},"ElseFilter":function(){return this.createElementNSPlus("sld:ElseFilter");},"MinScaleDenominator":function(scale){return this.createElementNSPlus("sld:MinScaleDenominator",{value:scale});},"MaxScaleDenominator":function(scale){return this.createElementNSPlus("sld:MaxScaleDenominator",{value:scale});},"LineSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:LineSymbolizer");this.writeNode("Stroke",symbolizer,node);return node;},"Stroke":function(symbolizer){var node=this.createElementNSPlus("sld:Stroke");if(symbolizer.strokeColor!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeColor"},node);}
61715 if(symbolizer.strokeOpacity!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeOpacity"},node);}
61716 if(symbolizer.strokeWidth!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeWidth"},node);}
61717 if(symbolizer.strokeDashstyle!=undefined&&symbolizer.strokeDashstyle!=="solid"){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeDashstyle"},node);}
61718 if(symbolizer.strokeLinecap!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeLinecap"},node);}
61719 return node;},"CssParameter":function(obj){return this.createElementNSPlus("sld:CssParameter",{attributes:{name:this.getCssProperty(obj.key)},value:obj.symbolizer[obj.key]});},"TextSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:TextSymbolizer");if(symbolizer.label!=null){this.writeNode("Label",symbolizer.label,node);}
61720 if(symbolizer.fontFamily!=null||symbolizer.fontSize!=null||symbolizer.fontWeight!=null||symbolizer.fontStyle!=null){this.writeNode("Font",symbolizer,node);}
61721 if(symbolizer.haloRadius!=null||symbolizer.haloColor!=null||symbolizer.haloOpacity!=null){this.writeNode("Halo",symbolizer,node);}
61722 if(symbolizer.fillColor!=null||symbolizer.fillOpacity!=null){this.writeNode("Fill",symbolizer,node);}
61723 return node;},"Font":function(symbolizer){var node=this.createElementNSPlus("sld:Font");if(symbolizer.fontFamily){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontFamily"},node);}
61724 if(symbolizer.fontSize){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontSize"},node);}
61725 if(symbolizer.fontWeight){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontWeight"},node);}
61726 if(symbolizer.fontStyle){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontStyle"},node);}
61727 return node;},"Label":function(label){var node=this.createElementNSPlus("sld:Label");var tokens=label.split("${");node.appendChild(this.createTextNode(tokens[0]));var item,last;for(var i=1,len=tokens.length;i<len;i++){item=tokens[i];last=item.indexOf("}");if(last>0){this.writeNode("ogc:PropertyName",{property:item.substring(0,last)},node);node.appendChild(this.createTextNode(item.substring(++last)));}else{node.appendChild(this.createTextNode("${"+item));}}
61728 return node;},"Halo":function(symbolizer){var node=this.createElementNSPlus("sld:Halo");if(symbolizer.haloRadius){this.writeNode("Radius",symbolizer.haloRadius,node);}
61729 if(symbolizer.haloColor||symbolizer.haloOpacity){this.writeNode("Fill",{fillColor:symbolizer.haloColor,fillOpacity:symbolizer.haloOpacity},node);}
61730 return node;},"Radius":function(value){return this.createElementNSPlus("sld:Radius",{value:value});},"RasterSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:RasterSymbolizer");if(symbolizer.geometry){this.writeNode("Geometry",symbolizer.geometry,node);}
61731 if(symbolizer.opacity){this.writeNode("Opacity",symbolizer.opacity,node);}
61732 if(symbolizer.colorMap){this.writeNode("ColorMap",symbolizer.colorMap,node);}
61733 return node;},"Geometry":function(geometry){var node=this.createElementNSPlus("sld:Geometry");if(geometry.property){this.writeNode("ogc:PropertyName",geometry,node);}
61734 return node;},"ColorMap":function(colorMap){var node=this.createElementNSPlus("sld:ColorMap");for(var i=0,len=colorMap.length;i<len;++i){this.writeNode("ColorMapEntry",colorMap[i],node);}
61735 return node;},"ColorMapEntry":function(colorMapEntry){var node=this.createElementNSPlus("sld:ColorMapEntry");var a=colorMapEntry;node.setAttribute("color",a.color);a.opacity!==undefined&&node.setAttribute("opacity",parseFloat(a.opacity));a.quantity!==undefined&&node.setAttribute("quantity",parseFloat(a.quantity));a.label!==undefined&&node.setAttribute("label",a.label);return node;},"PolygonSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:PolygonSymbolizer");if(symbolizer.fill!==false){this.writeNode("Fill",symbolizer,node);}
61736 if(symbolizer.stroke!==false){this.writeNode("Stroke",symbolizer,node);}
61737 return node;},"Fill":function(symbolizer){var node=this.createElementNSPlus("sld:Fill");if(symbolizer.fillColor){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fillColor"},node);}
61738 if(symbolizer.fillOpacity!=null){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fillOpacity"},node);}
61739 return node;},"PointSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:PointSymbolizer");this.writeNode("Graphic",symbolizer,node);return node;},"Graphic":function(symbolizer){var node=this.createElementNSPlus("sld:Graphic");if(symbolizer.externalGraphic!=undefined){this.writeNode("ExternalGraphic",symbolizer,node);}else{this.writeNode("Mark",symbolizer,node);}
61740 if(symbolizer.graphicOpacity!=undefined){this.writeNode("Opacity",symbolizer.graphicOpacity,node);}
61741 if(symbolizer.pointRadius!=undefined){this.writeNode("Size",symbolizer.pointRadius*2,node);}
61742 if(symbolizer.rotation!=undefined){this.writeNode("Rotation",symbolizer.rotation,node);}
61743 return node;},"ExternalGraphic":function(symbolizer){var node=this.createElementNSPlus("sld:ExternalGraphic");this.writeNode("OnlineResource",symbolizer.externalGraphic,node);var format=symbolizer.graphicFormat||this.getGraphicFormat(symbolizer.externalGraphic);this.writeNode("Format",format,node);return node;},"Mark":function(symbolizer){var node=this.createElementNSPlus("sld:Mark");if(symbolizer.graphicName){this.writeNode("WellKnownName",symbolizer.graphicName,node);}
61744 if(symbolizer.fill!==false){this.writeNode("Fill",symbolizer,node);}
61745 if(symbolizer.stroke!==false){this.writeNode("Stroke",symbolizer,node);}
61746 return node;},"WellKnownName":function(name){return this.createElementNSPlus("sld:WellKnownName",{value:name});},"Opacity":function(value){return this.createElementNSPlus("sld:Opacity",{value:value});},"Size":function(value){return this.createElementNSPlus("sld:Size",{value:value});},"Rotation":function(value){return this.createElementNSPlus("sld:Rotation",{value:value});},"OnlineResource":function(href){return this.createElementNSPlus("sld:OnlineResource",{attributes:{"xlink:type":"simple","xlink:href":href}});},"Format":function(format){return this.createElementNSPlus("sld:Format",{value:format});}}},OpenLayers.Format.Filter.v1_0_0.prototype.writers),CLASS_NAME:"OpenLayers.Format.SLD.v1"});OpenLayers.Format.WFST.v1_0_0=OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0,OpenLayers.Format.WFST.v1,{version:"1.0.0",srsNameInQuery:false,schemaLocations:{"wfs":"http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd"},initialize:function(options){OpenLayers.Format.Filter.v1_0_0.prototype.initialize.apply(this,[options]);OpenLayers.Format.WFST.v1.prototype.initialize.apply(this,[options]);},readers:{"wfs":OpenLayers.Util.applyDefaults({"WFS_TransactionResponse":function(node,obj){obj.insertIds=[];obj.success=false;this.readChildNodes(node,obj);},"InsertResult":function(node,container){var obj={fids:[]};this.readChildNodes(node,obj);container.insertIds.push(obj.fids[0]);},"TransactionResult":function(node,obj){this.readChildNodes(node,obj);},"Status":function(node,obj){this.readChildNodes(node,obj);},"SUCCESS":function(node,obj){obj.success=true;}},OpenLayers.Format.WFST.v1.prototype.readers["wfs"]),"gml":OpenLayers.Format.GML.v2.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.readers["feature"],"ogc":OpenLayers.Format.Filter.v1_0_0.prototype.readers["ogc"]},writers:{"wfs":OpenLayers.Util.applyDefaults({"Query":function(options){options=OpenLayers.Util.extend({featureNS:this.featureNS,featurePrefix:this.featurePrefix,featureType:this.featureType,srsName:this.srsName,srsNameInQuery:this.srsNameInQuery},options);var node=this.createElementNSPlus("wfs:Query",{attributes:{typeName:(options.featureNS?options.featurePrefix+":":"")+
61747 options.featureType}});if(options.srsNameInQuery&&options.srsName){node.setAttribute("srsName",options.srsName);}
61748 if(options.featureNS){node.setAttribute("xmlns:"+options.featurePrefix,options.featureNS);}
61749 if(options.propertyNames){for(var i=0,len=options.propertyNames.length;i<len;i++){this.writeNode("ogc:PropertyName",{property:options.propertyNames[i]},node);}}
61750 if(options.filter){this.setFilterProperty(options.filter);this.writeNode("ogc:Filter",options.filter,node);}
61751 return node;}},OpenLayers.Format.WFST.v1.prototype.writers["wfs"]),"gml":OpenLayers.Format.GML.v2.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.writers["feature"],"ogc":OpenLayers.Format.Filter.v1_0_0.prototype.writers["ogc"]},CLASS_NAME:"OpenLayers.Format.WFST.v1_0_0"});OpenLayers.Format.WFST.v1_1_0=OpenLayers.Class(OpenLayers.Format.Filter.v1_1_0,OpenLayers.Format.WFST.v1,{version:"1.1.0",schemaLocations:{"wfs":"http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"},initialize:function(options){OpenLayers.Format.Filter.v1_1_0.prototype.initialize.apply(this,[options]);OpenLayers.Format.WFST.v1.prototype.initialize.apply(this,[options]);},readers:{"wfs":OpenLayers.Util.applyDefaults({"FeatureCollection":function(node,obj){obj.numberOfFeatures=parseInt(node.getAttribute("numberOfFeatures"));OpenLayers.Format.WFST.v1.prototype.readers["wfs"]["FeatureCollection"].apply(this,arguments);},"TransactionResponse":function(node,obj){obj.insertIds=[];obj.success=false;this.readChildNodes(node,obj);},"TransactionSummary":function(node,obj){obj.success=true;},"InsertResults":function(node,obj){this.readChildNodes(node,obj);},"Feature":function(node,container){var obj={fids:[]};this.readChildNodes(node,obj);container.insertIds.push(obj.fids[0]);}},OpenLayers.Format.WFST.v1.prototype.readers["wfs"]),"gml":OpenLayers.Format.GML.v3.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.readers["feature"],"ogc":OpenLayers.Format.Filter.v1_1_0.prototype.readers["ogc"]},writers:{"wfs":OpenLayers.Util.applyDefaults({"GetFeature":function(options){var node=OpenLayers.Format.WFST.v1.prototype.writers["wfs"]["GetFeature"].apply(this,arguments);options&&options.resultType&&this.setAttributes(node,{resultType:options.resultType});return node;},"Query":function(options){options=OpenLayers.Util.extend({featureNS:this.featureNS,featurePrefix:this.featurePrefix,featureType:this.featureType,srsName:this.srsName},options);var node=this.createElementNSPlus("wfs:Query",{attributes:{typeName:(options.featureNS?options.featurePrefix+":":"")+
61752 options.featureType,srsName:options.srsName}});if(options.featureNS){node.setAttribute("xmlns:"+options.featurePrefix,options.featureNS);}
61753 if(options.propertyNames){for(var i=0,len=options.propertyNames.length;i<len;i++){this.writeNode("wfs:PropertyName",{property:options.propertyNames[i]},node);}}
61754 if(options.filter){this.setFilterProperty(options.filter);this.writeNode("ogc:Filter",options.filter,node);}
61755 return node;},"PropertyName":function(obj){return this.createElementNSPlus("wfs:PropertyName",{value:obj.property});}},OpenLayers.Format.WFST.v1.prototype.writers["wfs"]),"gml":OpenLayers.Format.GML.v3.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.writers["feature"],"ogc":OpenLayers.Format.Filter.v1_1_0.prototype.writers["ogc"]},CLASS_NAME:"OpenLayers.Format.WFST.v1_1_0"});OpenLayers.Protocol.SOS.v1_0_0=OpenLayers.Class(OpenLayers.Protocol,{fois:null,formatOptions:null,initialize:function(options){OpenLayers.Protocol.prototype.initialize.apply(this,[options]);if(!options.format){this.format=new OpenLayers.Format.SOSGetFeatureOfInterest(this.formatOptions);}},destroy:function(){if(this.options&&!this.options.format){this.format.destroy();}
61756 this.format=null;OpenLayers.Protocol.prototype.destroy.apply(this);},read:function(options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options||{});var response=new OpenLayers.Protocol.Response({requestType:"read"});var format=this.format;var data=OpenLayers.Format.XML.prototype.write.apply(format,[format.writeNode("sos:GetFeatureOfInterest",{fois:this.fois})]);response.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleRead,response,options),data:data});return response;},handleRead:function(response,options){if(options.callback){var request=response.priv;if(request.status>=200&&request.status<300){response.features=this.parseFeatures(request);response.code=OpenLayers.Protocol.Response.SUCCESS;}else{response.code=OpenLayers.Protocol.Response.FAILURE;}
61757 options.callback.call(options.scope,response);}},parseFeatures:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
61758 if(!doc||doc.length<=0){return null;}
61759 return this.format.read(doc);},CLASS_NAME:"OpenLayers.Protocol.SOS.v1_0_0"});OpenLayers.Format.SLD.v1_0_0=OpenLayers.Class(OpenLayers.Format.SLD.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd",initialize:function(options){OpenLayers.Format.SLD.v1.prototype.initialize.apply(this,[options]);},CLASS_NAME:"OpenLayers.Format.SLD.v1_0_0"});OpenLayers.Protocol.WFS.v1_0_0=OpenLayers.Class(OpenLayers.Protocol.WFS.v1,{version:"1.0.0",CLASS_NAME:"OpenLayers.Protocol.WFS.v1_0_0"});OpenLayers.Protocol.WFS.v1_1_0=OpenLayers.Class(OpenLayers.Protocol.WFS.v1,{version:"1.1.0",CLASS_NAME:"OpenLayers.Protocol.WFS.v1_1_0"});OpenLayers.Format.OWSContext.v0_3_1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{owc:"http://www.opengis.net/ows-context",gml:"http://www.opengis.net/gml",kml:"http://www.opengis.net/kml/2.2",ogc:"http://www.opengis.net/ogc",ows:"http://www.opengis.net/ows",sld:"http://www.opengis.net/sld",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},VERSION:"0.3.1",schemaLocation:"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd",defaultPrefix:"owc",extractAttributes:true,xy:true,regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},featureNS:"http://mapserver.gis.umn.edu/mapserver",featureType:'vector',geometryName:'geometry',nestingLayerLookup:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);OpenLayers.Format.GML.v2.prototype.setGeometryTypes.call(this);},setNestingPath:function(l){if(l.layersContext){for(var i=0,len=l.layersContext.length;i<len;i++){var layerContext=l.layersContext[i];var nPath=[];var nTitle=l.title||"";if(l.metadata&&l.metadata.nestingPath){nPath=l.metadata.nestingPath.slice();}
61760 if(nTitle!=""){nPath.push(nTitle);}
61761 layerContext.metadata.nestingPath=nPath;if(layerContext.layersContext){this.setNestingPath(layerContext);}}}},decomposeNestingPath:function(nPath){var a=[];if(nPath instanceof Array){while(nPath.length>0){a.push(nPath.slice());nPath.pop();}
61762 a.reverse();}
61763 return a;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61764 if(data&&data.nodeType==9){data=data.documentElement;}
61765 var context={};this.readNode(data,context);this.setNestingPath({layersContext:context.layersContext});var layers=[];this.processLayer(layers,context);delete context.layersContext;context.layersContext=layers;return context;},processLayer:function(layerArray,layer){if(layer.layersContext){for(var i=0,len=layer.layersContext.length;i<len;i++){var l=layer.layersContext[i];layerArray.push(l);if(l.layersContext){this.processLayer(layerArray,l);}}}},write:function(context,options){var name="OWSContext";this.nestingLayerLookup={};options=options||{};OpenLayers.Util.applyDefaults(options,context);var root=this.writeNode(name,options);this.nestingLayerLookup=null;this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},readers:{"kml":{"Document":function(node,obj){obj.features=new OpenLayers.Format.KML({kmlns:this.namespaces.kml,extractStyles:true}).read(node);}},"owc":{"OWSContext":function(node,obj){this.readChildNodes(node,obj);},"General":function(node,obj){this.readChildNodes(node,obj);},"ResourceList":function(node,obj){this.readChildNodes(node,obj);},"Layer":function(node,obj){var layerContext={metadata:{},visibility:(node.getAttribute("hidden")!="1"),queryable:(node.getAttribute("queryable")=="1"),opacity:((node.getAttribute("opacity")!=null)?parseFloat(node.getAttribute("opacity")):null),name:node.getAttribute("name"),categoryLayer:(node.getAttribute("name")==null),formats:[],styles:[]};if(!obj.layersContext){obj.layersContext=[];}
61766 obj.layersContext.push(layerContext);this.readChildNodes(node,layerContext);},"InlineGeometry":function(node,obj){obj.features=[];var elements=this.getElementsByTagNameNS(node,this.namespaces.gml,"featureMember");var el;if(elements.length>=1){el=elements[0];}
61767 if(el&&el.firstChild){var featurenode=(el.firstChild.nextSibling)?el.firstChild.nextSibling:el.firstChild;this.setNamespace("feature",featurenode.namespaceURI);this.featureType=featurenode.localName||featurenode.nodeName.split(":").pop();this.readChildNodes(node,obj);}},"Server":function(node,obj){if((!obj.service&&!obj.version)||(obj.service!=OpenLayers.Format.Context.serviceTypes.WMS)){obj.service=node.getAttribute("service");obj.version=node.getAttribute("version");this.readChildNodes(node,obj);}},"Name":function(node,obj){obj.name=this.getChildValue(node);this.readChildNodes(node,obj);},"Title":function(node,obj){obj.title=this.getChildValue(node);this.readChildNodes(node,obj);},"StyleList":function(node,obj){this.readChildNodes(node,obj.styles);},"Style":function(node,obj){var style={};obj.push(style);this.readChildNodes(node,style);},"LegendURL":function(node,obj){var legend={};obj.legend=legend;this.readChildNodes(node,legend);},"OnlineResource":function(node,obj){obj.url=this.getAttributeNS(node,this.namespaces.xlink,"href");this.readChildNodes(node,obj);}},"ows":OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers.ows,"gml":OpenLayers.Format.GML.v2.prototype.readers.gml,"sld":OpenLayers.Format.SLD.v1_0_0.prototype.readers.sld,"feature":OpenLayers.Format.GML.v2.prototype.readers.feature},writers:{"owc":{"OWSContext":function(options){var node=this.createElementNSPlus("OWSContext",{attributes:{version:this.VERSION,id:options.id||OpenLayers.Util.createUniqueID("OpenLayers_OWSContext_")}});this.writeNode("General",options,node);this.writeNode("ResourceList",options,node);return node;},"General":function(options){var node=this.createElementNSPlus("General");this.writeNode("ows:BoundingBox",options,node);this.writeNode("ows:Title",options.title||'OpenLayers OWSContext',node);return node;},"ResourceList":function(options){var node=this.createElementNSPlus("ResourceList");for(var i=0,len=options.layers.length;i<len;i++){var layer=options.layers[i];var decomposedPath=this.decomposeNestingPath(layer.metadata.nestingPath);this.writeNode("_Layer",{layer:layer,subPaths:decomposedPath},node);}
61768 return node;},"Server":function(options){var node=this.createElementNSPlus("Server",{attributes:{version:options.version,service:options.service}});this.writeNode("OnlineResource",options,node);return node;},"OnlineResource":function(options){var node=this.createElementNSPlus("OnlineResource",{attributes:{"xlink:href":options.url}});return node;},"InlineGeometry":function(layer){var node=this.createElementNSPlus("InlineGeometry");this.writeNode("gml:boundedBy",layer.getDataExtent(),node);for(var i=0,len=layer.features.length;i<len;i++){this.writeNode("gml:featureMember",layer.features[i],node);}
61769 return node;},"StyleList":function(styles){var node=this.createElementNSPlus("StyleList");for(var i=0,len=styles.length;i<len;i++){this.writeNode("Style",styles[i],node);}
61770 return node;},"Style":function(style){var node=this.createElementNSPlus("Style");this.writeNode("Name",style,node);this.writeNode("Title",style,node);this.writeNode("LegendURL",style,node);return node;},"Name":function(obj){var node=this.createElementNSPlus("Name",{value:obj.name});return node;},"Title":function(obj){var node=this.createElementNSPlus("Title",{value:obj.title});return node;},"LegendURL":function(style){var node=this.createElementNSPlus("LegendURL");this.writeNode("OnlineResource",style.legend,node);return node;},"_WMS":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:layer.params.LAYERS,queryable:layer.queryable?"1":"0",hidden:layer.visibility?"0":"1",opacity:layer.opacity?layer.opacity:null}});this.writeNode("ows:Title",layer.name,node);this.writeNode("ows:OutputFormat",layer.params.FORMAT,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.WMS,version:layer.params.VERSION,url:layer.url},node);if(layer.metadata.styles&&layer.metadata.styles.length>0){this.writeNode("StyleList",layer.metadata.styles,node);}
61771 return node;},"_Layer":function(options){var layer,subPaths,node,title;layer=options.layer;subPaths=options.subPaths;node=null;title=null;if(subPaths.length>0){var path=subPaths[0].join("/");var index=path.lastIndexOf("/");node=this.nestingLayerLookup[path];title=(index>0)?path.substring(index+1,path.length):path;if(!node){node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",title,node);this.nestingLayerLookup[path]=node;}
61772 options.subPaths.shift();this.writeNode("_Layer",options,node);return node;}else{if(layer instanceof OpenLayers.Layer.WMS){node=this.writeNode("_WMS",layer);}else if(layer instanceof OpenLayers.Layer.Vector){if(layer.protocol instanceof OpenLayers.Protocol.WFS.v1){node=this.writeNode("_WFS",layer);}else if(layer.protocol instanceof OpenLayers.Protocol.HTTP){if(layer.protocol.format instanceof OpenLayers.Format.GML){layer.protocol.format.version="2.1.2";node=this.writeNode("_GML",layer);}else if(layer.protocol.format instanceof OpenLayers.Format.KML){layer.protocol.format.version="2.2";node=this.writeNode("_KML",layer);}}else{this.setNamespace("feature",this.featureNS);node=this.writeNode("_InlineGeometry",layer);}}
61773 if(layer.options.maxScale){this.writeNode("sld:MinScaleDenominator",layer.options.maxScale,node);}
61774 if(layer.options.minScale){this.writeNode("sld:MaxScaleDenominator",layer.options.minScale,node);}
61775 this.nestingLayerLookup[layer.name]=node;return node;}},"_WFS":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:layer.protocol.featurePrefix+":"+layer.protocol.featureType,hidden:layer.visibility?"0":"1"}});this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.WFS,version:layer.protocol.version,url:layer.protocol.url},node);return node;},"_InlineGeometry":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:this.featureType,hidden:layer.visibility?"0":"1"}});this.writeNode("ows:Title",layer.name,node);this.writeNode("InlineGeometry",layer,node);return node;},"_GML":function(layer){var node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.GML,url:layer.protocol.url,version:layer.protocol.format.version},node);return node;},"_KML":function(layer){var node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.KML,version:layer.protocol.format.version,url:layer.protocol.url},node);return node;}},"gml":OpenLayers.Util.applyDefaults({"boundedBy":function(bounds){var node=this.createElementNSPlus("gml:boundedBy");this.writeNode("gml:Box",bounds,node);return node;}},OpenLayers.Format.GML.v2.prototype.writers.gml),"ows":OpenLayers.Format.OWSCommon.v1_0_0.prototype.writers.ows,"sld":OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld,"feature":OpenLayers.Format.GML.v2.prototype.writers.feature},CLASS_NAME:"OpenLayers.Format.OWSContext.v0_3_1"});
61776 (function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new w(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VERSION="1.4.4";var A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(r,n,u,i)}),e)};var O="Reduce of empty array with no initial value";w.reduce=w.foldl=w.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},w.reduceRight=w.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},w.find=w.detect=function(n,t,r){var e;return E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},w.filter=w.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=function(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};w.contains=w.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:E(n,function(n){return n===t})},w.invoke=function(n,t){var r=o.call(arguments,2),e=w.isFunction(t);return w.map(n,function(n){return(e?t:n[t]).apply(n,r)})},w.pluck=function(n,t){return w.map(n,function(n){return n[t]})},w.where=function(n,t,r){return w.isEmpty(t)?r?null:[]:w[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},w.findWhere=function(n,t){return w.where(n,t,!0)},w.max=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w.min=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var k=function(n){return w.isFunction(n)?n:function(t){return t[n]}};w.sortBy=function(n,t,r){var e=k(t);return w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index<t.index?-1:1}),"value")};var F=function(n,t,r,e){var u={},i=k(t||w.identity);return A(n,function(t,a){var o=i.call(r,t,a,n);e(u,o,t)}),u};w.groupBy=function(n,t,r){return F(n,t,r,function(n,t,r){(w.has(n,t)?n[t]:n[t]=[]).push(r)})},w.countBy=function(n,t,r){return F(n,t,r,function(n,t){w.has(n,t)||(n[t]=0),n[t]++})},w.sortedIndex=function(n,t,r,e){r=null==r?w.identity:k(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return i},w.toArray=function(n){return n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values(n):[]},w.size=function(n){return null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail=w.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},w.compact=function(n){return w.filter(n,w.identity)};var R=function(n,t,r){return A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flatten=function(n,t){return R(n,t,[])},w.without=function(n){return w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.isFunction(t)&&(e=r,r=t,t=!1);var u=r?w.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.push(n[e]))}),i},w.union=function(){return w.uniq(c.apply(e,arguments))},w.intersection=function(n){var t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return w.every(t,function(t){return w.indexOf(t,n)>=0})})},w.difference=function(n){var t=c.apply(e,o.call(arguments,1));return w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[e]=w.pluck(n,""+e);return r},w.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},w.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},w.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return i},w.bind=function(n,t){if(n.bind===j&&j)return j.apply(n,o.call(arguments,1));var r=o.call(arguments,2);return function(){return n.apply(t,r.concat(o.call(arguments)))}},w.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},w.bindAll=function(n){var t=o.call(arguments,1);return 0===t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var e=t.apply(this,arguments);return w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},w.defer=function(n){return w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return function(){var c=new Date,l=t-(c-a);return r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return function(){var i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return t},w.values=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return t},w.functions=w.methods=function(n){var t=[];for(var r in n)w.isFunction(n[r])&&t.push(r);return t.sort()},w.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},w.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},w.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObject(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return t(n),n};var I=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==t+"";case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=I(n[a],t[a],r,e)););}else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&I(n[s],t[s],r,e))))break;if(o){for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return r.pop(),e.pop(),o};w.isEqual=function(n,t){return I(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w.isString(n))return 0===n.length;for(var t in n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!==n.nodeType)},w.isArray=x||function(n){return"[object Array]"==l.call(n)},w.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){w["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n||!w.has(n,"callee"))}),"function"!=typeof/./&&(w.isFunction=function(n){return"function"==typeof n}),w.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},w.isNull=function(n){return null===n},w.isUndefined=function(n){return n===void 0},w.has=function(n,t){return f.call(n,t)},w.noConflict=function(){return n._=t,this},w.identity=function(n){return n},w.times=function(n,t,r){for(var e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return e},w.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var M={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};M.unescape=w.invert(M.escape);var S={escape:RegExp("["+w.keys(M.escape).join("")+"]","g"),unescape:RegExp("("+w.keys(M.unescape).join("|")+")","g")};w.each(["escape","unescape"],function(n){w[n]=function(t){return null==t?"":(""+t).replace(S[n],function(t){return M[n][t]})}}),w.result=function(n,t){if(null==n)return null;var r=n[t];return w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function(t){var r=w[t]=n[t];w.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),D.call(this,r.apply(w,n))}})};var N=0;w.uniqueId=function(n){var t=++N+"";return n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/(.)^/,q={"'":"'","\\":"\\","\r":"r","\n":"n","        ":"t","\u2028":"u2028","\u2029":"u2029"},B=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,r){var e;r=w.defaults({},r,w.templateSettings);var u=RegExp([(r.escape||T).source,(r.interpolate||T).source,(r.evaluate||T).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(B,function(n){return"\\"+q[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,w);var c=function(n){return e.call(this,n,w)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},w.chain=function(n){return w(n).chain()};var D=function(n){return this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];w.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],D.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];w.prototype[n]=function(){return D.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);/*global setImmediate: false, setTimeout: false, console: false */
61777 (function () {
61778
61779     var async = {};
61780
61781     // global on the server, window in the browser
61782     var root, previous_async;
61783
61784     root = this;
61785     if (root != null) {
61786       previous_async = root.async;
61787     }
61788
61789     async.noConflict = function () {
61790         root.async = previous_async;
61791         return async;
61792     };
61793
61794     function only_once(fn) {
61795         var called = false;
61796         return function() {
61797             if (called) throw new Error("Callback was already called.");
61798             called = true;
61799             fn.apply(root, arguments);
61800         }
61801     }
61802
61803     //// cross-browser compatiblity functions ////
61804
61805     var _each = function (arr, iterator) {
61806         if (arr.forEach) {
61807             return arr.forEach(iterator);
61808         }
61809         for (var i = 0; i < arr.length; i += 1) {
61810             iterator(arr[i], i, arr);
61811         }
61812     };
61813
61814     var _map = function (arr, iterator) {
61815         if (arr.map) {
61816             return arr.map(iterator);
61817         }
61818         var results = [];
61819         _each(arr, function (x, i, a) {
61820             results.push(iterator(x, i, a));
61821         });
61822         return results;
61823     };
61824
61825     var _reduce = function (arr, iterator, memo) {
61826         if (arr.reduce) {
61827             return arr.reduce(iterator, memo);
61828         }
61829         _each(arr, function (x, i, a) {
61830             memo = iterator(memo, x, i, a);
61831         });
61832         return memo;
61833     };
61834
61835     var _keys = function (obj) {
61836         if (Object.keys) {
61837             return Object.keys(obj);
61838         }
61839         var keys = [];
61840         for (var k in obj) {
61841             if (obj.hasOwnProperty(k)) {
61842                 keys.push(k);
61843             }
61844         }
61845         return keys;
61846     };
61847
61848     //// exported async module functions ////
61849
61850     //// nextTick implementation with browser-compatible fallback ////
61851     if (typeof process === 'undefined' || !(process.nextTick)) {
61852         if (typeof setImmediate === 'function') {
61853             async.nextTick = function (fn) {
61854                 // not a direct alias for IE10 compatibility
61855                 setImmediate(fn);
61856             };
61857             async.setImmediate = async.nextTick;
61858         }
61859         else {
61860             async.nextTick = function (fn) {
61861                 setTimeout(fn, 0);
61862             };
61863             async.setImmediate = async.nextTick;
61864         }
61865     }
61866     else {
61867         async.nextTick = process.nextTick;
61868         if (typeof setImmediate !== 'undefined') {
61869             async.setImmediate = setImmediate;
61870         }
61871         else {
61872             async.setImmediate = async.nextTick;
61873         }
61874     }
61875
61876     async.each = function (arr, iterator, callback) {
61877         callback = callback || function () {};
61878         if (!arr.length) {
61879             return callback();
61880         }
61881         var completed = 0;
61882         _each(arr, function (x) {
61883             iterator(x, only_once(function (err) {
61884                 if (err) {
61885                     callback(err);
61886                     callback = function () {};
61887                 }
61888                 else {
61889                     completed += 1;
61890                     if (completed >= arr.length) {
61891                         callback(null);
61892                     }
61893                 }
61894             }));
61895         });
61896     };
61897     async.forEach = async.each;
61898
61899     async.eachSeries = function (arr, iterator, callback) {
61900         callback = callback || function () {};
61901         if (!arr.length) {
61902             return callback();
61903         }
61904         var completed = 0;
61905         var iterate = function () {
61906             iterator(arr[completed], function (err) {
61907                 if (err) {
61908                     callback(err);
61909                     callback = function () {};
61910                 }
61911                 else {
61912                     completed += 1;
61913                     if (completed >= arr.length) {
61914                         callback(null);
61915                     }
61916                     else {
61917                         iterate();
61918                     }
61919                 }
61920             });
61921         };
61922         iterate();
61923     };
61924     async.forEachSeries = async.eachSeries;
61925
61926     async.eachLimit = function (arr, limit, iterator, callback) {
61927         var fn = _eachLimit(limit);
61928         fn.apply(null, [arr, iterator, callback]);
61929     };
61930     async.forEachLimit = async.eachLimit;
61931
61932     var _eachLimit = function (limit) {
61933
61934         return function (arr, iterator, callback) {
61935             callback = callback || function () {};
61936             if (!arr.length || limit <= 0) {
61937                 return callback();
61938             }
61939             var completed = 0;
61940             var started = 0;
61941             var running = 0;
61942
61943             (function replenish () {
61944                 if (completed >= arr.length) {
61945                     return callback();
61946                 }
61947
61948                 while (running < limit && started < arr.length) {
61949                     started += 1;
61950                     running += 1;
61951                     iterator(arr[started - 1], function (err) {
61952                         if (err) {
61953                             callback(err);
61954                             callback = function () {};
61955                         }
61956                         else {
61957                             completed += 1;
61958                             running -= 1;
61959                             if (completed >= arr.length) {
61960                                 callback();
61961                             }
61962                             else {
61963                                 replenish();
61964                             }
61965                         }
61966                     });
61967                 }
61968             })();
61969         };
61970     };
61971
61972
61973     var doParallel = function (fn) {
61974         return function () {
61975             var args = Array.prototype.slice.call(arguments);
61976             return fn.apply(null, [async.each].concat(args));
61977         };
61978     };
61979     var doParallelLimit = function(limit, fn) {
61980         return function () {
61981             var args = Array.prototype.slice.call(arguments);
61982             return fn.apply(null, [_eachLimit(limit)].concat(args));
61983         };
61984     };
61985     var doSeries = function (fn) {
61986         return function () {
61987             var args = Array.prototype.slice.call(arguments);
61988             return fn.apply(null, [async.eachSeries].concat(args));
61989         };
61990     };
61991
61992
61993     var _asyncMap = function (eachfn, arr, iterator, callback) {
61994         var results = [];
61995         arr = _map(arr, function (x, i) {
61996             return {index: i, value: x};
61997         });
61998         eachfn(arr, function (x, callback) {
61999             iterator(x.value, function (err, v) {
62000                 results[x.index] = v;
62001                 callback(err);
62002             });
62003         }, function (err) {
62004             callback(err, results);
62005         });
62006     };
62007     async.map = doParallel(_asyncMap);
62008     async.mapSeries = doSeries(_asyncMap);
62009     async.mapLimit = function (arr, limit, iterator, callback) {
62010         return _mapLimit(limit)(arr, iterator, callback);
62011     };
62012
62013     var _mapLimit = function(limit) {
62014         return doParallelLimit(limit, _asyncMap);
62015     };
62016
62017     // reduce only has a series version, as doing reduce in parallel won't
62018     // work in many situations.
62019     async.reduce = function (arr, memo, iterator, callback) {
62020         async.eachSeries(arr, function (x, callback) {
62021             iterator(memo, x, function (err, v) {
62022                 memo = v;
62023                 callback(err);
62024             });
62025         }, function (err) {
62026             callback(err, memo);
62027         });
62028     };
62029     // inject alias
62030     async.inject = async.reduce;
62031     // foldl alias
62032     async.foldl = async.reduce;
62033
62034     async.reduceRight = function (arr, memo, iterator, callback) {
62035         var reversed = _map(arr, function (x) {
62036             return x;
62037         }).reverse();
62038         async.reduce(reversed, memo, iterator, callback);
62039     };
62040     // foldr alias
62041     async.foldr = async.reduceRight;
62042
62043     var _filter = function (eachfn, arr, iterator, callback) {
62044         var results = [];
62045         arr = _map(arr, function (x, i) {
62046             return {index: i, value: x};
62047         });
62048         eachfn(arr, function (x, callback) {
62049             iterator(x.value, function (v) {
62050                 if (v) {
62051                     results.push(x);
62052                 }
62053                 callback();
62054             });
62055         }, function (err) {
62056             callback(_map(results.sort(function (a, b) {
62057                 return a.index - b.index;
62058             }), function (x) {
62059                 return x.value;
62060             }));
62061         });
62062     };
62063     async.filter = doParallel(_filter);
62064     async.filterSeries = doSeries(_filter);
62065     // select alias
62066     async.select = async.filter;
62067     async.selectSeries = async.filterSeries;
62068
62069     var _reject = function (eachfn, arr, iterator, callback) {
62070         var results = [];
62071         arr = _map(arr, function (x, i) {
62072             return {index: i, value: x};
62073         });
62074         eachfn(arr, function (x, callback) {
62075             iterator(x.value, function (v) {
62076                 if (!v) {
62077                     results.push(x);
62078                 }
62079                 callback();
62080             });
62081         }, function (err) {
62082             callback(_map(results.sort(function (a, b) {
62083                 return a.index - b.index;
62084             }), function (x) {
62085                 return x.value;
62086             }));
62087         });
62088     };
62089     async.reject = doParallel(_reject);
62090     async.rejectSeries = doSeries(_reject);
62091
62092     var _detect = function (eachfn, arr, iterator, main_callback) {
62093         eachfn(arr, function (x, callback) {
62094             iterator(x, function (result) {
62095                 if (result) {
62096                     main_callback(x);
62097                     main_callback = function () {};
62098                 }
62099                 else {
62100                     callback();
62101                 }
62102             });
62103         }, function (err) {
62104             main_callback();
62105         });
62106     };
62107     async.detect = doParallel(_detect);
62108     async.detectSeries = doSeries(_detect);
62109
62110     async.some = function (arr, iterator, main_callback) {
62111         async.each(arr, function (x, callback) {
62112             iterator(x, function (v) {
62113                 if (v) {
62114                     main_callback(true);
62115                     main_callback = function () {};
62116                 }
62117                 callback();
62118             });
62119         }, function (err) {
62120             main_callback(false);
62121         });
62122     };
62123     // any alias
62124     async.any = async.some;
62125
62126     async.every = function (arr, iterator, main_callback) {
62127         async.each(arr, function (x, callback) {
62128             iterator(x, function (v) {
62129                 if (!v) {
62130                     main_callback(false);
62131                     main_callback = function () {};
62132                 }
62133                 callback();
62134             });
62135         }, function (err) {
62136             main_callback(true);
62137         });
62138     };
62139     // all alias
62140     async.all = async.every;
62141
62142     async.sortBy = function (arr, iterator, callback) {
62143         async.map(arr, function (x, callback) {
62144             iterator(x, function (err, criteria) {
62145                 if (err) {
62146                     callback(err);
62147                 }
62148                 else {
62149                     callback(null, {value: x, criteria: criteria});
62150                 }
62151             });
62152         }, function (err, results) {
62153             if (err) {
62154                 return callback(err);
62155             }
62156             else {
62157                 var fn = function (left, right) {
62158                     var a = left.criteria, b = right.criteria;
62159                     return a < b ? -1 : a > b ? 1 : 0;
62160                 };
62161                 callback(null, _map(results.sort(fn), function (x) {
62162                     return x.value;
62163                 }));
62164             }
62165         });
62166     };
62167
62168     async.auto = function (tasks, callback) {
62169         callback = callback || function () {};
62170         var keys = _keys(tasks);
62171         if (!keys.length) {
62172             return callback(null);
62173         }
62174
62175         var results = {};
62176
62177         var listeners = [];
62178         var addListener = function (fn) {
62179             listeners.unshift(fn);
62180         };
62181         var removeListener = function (fn) {
62182             for (var i = 0; i < listeners.length; i += 1) {
62183                 if (listeners[i] === fn) {
62184                     listeners.splice(i, 1);
62185                     return;
62186                 }
62187             }
62188         };
62189         var taskComplete = function () {
62190             _each(listeners.slice(0), function (fn) {
62191                 fn();
62192             });
62193         };
62194
62195         addListener(function () {
62196             if (_keys(results).length === keys.length) {
62197                 callback(null, results);
62198                 callback = function () {};
62199             }
62200         });
62201
62202         _each(keys, function (k) {
62203             var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
62204             var taskCallback = function (err) {
62205                 var args = Array.prototype.slice.call(arguments, 1);
62206                 if (args.length <= 1) {
62207                     args = args[0];
62208                 }
62209                 if (err) {
62210                     var safeResults = {};
62211                     _each(_keys(results), function(rkey) {
62212                         safeResults[rkey] = results[rkey];
62213                     });
62214                     safeResults[k] = args;
62215                     callback(err, safeResults);
62216                     // stop subsequent errors hitting callback multiple times
62217                     callback = function () {};
62218                 }
62219                 else {
62220                     results[k] = args;
62221                     async.setImmediate(taskComplete);
62222                 }
62223             };
62224             var requires = task.slice(0, Math.abs(task.length - 1)) || [];
62225             var ready = function () {
62226                 return _reduce(requires, function (a, x) {
62227                     return (a && results.hasOwnProperty(x));
62228                 }, true) && !results.hasOwnProperty(k);
62229             };
62230             if (ready()) {
62231                 task[task.length - 1](taskCallback, results);
62232             }
62233             else {
62234                 var listener = function () {
62235                     if (ready()) {
62236                         removeListener(listener);
62237                         task[task.length - 1](taskCallback, results);
62238                     }
62239                 };
62240                 addListener(listener);
62241             }
62242         });
62243     };
62244
62245     async.waterfall = function (tasks, callback) {
62246         callback = callback || function () {};
62247         if (tasks.constructor !== Array) {
62248           var err = new Error('First argument to waterfall must be an array of functions');
62249           return callback(err);
62250         }
62251         if (!tasks.length) {
62252             return callback();
62253         }
62254         var wrapIterator = function (iterator) {
62255             return function (err) {
62256                 if (err) {
62257                     callback.apply(null, arguments);
62258                     callback = function () {};
62259                 }
62260                 else {
62261                     var args = Array.prototype.slice.call(arguments, 1);
62262                     var next = iterator.next();
62263                     if (next) {
62264                         args.push(wrapIterator(next));
62265                     }
62266                     else {
62267                         args.push(callback);
62268                     }
62269                     async.setImmediate(function () {
62270                         iterator.apply(null, args);
62271                     });
62272                 }
62273             };
62274         };
62275         wrapIterator(async.iterator(tasks))();
62276     };
62277
62278     var _parallel = function(eachfn, tasks, callback) {
62279         callback = callback || function () {};
62280         if (tasks.constructor === Array) {
62281             eachfn.map(tasks, function (fn, callback) {
62282                 if (fn) {
62283                     fn(function (err) {
62284                         var args = Array.prototype.slice.call(arguments, 1);
62285                         if (args.length <= 1) {
62286                             args = args[0];
62287                         }
62288                         callback.call(null, err, args);
62289                     });
62290                 }
62291             }, callback);
62292         }
62293         else {
62294             var results = {};
62295             eachfn.each(_keys(tasks), function (k, callback) {
62296                 tasks[k](function (err) {
62297                     var args = Array.prototype.slice.call(arguments, 1);
62298                     if (args.length <= 1) {
62299                         args = args[0];
62300                     }
62301                     results[k] = args;
62302                     callback(err);
62303                 });
62304             }, function (err) {
62305                 callback(err, results);
62306             });
62307         }
62308     };
62309
62310     async.parallel = function (tasks, callback) {
62311         _parallel({ map: async.map, each: async.each }, tasks, callback);
62312     };
62313
62314     async.parallelLimit = function(tasks, limit, callback) {
62315         _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
62316     };
62317
62318     async.series = function (tasks, callback) {
62319         callback = callback || function () {};
62320         if (tasks.constructor === Array) {
62321             async.mapSeries(tasks, function (fn, callback) {
62322                 if (fn) {
62323                     fn(function (err) {
62324                         var args = Array.prototype.slice.call(arguments, 1);
62325                         if (args.length <= 1) {
62326                             args = args[0];
62327                         }
62328                         callback.call(null, err, args);
62329                     });
62330                 }
62331             }, callback);
62332         }
62333         else {
62334             var results = {};
62335             async.eachSeries(_keys(tasks), function (k, callback) {
62336                 tasks[k](function (err) {
62337                     var args = Array.prototype.slice.call(arguments, 1);
62338                     if (args.length <= 1) {
62339                         args = args[0];
62340                     }
62341                     results[k] = args;
62342                     callback(err);
62343                 });
62344             }, function (err) {
62345                 callback(err, results);
62346             });
62347         }
62348     };
62349
62350     async.iterator = function (tasks) {
62351         var makeCallback = function (index) {
62352             var fn = function () {
62353                 if (tasks.length) {
62354                     tasks[index].apply(null, arguments);
62355                 }
62356                 return fn.next();
62357             };
62358             fn.next = function () {
62359                 return (index < tasks.length - 1) ? makeCallback(index + 1): null;
62360             };
62361             return fn;
62362         };
62363         return makeCallback(0);
62364     };
62365
62366     async.apply = function (fn) {
62367         var args = Array.prototype.slice.call(arguments, 1);
62368         return function () {
62369             return fn.apply(
62370                 null, args.concat(Array.prototype.slice.call(arguments))
62371             );
62372         };
62373     };
62374
62375     var _concat = function (eachfn, arr, fn, callback) {
62376         var r = [];
62377         eachfn(arr, function (x, cb) {
62378             fn(x, function (err, y) {
62379                 r = r.concat(y || []);
62380                 cb(err);
62381             });
62382         }, function (err) {
62383             callback(err, r);
62384         });
62385     };
62386     async.concat = doParallel(_concat);
62387     async.concatSeries = doSeries(_concat);
62388
62389     async.whilst = function (test, iterator, callback) {
62390         if (test()) {
62391             iterator(function (err) {
62392                 if (err) {
62393                     return callback(err);
62394                 }
62395                 async.whilst(test, iterator, callback);
62396             });
62397         }
62398         else {
62399             callback();
62400         }
62401     };
62402
62403     async.doWhilst = function (iterator, test, callback) {
62404         iterator(function (err) {
62405             if (err) {
62406                 return callback(err);
62407             }
62408             if (test()) {
62409                 async.doWhilst(iterator, test, callback);
62410             }
62411             else {
62412                 callback();
62413             }
62414         });
62415     };
62416
62417     async.until = function (test, iterator, callback) {
62418         if (!test()) {
62419             iterator(function (err) {
62420                 if (err) {
62421                     return callback(err);
62422                 }
62423                 async.until(test, iterator, callback);
62424             });
62425         }
62426         else {
62427             callback();
62428         }
62429     };
62430
62431     async.doUntil = function (iterator, test, callback) {
62432         iterator(function (err) {
62433             if (err) {
62434                 return callback(err);
62435             }
62436             if (!test()) {
62437                 async.doUntil(iterator, test, callback);
62438             }
62439             else {
62440                 callback();
62441             }
62442         });
62443     };
62444
62445     async.queue = function (worker, concurrency) {
62446         if (concurrency === undefined) {
62447             concurrency = 1;
62448         }
62449         function _insert(q, data, pos, callback) {
62450           if(data.constructor !== Array) {
62451               data = [data];
62452           }
62453           _each(data, function(task) {
62454               var item = {
62455                   data: task,
62456                   callback: typeof callback === 'function' ? callback : null
62457               };
62458
62459               if (pos) {
62460                 q.tasks.unshift(item);
62461               } else {
62462                 q.tasks.push(item);
62463               }
62464
62465               if (q.saturated && q.tasks.length === concurrency) {
62466                   q.saturated();
62467               }
62468               async.setImmediate(q.process);
62469           });
62470         }
62471
62472         var workers = 0;
62473         var q = {
62474             tasks: [],
62475             concurrency: concurrency,
62476             saturated: null,
62477             empty: null,
62478             drain: null,
62479             push: function (data, callback) {
62480               _insert(q, data, false, callback);
62481             },
62482             unshift: function (data, callback) {
62483               _insert(q, data, true, callback);
62484             },
62485             process: function () {
62486                 if (workers < q.concurrency && q.tasks.length) {
62487                     var task = q.tasks.shift();
62488                     if (q.empty && q.tasks.length === 0) {
62489                         q.empty();
62490                     }
62491                     workers += 1;
62492                     var next = function () {
62493                         workers -= 1;
62494                         if (task.callback) {
62495                             task.callback.apply(task, arguments);
62496                         }
62497                         if (q.drain && q.tasks.length + workers === 0) {
62498                             q.drain();
62499                         }
62500                         q.process();
62501                     };
62502                     var cb = only_once(next);
62503                     worker(task.data, cb);
62504                 }
62505             },
62506             length: function () {
62507                 return q.tasks.length;
62508             },
62509             running: function () {
62510                 return workers;
62511             }
62512         };
62513         return q;
62514     };
62515
62516     async.cargo = function (worker, payload) {
62517         var working     = false,
62518             tasks       = [];
62519
62520         var cargo = {
62521             tasks: tasks,
62522             payload: payload,
62523             saturated: null,
62524             empty: null,
62525             drain: null,
62526             push: function (data, callback) {
62527                 if(data.constructor !== Array) {
62528                     data = [data];
62529                 }
62530                 _each(data, function(task) {
62531                     tasks.push({
62532                         data: task,
62533                         callback: typeof callback === 'function' ? callback : null
62534                     });
62535                     if (cargo.saturated && tasks.length === payload) {
62536                         cargo.saturated();
62537                     }
62538                 });
62539                 async.setImmediate(cargo.process);
62540             },
62541             process: function process() {
62542                 if (working) return;
62543                 if (tasks.length === 0) {
62544                     if(cargo.drain) cargo.drain();
62545                     return;
62546                 }
62547
62548                 var ts = typeof payload === 'number'
62549                             ? tasks.splice(0, payload)
62550                             : tasks.splice(0);
62551
62552                 var ds = _map(ts, function (task) {
62553                     return task.data;
62554                 });
62555
62556                 if(cargo.empty) cargo.empty();
62557                 working = true;
62558                 worker(ds, function () {
62559                     working = false;
62560
62561                     var args = arguments;
62562                     _each(ts, function (data) {
62563                         if (data.callback) {
62564                             data.callback.apply(null, args);
62565                         }
62566                     });
62567
62568                     process();
62569                 });
62570             },
62571             length: function () {
62572                 return tasks.length;
62573             },
62574             running: function () {
62575                 return working;
62576             }
62577         };
62578         return cargo;
62579     };
62580
62581     var _console_fn = function (name) {
62582         return function (fn) {
62583             var args = Array.prototype.slice.call(arguments, 1);
62584             fn.apply(null, args.concat([function (err) {
62585                 var args = Array.prototype.slice.call(arguments, 1);
62586                 if (typeof console !== 'undefined') {
62587                     if (err) {
62588                         if (console.error) {
62589                             console.error(err);
62590                         }
62591                     }
62592                     else if (console[name]) {
62593                         _each(args, function (x) {
62594                             console[name](x);
62595                         });
62596                     }
62597                 }
62598             }]));
62599         };
62600     };
62601     async.log = _console_fn('log');
62602     async.dir = _console_fn('dir');
62603     /*async.info = _console_fn('info');
62604     async.warn = _console_fn('warn');
62605     async.error = _console_fn('error');*/
62606
62607     async.memoize = function (fn, hasher) {
62608         var memo = {};
62609         var queues = {};
62610         hasher = hasher || function (x) {
62611             return x;
62612         };
62613         var memoized = function () {
62614             var args = Array.prototype.slice.call(arguments);
62615             var callback = args.pop();
62616             var key = hasher.apply(null, args);
62617             if (key in memo) {
62618                 callback.apply(null, memo[key]);
62619             }
62620             else if (key in queues) {
62621                 queues[key].push(callback);
62622             }
62623             else {
62624                 queues[key] = [callback];
62625                 fn.apply(null, args.concat([function () {
62626                     memo[key] = arguments;
62627                     var q = queues[key];
62628                     delete queues[key];
62629                     for (var i = 0, l = q.length; i < l; i++) {
62630                       q[i].apply(null, arguments);
62631                     }
62632                 }]));
62633             }
62634         };
62635         memoized.memo = memo;
62636         memoized.unmemoized = fn;
62637         return memoized;
62638     };
62639
62640     async.unmemoize = function (fn) {
62641       return function () {
62642         return (fn.unmemoized || fn).apply(null, arguments);
62643       };
62644     };
62645
62646     async.times = function (count, iterator, callback) {
62647         var counter = [];
62648         for (var i = 0; i < count; i++) {
62649             counter.push(i);
62650         }
62651         return async.map(counter, iterator, callback);
62652     };
62653
62654     async.timesSeries = function (count, iterator, callback) {
62655         var counter = [];
62656         for (var i = 0; i < count; i++) {
62657             counter.push(i);
62658         }
62659         return async.mapSeries(counter, iterator, callback);
62660     };
62661
62662     async.compose = function (/* functions... */) {
62663         var fns = Array.prototype.reverse.call(arguments);
62664         return function () {
62665             var that = this;
62666             var args = Array.prototype.slice.call(arguments);
62667             var callback = args.pop();
62668             async.reduce(fns, args, function (newargs, fn, cb) {
62669                 fn.apply(that, newargs.concat([function () {
62670                     var err = arguments[0];
62671                     var nextargs = Array.prototype.slice.call(arguments, 1);
62672                     cb(err, nextargs);
62673                 }]))
62674             },
62675             function (err, results) {
62676                 callback.apply(that, [err].concat(results));
62677             });
62678         };
62679     };
62680
62681     var _applyEach = function (eachfn, fns /*args...*/) {
62682         var go = function () {
62683             var that = this;
62684             var args = Array.prototype.slice.call(arguments);
62685             var callback = args.pop();
62686             return eachfn(fns, function (fn, cb) {
62687                 fn.apply(that, args.concat([cb]));
62688             },
62689             callback);
62690         };
62691         if (arguments.length > 2) {
62692             var args = Array.prototype.slice.call(arguments, 2);
62693             return go.apply(this, args);
62694         }
62695         else {
62696             return go;
62697         }
62698     };
62699     async.applyEach = doParallel(_applyEach);
62700     async.applyEachSeries = doSeries(_applyEach);
62701
62702     async.forever = function (fn, callback) {
62703         function next(err) {
62704             if (err) {
62705                 if (callback) {
62706                     return callback(err);
62707                 }
62708                 throw err;
62709             }
62710             fn(next);
62711         }
62712         next();
62713     };
62714
62715     root.async = async;
62716
62717 }());
62718 (function() {
62719
62720     var redblack = {};
62721     var root = this;
62722     var orig = root.redblack;
62723
62724     if (typeof module !== 'undefined' && module.exports) {
62725         module.exports = redblack;
62726     } else {
62727         root.redblack = redblack;
62728     }
62729
62730     redblack.VERSION = '0.1.2';
62731
62732     redblack.noConflict = function() {
62733         root.redblack = orig;
62734         return redblack;
62735     };
62736
62737     redblack.tree = function() {
62738         return new Tree();
62739     };
62740
62741     var BLACK = redblack.BLACK = 'black';
62742     var RED = redblack.RED = 'red';
62743
62744     // Node
62745     // ---------------
62746
62747     function Node(key, value) {
62748         this.key = key;
62749         this.value = value;
62750         this.color = RED;
62751         this.left = null;
62752         this.right = null;
62753         this.parent = null;
62754     };
62755
62756     Node.prototype.grandparent = function() {
62757         if (this.parent === null) return null;
62758         return this.parent.parent;
62759     };
62760
62761     Node.prototype.sibling = function() {
62762         if (this.parent === null) return null;
62763         return this === this.parent.left ? this.parent.right : this.parent.left;
62764     };
62765
62766     Node.prototype.uncle = function() {
62767         if (this.parent === null) return null;
62768         return this.parent.sibling();
62769     };
62770
62771     // Cursor
62772     // ---------------
62773
62774     function Cursor(tree, start, end) {
62775         this.tree = tree;
62776         this.start = start;
62777         this.end = end;
62778
62779         var self = this;
62780         this.walk = function walk(node, iterator) {
62781             if (node === null) return;
62782
62783             if (start !== undefined && node.key < start) {
62784                 walk(node.right, iterator);
62785             } else if (end !== undefined && node.key > end) {
62786                 walk(node.left, iterator);
62787             } else {
62788                 walk(node.left, iterator);
62789                 iterator(node.value, node.key, self.tree);
62790                 walk(node.right, iterator);
62791             }
62792         };
62793     };
62794
62795     Cursor.prototype.forEach = function(iterator) {
62796         this.walk(this.tree.root, iterator);
62797     };
62798
62799     Cursor.prototype.map = function(iterator) {
62800         var results = [];
62801
62802         this.forEach(function(value, key, tree) {
62803             results.push(iterator(value, key, tree));
62804         });
62805
62806         return results;
62807     };
62808
62809     // Tree
62810     // ---------------
62811
62812     function Tree() {
62813         this.root = null;
62814         this.balancer = new Balancer(this);
62815     };
62816
62817     Tree.prototype.get = function(key) {
62818         var node = find(this.root, key);
62819         return node === null ? null : node.value;
62820     };
62821
62822     Tree.prototype.insert = function(key, value) {
62823         var newNode = new Node(key, value);
62824
62825         if (this.root === null) {
62826             this.root = newNode;
62827         } else {
62828             var node = this.root;
62829
62830             while (true) {
62831                 if (key < node.key) {
62832                     if (node.left === null) {
62833                         node.left = newNode;
62834                         break;
62835                     } else {
62836                         node = node.left;
62837                     }
62838                 } else if (key > node.key) {
62839                     if (node.right === null) {
62840                         node.right = newNode;
62841                         break;
62842                     } else {
62843                         node = node.right;
62844                     }
62845                 } else {
62846                     node.value = value;
62847                     return;
62848                 }
62849             }
62850
62851             newNode.parent = node;
62852         }
62853
62854         this.balancer.inserted(newNode);
62855     };
62856
62857     Tree.prototype.delete = function(key) {
62858         var node = find(this.root, key);
62859         if (node === null) return;
62860
62861         if (node.left !== null && node.right !== null) {
62862             var pred = node.left;
62863             while (pred.right !== null) pred = pred.right;
62864
62865             node.key = pred.key;
62866             node.value = pred.value;
62867             node = pred;
62868         }
62869
62870         var child = (node.right === null) ? node.left : node.right;
62871         if (nodeColor(node) === BLACK) {
62872             node.color = nodeColor(child);
62873             this.balancer.deleted(node);
62874         }
62875
62876         this.balancer.replaceNode(node, child);
62877
62878         if (nodeColor(this.root) === RED) {
62879             this.root.color = BLACK;
62880         }
62881     };
62882
62883     Tree.prototype.range = function(start, end) {
62884         return new Cursor(this, start, end);
62885     };
62886
62887     // Proxy cursor methods
62888     for (var method in Cursor.prototype) {
62889         if (Cursor.prototype.hasOwnProperty(method)) {
62890             var func = Cursor.prototype[method];
62891             Tree.prototype[method] = function() {
62892                 var cursor = new Cursor(this);
62893                 return func.apply(cursor, arguments);
62894             };
62895         }
62896     }
62897
62898     // Balancer
62899     // ---------------
62900
62901     function Balancer(tree) {
62902         this.tree = tree;
62903     };
62904
62905     Balancer.prototype.inserted = function(node) {
62906         this.insertCase1(node);
62907     };
62908
62909     Balancer.prototype.deleted = function(node) {
62910         this.deleteCase1(node);
62911     };
62912
62913     Balancer.prototype.replaceNode = function(original, replacement) {
62914         if (original.parent === null) {
62915             this.tree.root = replacement;
62916         } else {
62917             if (original === original.parent.left) {
62918                 original.parent.left = replacement;
62919             } else {
62920                 original.parent.right = replacement;
62921             }
62922         }
62923
62924         if (replacement !== null) {
62925             replacement.parent = original.parent;
62926         }
62927     };
62928
62929     Balancer.prototype.rotateLeft = function(node) {
62930         var right = node.right;
62931         this.replaceNode(node, right);
62932
62933         // Update pointers
62934         node.right = right.left;
62935         if (right.left !== null) right.left.parent = node;
62936         right.left = node;
62937         node.parent = right;
62938     };
62939
62940     Balancer.prototype.rotateRight = function(node) {
62941         var left = node.left;
62942         this.replaceNode(node, left);
62943
62944         // Update pointers
62945         node.left = left.right;
62946         if (left.right !== null) left.right.parent = node;
62947         left.right = node;
62948         node.parent = left;
62949     };
62950
62951     Balancer.prototype.insertCase1 = function(node) {
62952         if (node.parent === null) {
62953             node.color = BLACK;
62954         } else {
62955             this.insertCase2(node);
62956         }
62957     };
62958
62959     Balancer.prototype.insertCase2 = function(node) {
62960         if (nodeColor(node.parent) === BLACK) {
62961             return;
62962         } else {
62963             this.insertCase3(node);
62964         }
62965     };
62966
62967     Balancer.prototype.insertCase3 = function(node) {
62968         var uncle = node.uncle();
62969         var grandparent = node.grandparent();
62970
62971         if (uncle !== null && nodeColor(uncle) === RED) {
62972             node.parent.color = BLACK;
62973             uncle.color = BLACK;
62974             grandparent.color = RED;
62975             this.insertCase1(grandparent);
62976         } else {
62977             this.insertCase4(node);
62978         }
62979     };
62980
62981     Balancer.prototype.insertCase4 = function(node) {
62982         var grandparent = node.grandparent();
62983
62984         if (node === node.parent.right && node.parent === grandparent.left) {
62985             this.rotateLeft(node.parent);
62986             node = node.left;
62987         } else if (node === node.parent.left && node.parent === grandparent.right) {
62988             this.rotateRight(node.parent);
62989             node = node.right;
62990         }
62991
62992         this.insertCase5(node);
62993     };
62994
62995     Balancer.prototype.insertCase5 = function(node) {
62996         var grandparent = node.grandparent();
62997
62998         node.parent.color = BLACK;
62999         grandparent.color = RED;
63000
63001         if (node === node.parent.left && node.parent === grandparent.left) {
63002             this.rotateRight(grandparent);
63003         } else if (node === node.parent.right && node.parent === grandparent.right) {
63004             this.rotateLeft(grandparent);
63005         }
63006     };
63007
63008     Balancer.prototype.deleteCase1 = function(node) {
63009         if (node.parent !== null) this.deleteCase2(node);
63010     };
63011
63012     Balancer.prototype.deleteCase2 = function(node) {
63013         var sibling = node.sibling();
63014
63015         if (nodeColor(sibling) === RED) {
63016             node.parent.color = RED;
63017             sibling.color = BLACK;
63018             if (node === node.parent.left) {
63019                 this.rotateLeft(node.parent);
63020             } else {
63021                 this.rotateRight(node.parent);
63022             }
63023         }
63024
63025         this.deleteCase3(node);
63026     };
63027
63028     Balancer.prototype.deleteCase3 = function(node) {
63029         var sibling = node.sibling();
63030
63031         if (nodeColor(node.parent) === BLACK &&
63032             nodeColor(sibling) === BLACK &&
63033             nodeColor(sibling.left) === BLACK &&
63034             nodeColor(sibling.right) === BLACK) {
63035
63036             sibling.color = RED;
63037             this.deleteCase1(node.parent);
63038         } else {
63039             this.deleteCase4(node);
63040         }
63041     };
63042
63043     Balancer.prototype.deleteCase4 = function(node) {
63044         var sibling = node.sibling();
63045
63046         if (nodeColor(node.parent) === RED &&
63047             nodeColor(sibling) === BLACK &&
63048             nodeColor(sibling.left) === BLACK &&
63049             nodeColor(sibling.right) === BLACK) {
63050
63051             sibling.color = RED;
63052             node.parent.color = BLACK;
63053         } else {
63054             this.deleteCase5(node);
63055         }
63056     };
63057
63058     Balancer.prototype.deleteCase5 = function(node) {
63059         var sibling = node.sibling();
63060
63061         if (node === node.parent.left &&
63062             nodeColor(sibling) === BLACK &&
63063             nodeColor(sibling.left) === RED &&
63064             nodeColor(sibling.right) === BLACK) {
63065
63066             sibling.color = RED;
63067             sibling.left.color = BLACK;
63068             this.rotateRight(sibling);
63069         } else if (node === node.parent.right &&
63070             nodeColor(sibling) === BLACK &&
63071             nodeColor(sibling.right) === RED &&
63072             nodeColor(sibling.left) === BLACK) {
63073
63074             sibling.color = RED;
63075             sibling.right.color = BLACK;
63076             this.rotateLeft(sibling);
63077         }
63078
63079         this.deleteCase6(node);
63080     };
63081
63082     Balancer.prototype.deleteCase6 = function(node) {
63083         var sibling = node.sibling();
63084
63085         sibling.color = nodeColor(node.parent);
63086         node.parent.color = BLACK;
63087
63088         if (node === node.parent.left) {
63089             sibling.right.color = BLACK;
63090             this.rotateLeft(node.parent);
63091         } else {
63092             sibling.left.color = BLACK;
63093             this.rotateRight(node.parent);
63094         }
63095     };
63096
63097     // Helpers
63098     // ---------------
63099
63100     function nodeColor(node) {
63101         return node === null ? BLACK : node.color;
63102     };
63103
63104     function find(node, key) {
63105         while (node !== null) {
63106             if (key === node.key) {
63107                 return node;
63108             } else if (key < node.key) {
63109                 node = node.left;
63110             } else if (key > node.key) {
63111                 node = node.right;
63112             }
63113         }
63114
63115         return node;
63116     };
63117
63118 })();
63119 define.unordered = true;define('ripple/accelerometer', function (require, exports, module) {
63120 /*
63121  *  Copyright 2011 Research In Motion Limited.
63122  *
63123  * Licensed under the Apache License, Version 2.0 (the "License");
63124  * you may not use this file except in compliance with the License.
63125  * You may obtain a copy of the License at
63126  *
63127  * http://www.apache.org/licenses/LICENSE-2.0
63128  *
63129  * Unless required by applicable law or agreed to in writing, software
63130  * distributed under the License is distributed on an "AS IS" BASIS,
63131  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63132  * See the License for the specific language governing permissions and
63133  * limitations under the License.
63134  */
63135 var _self,
63136     utils = require('ripple/utils'),
63137     exception = require('ripple/exception'),
63138     event = require('ripple/event'),
63139     Rotation = require('ripple/platform/w3c/1.0/Rotation'),
63140     Acceleration = require('ripple/platform/w3c/1.0/Acceleration'),
63141     _motion = {
63142         acceleration: new Acceleration(0, 0, 0),
63143         accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
63144         rotationRate: new Rotation(0, 0, 0),
63145         orientation: new Rotation(0, 0, 0),
63146         interval: 60000,
63147         timestamp: new Date().getTime()
63148     };
63149
63150 function _validateAccelerometerInfo(x, y, z) {
63151     return !(isNaN(x) || isNaN(y) || isNaN(z));
63152 }
63153
63154 _self = {
63155     getInfo: function () {
63156         return utils.copy(_motion);
63157     },
63158
63159     setInfo: function (e) {
63160         var triggerDeviceMotion = false,
63161             triggerDeviceOrientation = false;
63162
63163         if (e.x !== undefined && e.y !== undefined && e.z !== undefined) {
63164             _motion = {
63165                 acceleration: new Acceleration(e.x, e.y, e.z),
63166                 accelerationIncludingGravity: new Acceleration(e.x, e.y, e.z),
63167                 rotationRate: new Rotation(0, 0, 0),
63168                 orientation: new Rotation(e.alpha, e.beta, e.gamma),
63169                 timestamp: new Date().getTime()
63170             };
63171             triggerDeviceMotion = true;
63172             triggerDeviceOrientation = true;
63173         }
63174         else {
63175             _motion = {
63176                 acceleration: new Acceleration(0, 0, 0),
63177                 accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
63178                 rotationRate: new Rotation(0, 0, 0),
63179                 orientation: new Rotation(0, 0, 0),
63180                 timestamp: new Date().getTime()
63181             };
63182         }
63183
63184         if (triggerDeviceMotion) {
63185             event.trigger("DeviceMotionEvent", [_motion]);
63186         }
63187
63188         if (triggerDeviceOrientation) {
63189             event.trigger("DeviceOrientationEvent", [_motion]);
63190         }
63191
63192         event.trigger("AccelerometerInfoChangedEvent", [_motion]);
63193     },
63194
63195     triggerEvent: function() {
63196         event.trigger("DeviceMotionEvent", [_motion]);
63197         event.trigger("DeviceOrientationEvent", [_motion]);
63198         event.trigger("AccelerometerInfoChangedEvent", [_motion]);
63199     },
63200
63201     shake: function (shakeXtimes) {
63202         var id,
63203             count = 1,
63204             stopCount = shakeXtimes || 17,
63205             oldX = _motion.accelerationIncludingGravity.x;
63206
63207         id = setInterval(function () {
63208             var freq = 1,
63209                 amp = 30,
63210                 value = Math.round(amp * Math.sin(freq * count * (180 / Math.PI)) * 100) / 100;
63211
63212             if (count > stopCount) {
63213                 _motion.acceleration.x = oldX;
63214                 _motion.accelerationIncludingGravity.x = oldX;
63215                 event.trigger("AccelerometerInfoChangedEvent", [_motion]);
63216                 clearInterval(id);
63217                 return;
63218             }
63219
63220             _motion.acceleration.x = value;
63221             _motion.accelerationIncludingGravity.x = value;
63222
63223             event.trigger("AccelerometerInfoChangedEvent", [_motion]);
63224
63225             count++;
63226
63227         }, 80);
63228     },
63229
63230     init: function () {
63231         event.on("DeviceMotionEventAddedEvent", function () {
63232             _self.triggerEvent();
63233         });
63234         event.on("DeviceOrientationEventAddedEvent", function () {
63235             _self.triggerEvent();
63236         });
63237     }
63238 };
63239
63240 module.exports = _self;
63241
63242 });
63243 define('ripple/app', function (require, exports, module) {
63244 /*
63245  *  Copyright 2011 Research In Motion Limited.
63246  *
63247  * Licensed under the Apache License, Version 2.0 (the "License");
63248  * you may not use this file except in compliance with the License.
63249  * You may obtain a copy of the License at
63250  *
63251  * http://www.apache.org/licenses/LICENSE-2.0
63252  *
63253  * Unless required by applicable law or agreed to in writing, software
63254  * distributed under the License is distributed on an "AS IS" BASIS,
63255  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63256  * See the License for the specific language governing permissions and
63257  * limitations under the License.
63258  */
63259 var _data = {},
63260     utils = require('ripple/utils'),
63261     _self;
63262
63263 _self = {
63264     setInfo: function (info) {
63265         if (!info) {
63266             _data = {};
63267         }
63268         _data = info;
63269     },
63270
63271     getInfo: function () {
63272         return utils.copy(_data);
63273     },
63274
63275     isPreferenceReadOnly: function (key) {
63276         return (_data.preferences &&
63277                 _data.preferences[key] &&
63278                 _data.preferences[key].readonly &&
63279                 _data.preferences[key].readonly === true);
63280     },
63281
63282     validateVersion: function (configValidationObject) {
63283         // TODO: WTF figure this out, platform is empty object when require at require time
63284         // could be that the new platform _getBuilder code dies when called, beforre it is initialized
63285         var spec = require('ripple/platform').current();
63286         if (typeof spec.config.validateVersion === "function" && configValidationObject) {
63287             return spec.config.validateVersion(configValidationObject);
63288         }
63289
63290         return true;
63291     },
63292
63293     saveInfo: function (configValidationObject) {
63294         var spec = require('ripple/platform').current(),
63295             info = null;
63296         if (typeof spec.config.extractInfo === "function") {
63297             info = spec.config.extractInfo(configValidationObject);
63298         }
63299
63300         if (info) {
63301             _self.setInfo(info);
63302         }
63303     }
63304
63305 };
63306
63307 module.exports = _self;
63308
63309 });
63310 define('ripple/appcache', function (require, exports, module) {
63311 /*
63312  *  Copyright 2011 Research In Motion Limited.
63313  *
63314  * Licensed under the Apache License, Version 2.0 (the "License");
63315  * you may not use this file except in compliance with the License.
63316  * You may obtain a copy of the License at
63317  *
63318  * http://www.apache.org/licenses/LICENSE-2.0
63319  *
63320  * Unless required by applicable law or agreed to in writing, software
63321  * distributed under the License is distributed on an "AS IS" BASIS,
63322  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63323  * See the License for the specific language governing permissions and
63324  * limitations under the License.
63325  */
63326 module.exports = {
63327     initialize: function () {
63328         window.addEventListener('load', function (e) {
63329             window.applicationCache.addEventListener('updateready', function (e) {
63330                 if (window.applicationCache.status === window.applicationCache.UPDATEREADY) {
63331                     window.applicationCache.swapCache();
63332                     window.location.reload();
63333                 }
63334             }, false);
63335         }, false);
63336     }
63337 };
63338
63339 });
63340 define('ripple/bootstrap', function (require, exports, module) {
63341 /*
63342  *  Copyright 2011 Research In Motion Limited.
63343  *
63344  * Licensed under the Apache License, Version 2.0 (the "License");
63345  * you may not use this file except in compliance with the License.
63346  * You may obtain a copy of the License at
63347  *
63348  * http://www.apache.org/licenses/LICENSE-2.0
63349  *
63350  * Unless required by applicable law or agreed to in writing, software
63351  * distributed under the License is distributed on an "AS IS" BASIS,
63352  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63353  * See the License for the specific language governing permissions and
63354  * limitations under the License.
63355  */
63356 var _bound,
63357     _console = require('ripple/console'),
63358     utils = require('ripple/utils'),
63359     ui = require('ripple/ui'),
63360     db = require('ripple/db'),
63361     _CURRENT_URL = "current-url",
63362     resizer = require('ripple/resizer'),
63363     platform = require('ripple/platform');
63364
63365 var _srcChangedObserver = new WebKitMutationObserver(function (mutations) {
63366             utils.forEach(mutations, function (mutation) {
63367                 _bindObjectsToFrame(mutation.target);
63368             });
63369         });
63370
63371 function _observeIframeAdded(doc) {
63372     doc._iframeAddedObserver.observe(doc, {childList: true, subtree: true});
63373 }
63374
63375 function _bindObjects(win, doc) {
63376     if (!win.tinyHippos) {
63377         require('ripple/emulatorBridge').link(win, doc);
63378         /// require('ripple/platform/tizen/2.0/touchEvent').mask(win, doc);
63379         require('ripple/touchEventEmulator').mask(win, doc);
63380         require('ripple/hwKeyEmulator').init(win, doc);
63381         require('ripple/documentEventListener').mask(win, doc);
63382         require('ripple/deviceMotionEmulator').init(win, doc);
63383         require('ripple/resizer').init(win, doc);
63384         win.addEventListener("DOMContentLoaded", function () {
63385             var iframes =  $(this.document).find("iframe");
63386             // Observe iframe added event so that we can bind objects to newly added iframes
63387             if (!this.document._iframeAddedObserver) {
63388                 this.document._iframeAddedObserver = new WebKitMutationObserver(function (mutations) {
63389                     utils.forEach(mutations, function (mutation) {
63390                         for (var i in mutation.addedNodes) {
63391                             var node = mutation.addedNodes[i];
63392                             if (node.tagName && (node.tagName.toUpperCase() === "IFRAME")) {
63393                                 _bindObjectsToFrame(node);
63394                             }
63395                         }
63396                     });
63397                 });
63398                 _observeIframeAdded(this.document);
63399             }
63400             iframes.each(function () {
63401                 _bindObjectsToFrame(this);
63402             });
63403
63404         });
63405         win.frameElement._bound = true;
63406     }
63407 }
63408
63409 function _beforeLoad() {
63410     this._bound = false;
63411     _bindObjects(this.contentWindow, this.contentDocument);
63412     this._intervalId = window.setInterval(function () {
63413         if (this._bound) {
63414             window.clearInterval(this._intervalId);
63415         } else {
63416             _bindObjects(this.contentWindow, this.contentDocument);
63417         }
63418     }.bind(this), 1);
63419 }
63420
63421 function _bindObjectsToFrame(frame) {
63422     _srcChangedObserver.observe(frame, {attributes: true, attributeFilter: ["src"]});
63423     frame.addEventListener("beforeload", _beforeLoad);
63424     // beforeload event of an iframe will not be triggered unless we detach and
63425     // then attach the iframe to the dom tree
63426     var parentNode = frame.parentNode;
63427     var nextNode = frame.nextNode;
63428     if (parentNode) {
63429         // Disable iframe added observer to avoid infinite loop of binding objects
63430         if (frame.ownerDocument && frame.ownerDocument._iframeAddedObserver) {
63431             frame.ownerDocument._iframeAddedObserver.disconnect();
63432         }
63433         parentNode.removeChild(frame);
63434         if (nextNode)
63435             nextNode.insertBefore(frame);
63436         else
63437             parentNode.appendChild(frame);
63438
63439         if (frame.ownerDocument && frame.ownerDocument._iframeAddedObserver) {
63440             _observeIframeAdded(frame.ownerDocument);
63441         }
63442     }
63443 }
63444
63445 function _createFrame(src) {
63446     var frame = document.createElement("iframe");
63447     frame.setAttribute("id", "document");
63448     frame.src = src;
63449
63450     if (ui.registered("omnibar")) {
63451         _bindObjectsToFrame(frame);
63452     }
63453
63454     return frame;
63455 }
63456
63457 function _cleanBody() {
63458     require('ripple/utils').forEach(document.body.children, function (child) {
63459         if (child && child.id && !child.id.match(/ui|tooltip|bus/)) {
63460             document.body.removeChild(child);
63461         }
63462
63463         document.body.removeAttribute("style");
63464         document.body.removeAttribute("id");
63465         document.body.removeAttribute("class");
63466     });
63467 }
63468
63469 function reload() {
63470     window.tinyHipposReload = true;
63471     location.reload();
63472 }
63473
63474 function _post(src) {
63475     var event = require('ripple/event'),
63476         frame = _createFrame(src);
63477
63478     _console.log("Initialization Finished (Make it so.)");
63479
63480     frame.onload = function () {
63481         var bootLoader = document.querySelector("#emulator-booting"),
63482             id,
63483             iframe = document.getElementById('document'),
63484             viewportTagFound = false,
63485             viewportTagContent = {},
63486             viewportTagStr = "",
63487             tagProperties = [],
63488             propertyKey ="",
63489             propertyValue = "",
63490             curViewPortWidth = "",
63491             curViewPortHeight = "",
63492             layout = db.retrieve("layout") || "portrait",
63493             preLayout = "";
63494
63495         if (bootLoader) {
63496             document.querySelector("#ui").removeChild(bootLoader);
63497         }
63498
63499         // Workaround to enforce the content of iframe to rerender when scrolling
63500         document.getElementById('document').contentWindow.onscroll = function() {
63501             jQuery("#device-maskmask").show();
63502             setTimeout(function() {
63503                 jQuery("#device-maskmask").hide();
63504             }, 50);
63505         }
63506
63507         event.trigger("TinyHipposLoaded");
63508         _cleanBody();
63509         id = window.setInterval(_cleanBody, 20);
63510
63511         window.setTimeout(function () {
63512             window.clearInterval(id);
63513         }, 1200);
63514
63515         // Clean data for different app
63516         if (db.retrieve("current-url") !== db.retrieve("previous-url")) {
63517             db.remove("viewport_width");
63518             db.remove("viewport_height");
63519             db.remove("viewportTag");
63520             db.remove("prelayout");
63521         }
63522
63523         curViewPortWidth = db.retrieve("viewport_width");
63524         curViewPortHeight = db.retrieve("viewport_height");
63525         preLayout = db.retrieve("prelayout") || "portrait";
63526         db.save("previous-url", db.retrieve("current-url"));
63527
63528         if (iframe.contentDocument.getElementsByName('viewport')[0] !== undefined) {
63529             viewportTagStr = iframe.contentDocument.getElementsByName('viewport')[0].getAttribute("content");
63530             viewportTagStr = viewportTagStr.replace(/\s/g, '');
63531             tagProperties = viewportTagStr.split(",");
63532
63533             for (var i in tagProperties) {
63534                 propertyKey = tagProperties[i].split("=")[0];
63535                 propertyValue = tagProperties[i].split("=")[1];
63536                 viewportTagContent[propertyKey] = propertyValue;
63537             }
63538             viewportTagFound = true;
63539         }
63540
63541         // if viewport tag found (width, height)
63542         if (viewportTagFound && ((viewportTagContent['width'] !== undefined) || (viewportTagContent['height'] !== undefined))) {
63543             if ((viewportTagContent['width'] !== undefined)) {
63544                 if (curViewPortWidth !== viewportTagContent['width']) {
63545                     db.saveObject("viewportTag", viewportTagContent);
63546                     if (layout !== preLayout) {
63547                         db.save("prelayout", layout);
63548                         resizer.changeLayoutType(layout);
63549                         event.trigger("LayoutChanged", [layout], true);
63550                         frame.contentWindow.location.reload(); // get the updated screenAvailWidth, screenWidth....
63551                     } else {
63552                         resizer.changeLayoutType(layout);
63553                     }
63554                 }
63555             } else {
63556                 if (curViewPortHeight !== viewportTagContent['height']) {
63557                     db.saveObject("viewportTag", viewportTagContent);
63558                     if (layout !== preLayout) {
63559                         db.save("prelayout", layout);
63560                         resizer.changeLayoutType(layout);
63561                         event.trigger("LayoutChanged", [layout], true);
63562                         frame.contentWindow.location.reload(); // get the updated screenAvailWidth, screenWidth....
63563                     } else {
63564                         resizer.changeLayoutType(layout);
63565                     }
63566                 }
63567             }
63568         } else {
63569             // Set layout to portrait if no viewport tag detected
63570             resizer.changeLayoutType('portrait');
63571             event.trigger("LayoutChanged", ['portrait'], true);
63572         }
63573
63574         if (ui.registered("omnibar")) {
63575             //reset the onload function so that when navigating we can destroy
63576             //the iframe and create a new one so we can reinject the platform by
63577             //calling post again.
63578             frame.onload = function () {
63579                 var url = frame.contentWindow.location.href;
63580                 document.getElementById("viewport-container").removeChild(frame);
63581                 event.trigger("FrameHistoryChange", [url]);
63582                 _console.log("-----------------------------------------------------------");
63583                 _console.log("Pay no attention to that man behind the curtain.");
63584                 _console.log("Environment Warning up again (Set main batteries to auto-fire cycle)");
63585                 _post(url);
63586             };
63587         }
63588     };
63589
63590     // append frame
63591     document.getElementById("viewport-container").appendChild(frame);
63592
63593     delete tinyHippos.boot;
63594 }
63595
63596 function _bootstrap() {
63597     // TODO: figure this out for web and ext
63598     //_console.log("-----------------------------------------------------------");
63599     //_console.log("There be dragons above here!");
63600     _console.log("Web Simulator :: Environment Warming Up (Tea. Earl Gray. Hot.)");
63601
63602     window.tinyHippos = require('ripple');
63603
63604     tinyHippos.boot(function () {
63605         var uri = ui.registered('omnibar') ?
63606                 db.retrieve(_CURRENT_URL) || "about:blank" :
63607                 document.documentURI.replace(/enableripple=[^&]*[&]?/i, "").replace(/[\?&]*$/, "");
63608
63609         _post(uri);
63610         delete tinyHippos.boot;
63611     });
63612 }
63613
63614 module.exports = {
63615     bootstrap: _bootstrap,
63616     inject: function (frameWindow, frameDocument) {
63617         _bindObjects(frameWindow, frameDocument);
63618     }
63619 };
63620
63621 });
63622 define('ripple/bus', function (require, exports, module) {
63623 /*
63624  *  Copyright 2011 Research In Motion Limited.
63625  *
63626  * Licensed under the Apache License, Version 2.0 (the "License");
63627  * you may not use this file except in compliance with the License.
63628  * You may obtain a copy of the License at
63629  *
63630  * http://www.apache.org/licenses/LICENSE-2.0
63631  *
63632  * Unless required by applicable law or agreed to in writing, software
63633  * distributed under the License is distributed on an "AS IS" BASIS,
63634  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63635  * See the License for the specific language governing permissions and
63636  * limitations under the License.
63637  */
63638
63639 var _send = document.getElementById("bus-send"),
63640     _receive = document.getElementById("bus-receive"),
63641     _evt = document.createEvent("Events");
63642
63643 _evt.initEvent('bus-init', true, true);
63644 document.dispatchEvent(_evt);
63645
63646 module.exports = {
63647     send: function (msg, data, callback) {
63648         var m = document.createElement("span");
63649         m.dataset.msg = msg;
63650         m.innerHTML = JSON.stringify(data);
63651
63652         if (callback) {
63653             m.dataset.callback = Math.uuid();
63654             this.receive(m.dataset.callback, callback);
63655         }
63656
63657         _send.appendChild(m);
63658     },
63659
63660     receive: function (msg, handler) {
63661         if (!handler) {
63662             return;
63663         }
63664
63665         _receive.addEventListener("DOMNodeInserted", function (evt) {
63666             if (evt.target.dataset.msg === msg) {
63667                 handler(JSON.parse(evt.target.innerHTML));
63668             }
63669         });
63670     },
63671
63672     ajax: function (method, url, data, success, fail) {
63673         this.send("xhr", {
63674             method: method,
63675             url: url,
63676             data: data
63677         }, function (result) {
63678             if (result.code === 200) {
63679                 success(result.data);
63680             }
63681             else {
63682                 fail(result);
63683             }
63684         });
63685     }
63686 };
63687
63688 });
63689 define('ripple/console', function (require, exports, module) {
63690 /*
63691  *  Copyright 2011 Research In Motion Limited.
63692  *
63693  * Licensed under the Apache License, Version 2.0 (the "License");
63694  * you may not use this file except in compliance with the License.
63695  * You may obtain a copy of the License at
63696  *
63697  * http://www.apache.org/licenses/LICENSE-2.0
63698  *
63699  * Unless required by applicable law or agreed to in writing, software
63700  * distributed under the License is distributed on an "AS IS" BASIS,
63701  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63702  * See the License for the specific language governing permissions and
63703  * limitations under the License.
63704  */
63705 var _self;
63706
63707 function _log(msg, method) {
63708     try {
63709         console[method](_self.prefix ? _self.prefix + " :: " + msg : msg);
63710     } catch (e) {
63711         // silent
63712     }
63713 }
63714
63715 _self = {
63716     log: function (msg) {
63717         _log(msg, "log");
63718     },
63719
63720     warn: function (msg) {
63721         _log(msg, "warn");
63722     },
63723
63724     error: function (msg) {
63725         _log(msg, "error");
63726     }
63727 };
63728
63729 module.exports = _self;
63730
63731 });
63732 define('ripple/constants', function (require, exports, module) {
63733 /*
63734  *  Copyright 2011 Research In Motion Limited.
63735  *
63736  * Licensed under the Apache License, Version 2.0 (the "License");
63737  * you may not use this file except in compliance with the License.
63738  * You may obtain a copy of the License at
63739  *
63740  * http://www.apache.org/licenses/LICENSE-2.0
63741  *
63742  * Unless required by applicable law or agreed to in writing, software
63743  * distributed under the License is distributed on an "AS IS" BASIS,
63744  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63745  * See the License for the specific language governing permissions and
63746  * limitations under the License.
63747  */
63748 module.exports = {
63749     "API_URL": "http://api.tinyhippos.com",
63750
63751     "RELEASE_VERSION": "simulator-release-version",
63752
63753     "SERVICES": {
63754         "GOOGLE_MAPS_URI": "http://maps.google.com/maps/api/staticmap?size=476x476&maptype=roadmap",
63755         "GOOGLE_MAPS_API_KEY": "ABQIAAAA-CaPZHXR-0Tzhui_h6gpjhSE_2rGlnYiB7L-ZGVwgaut5s7OYRSlBAaHCzBuZf2_23_vrCOfPxXHjA"
63756     },
63757
63758     "FS_SIZE": 1024 * 1024 * 10,
63759
63760     "COMMON":  {
63761         "APPLICATION_STATE": "ui-application-state-",
63762         "PREFIX": "tinyhippos-",
63763         "DEVICE_CONTAINER" : "device-container",
63764         "MENU_BUTTON" : "menu-button",
63765         "BACK_BUTTON" : "back-button",
63766         "HTML_CONTAINER" : "document",
63767         "INFO_SECTION": "information-sub-container",
63768         "ORIENTATION_SELECT_PORTRAIT_ID" : "layout-portrait",
63769         "ORIENTATION_SELECT_LANDSCAPE_ID" : "layout-landscape",
63770         "PLATFORM_SELECT_ID": "platform-select",
63771         "DEVICE_SELECT_ID": "device-select",
63772         "STORAGE_TABLE_BODY_CLASS": "preferences-list-body",
63773         "STORAGE_COUNT_CONTAINER_ID": "preferences-count",
63774         "GEO_MAP_CONTAINER_ID": "geo-map",
63775         "FILESYSTEM_UPDATE_BUTTON_ID_WITH_HASH": "#update-filesystem-button",
63776         "USER_AGENT_DEFAULT": "default",
63777         "APPLICATIONS_CONTAINER_ID": "widget-applications-content",
63778         "STORAGE_CLEAR_BUTTON_ID": "preferences-clear-button",
63779         "AJAX_LOADER_CONTAINER_CLASS": ".loader",
63780         "IRRELEVANT_CLASS": "irrelevant",
63781         "MULTIMEDIA_VOLUME_SLIDER_ID": "media-volume",
63782         "MULTIMEDIA_VOLUME_FIELD_ID": "media-volume-value",
63783         "MULTIMEDIA_AUDIO_STATE_FIELD_ID": "media-audio-state",
63784         "MULTIMEDIA_AUDIO_PLAYING_FIELD_ID": "multimedia-isaudioplaying",
63785         "MULTIMEDIA_AUDIO_PROGRESS_ID": "media-audio-progress",
63786         "MULTIMEDIA_AUDIO_FILE_FIELD_ID": "media-audio-file",
63787         "MULTIMEDIA_VIDEO_STATE_FIELD_ID": "media-video-state",
63788         "MULTIMEDIA_VIDEO_PLAYING_FIELD_ID": "multimedia-isvideoplaying",
63789         "MULTIMEDIA_VIDEO_PROGRESS_ID": "media-video-progress",
63790         "MULTIMEDIA_VIDEO_FILE_FIELD_ID": "media-video-file",
63791         "EXTENSION_URL_CONTAINER": "extension-url",
63792         "SECURITY_LEVEL": "security-level"
63793     },
63794     "LAUNCHING_HISTORY": "application-launching-history",
63795
63796     "FILESYSTEM": {
63797         "PERSISTENCE_KEY": "filesystem",
63798         "INPUT_PREFIX_ID": "#panel-filesystem-"
63799     },
63800
63801     "PLATFORM":  {
63802         "DEFAULT": {
63803             "name": "tizen",
63804             "version": "1.0"
63805         }
63806     },
63807
63808     "DEVICE":  {
63809         "SAVED_KEY": "device-key"
63810     },
63811
63812     "BATTERY":  {
63813         "TIME": "charging-time",
63814         "VOLUME": "battery-volume",
63815         "CHARGING": "is-charging"
63816     },
63817
63818     "TOUCHEVENT":  {
63819         "OPTION": "touch_option",
63820         "ALTKEY": "touch_altKey",
63821         "METAKEY": "touch_metaKey",
63822         "CTRLKEY": "touch_ctrlKey",
63823         "SHIFTKEY": "touch_shiftKey",
63824         "CANVAS": "touch_canvas"
63825     },
63826
63827     "ENCAPSULATOR":  {
63828         "DEFAULT_HEIGHT": 684,
63829         "DEFAULT_WIDTH": 480,
63830         "LAYOUT": "layout",
63831         "DISPLAY_LAYOUT": {
63832             "LANDSCAPE": "landscape",
63833             "PORTRAIT": "portrait"
63834         },
63835         "ZOOMING": "screen-zooming"
63836     },
63837
63838     "GEO":  {
63839         "OPTIONS" : {
63840             "LATITUDE" : "geo-latitude",
63841             "LONGITUDE" : "geo-longitude",
63842             "ALTITUDE" : "geo-altitude",
63843             "CELL_ID" : "geo-cellid",
63844             "ACCURACY" : "geo-accuracy",
63845             "ALTITUDE_ACCURACY" : "geo-altitudeaccuracy",
63846             "HEADING" : "geo-heading",
63847             "SPEED" : "geo-speed",
63848             "TIME_STAMP" : "geo-timestamp",
63849             "DELAY" : "geo-delay",
63850             "DELAY_LABEL" : "geo-delay-label",
63851             "HEADING_LABEL" : "geo-heading-label",
63852             "HEADING_MAP_LABEL" : "geo-map-direction-label",
63853             "IMAGE" : "geo-map-img",
63854             "MAP_CONTAINER" : "geo-map-container",
63855             "TIMEOUT" : "geo-timeout",
63856             "GPXFILE": "geo-gpxfile",
63857             "GPXGO": "geo-gpx-go",
63858             "GPXMULTIPLIER": "geo-gpxmultiplier-select",
63859             "GPXREPLAYSTATUS": "geo-gpxreplaystatus"
63860         },
63861         "MAP_ZOOM_MAX": 18,
63862         "MAP_ZOOM_MIN": 0,
63863         "MAP_ZOOM_LEVEL_CONTAINER": "geo-map-zoomlevel-value",
63864         "MAP_ZOOM_KEY": "geo-map-zoom-key",
63865         "GPXGO_LABELS": {
63866
63867             "GO": "Go",
63868             "STOP": "Stop"
63869         }
63870     },
63871
63872     "PUSH": {
63873         "OPTIONS" : {
63874             "PAYLOAD" : "push-text"
63875         }
63876     },
63877
63878     "TELEPHONY": {
63879         "CALL_LIST_KEY": "telephony-call-list-key"
63880     },
63881
63882     "PIM": {
63883         "ADDRESS_LIST_KEY": "pim-address-list-key",
63884         "CALENDAR_LIST_KEY": "pim-calendar-list-key"
63885     },
63886
63887     "CAMERA": {
63888         "WINDOW_ANIMATION": "images/tizen-wave.gif",
63889         "WARNING_TEXT": "The runtime simulated saving the camera file to {file}. If you need to access this file in your application, please copy a file to the saved location"
63890     },
63891
63892     "AUDIOPLAYER" : {
63893         "WARNING_TEXT": "The runtime simulated saving the audio file to {file}. If you need to access this file in your application, please copy a file to the saved location"
63894     },
63895
63896     "API_APPLICATION": {
63897         "NO_APPLICATIONS_MESSAGE": "No applications available for your platform"
63898     },
63899
63900     "NOTIFICATIONS":  {
63901         "MESSAGE_CONTAINER_CLASS": "notification-message-div",
63902         "MAIN_CONTAINER_CLASS": "panel-notification",
63903         "CLOSE_BUTTON_CLASS": "panel-notification-closebtn",
63904         "MESSAGE_TEXT_CONTAINER_CLASS": "panel-notification-text",
63905         "CSS_PREFIX": "panel-notification-",
63906         "STATE_TYPES": {
63907             "OPEN": 1,
63908             "CLOSE": 2
63909         }
63910     },
63911
63912     "CSS_PREFIX":  {
63913         "IRRELEVANT" : "irrelevant"
63914     },
63915
63916     "STORAGE":  {
63917         "PAIR_DELIMETER" : ",",
63918         "KEY_VALUE_DELIMETER" : "|"
63919     },
63920
63921     "REGEX":  {
63922         "GEO" : /^geo-/,
63923         "URL": /^((https?|ftp|gopher|telnet|file|notes|ms-help):((\/\/)|(\\\\))+[\w\d:#@%\/;$()~_?\+-=\\\.&]*)$/,
63924         //"Email": /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/
63925         "EMAIL": /^([^@\s]+)@((?:[\-a-z0-9]+\.)+[a-z]{2,})$/,
63926         "WC3_DTF": /^((\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)|(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)|(\d{4})-(\d\d)-(\d\d)|(\d{4})-(\d\d)|(\d\d\d\d))$/,
63927         "LOCAL_URI": /^https?:\/\/(127\.0\.0\.1|localhost)|^file:\/\//,
63928         "EXTERNAL_URI": /(?:(?:[a-zA-Z0-9\/;\?&=:\-_\$\+!\*'\(\|\\~\[\]#%\.](?!www))+(?:\.[Cc]om|\.[Ee]du|\.[gG]ov|\.[Ii]nt|\.[Mm]il|\.[Nn]et|\.[Oo]rg|\.[Bb]iz|\.[Ii]nfo|\.[Nn]ame|\.[Pp]ro|\.[Aa]ero|\.[cC]oop|\.[mM]useum|\.[Cc]at|\.[Jj]obs|\.[Tt]ravel|\.[Aa]rpa|\.[Mm]obi|\.[Aa]c|\.[Aa]d|\.[aA]e|\.[aA]f|\.[aA]g|\.[aA]i|\.[aA]l|\.[aA]m|\.[aA]n|\.[aA]o|\.[aA]q|\.[aA]r|\.[aA]s|\.[aA]t|\.[aA]u|\.[aA]w|\.[aA]z|\.[aA]x|\.[bB]a|\.[bB]b|\.[bB]d|\.[bB]e|\.[bB]f|\.[bB]g|\.[bB]h|\.[bB]i|\.[bB]j|\.[bB]m|\.[bB]n|\.[bB]o|\.[bB]r|\.[bB]s|\.[bB]t|\.[bB]v|\.[bB]w|\.[bB]y|\.[bB]z|\.[cC]a|\.[cC]c|\.[cC]d|\.[cC]f|\.[cC]g|\.[cC]h|\.[cC]i|\.[cC]k|\.[cC]l|\.[cC]m|\.[cC]n|\.[cC]o|\.[cC]r|\.[cC]s|\.[cC]u|\.[cC]v|\.[cC]x|\.[cC]y|\.[cC]z|\.[dD]e|\.[dD]j|\.[dD]k|\.[dD]m|\.[dD]o|\.[dD]z|\.[eE]c|\.[eE]e|\.[eE]g|\.[eE]h|\.[eE]r|\.[eE]s|\.[eE]t|\.[eE]u|\.[fF]i|\.[fF]j|\.[fF]k|\.[fF]m|\.[fF]o|\.[fF]r|\.[gG]a|\.[gG]b|\.[gG]d|\.[gG]e|\.[gG]f|\.[gG]g|\.[gG]h|\.[gG]i|\.[gG]l|\.[gG]m|\.[gG]n|\.[gG]p|\.[gG]q|\.[gG]r|\.[gG]s|\.[gG]t|\.[gG]u|\.[gG]w|\.[gG]y|\.[hH]k|\.[hH]m|\.[hH]n|\.[hH]r|\.[hH]t^[ml]?|\.[hH]u|\.[iI]d|\.[iI]e|\.[iI]l|\.[iI]m|\.[iI]n|\.[iI]o|\.[iI]q|\.[iI]r|\.[iI]s|\.[iI]t|\.[jJ]e|\.[jJ]m|\.[jJ]o|\.[jJ]p|\.[kK]e|\.[kK]g|\.[kK]h|\.[kK]i|\.[kK]m|\.[kK]n|\.[kK]p|\.[kK]r|\.[kK]w|\.[kK]y|\.[kK]z|\.[lL]a|\.[lL]b|\.[lL]c|\.[lL]i|\.[lL]k|\.[lL]r|\.[lL]s|\.[lL]t|\.[lL]u|\.[lL]v|\.[lL]y|\.[mM]a|\.[mM]c|\.[mM]d|\.[mM]g|\.[mM]h|\.[mM]k|\.[mM]l|\.[mM]m|\.[mM]n|\.[mM]o|\.[mM]p|\.[mM]q|\.[mM]r|\.[mM]s|\.[mM]t|\.[mM]u|\.[mM]v|\.[mM]w|\.[mM]x|\.[mM]y|\.[mM]z|\.[nN]a|\.[nN]c|\.[nN]e|\.[nN]f|\.[nN]g|\.[nN]i|\.[nN]l|\.[nN]o|\.[nN]p|\.[nN]r|\.[nN]u|\.[nN]z|\.[oO]m|\.[pP]a|\.[pP]e|\.[pP]f|\.[pP]g|\.[pP]h|\.[pP]k|\.[pP]l|\.[pP]m|\.[pP]n|\.[pP]r|\.[pP]s|\.[pP]t|\.[pP]w|\.[pP]y|\.[qP]a|\.[rR]e|\.[rR]o|\.[rR]u|\.[rR]w|\.[sS]a|\.[sS]b|\.[sS]c|\.[sS]d|\.[sS]e|\.[sS]g|\.[sS]h|\.[Ss]i|\.[sS]j|\.[sS]k|\.[sS]l|\.[sS]m|\.[sS]n|\.[sS]o|\.[sS]r|\.[sS]t|\.[sS]v[^c]|\.[sS]y|\.[sS]z|\.[tT]c|\.[tT]d|\.[tT]f|\.[tT]g|\.[tT]h|\.[tT]j|\.[tT]k|\.[tT]l|\.[tT]m|\.[tT]n|\.[tT]o|\.[tT]p|\.[tT]r|\.[tT]t|\.[tT]v|\.[tT]w|\.[tT]z|\.[uU]a|\.[uU]g|\.[uU]k|\.[uU]m|\.[uU]s|\.[uU]y|\.[uU]z|\.[vV]a|\.[vV]c|\.[vV]e|\.[vV]g|\.[vV]i|\.[vV]n|\.[vV]u|\.[wW]f|\.[wW]s|\.[yY]e|\.[yY]t|\.[yY]u|\.[zZ]a|\.[zZ]m|\.[zZ]w))/
63929     },
63930
63931     "CONFIG": {
63932         "SUCCESS_CSS": {
63933             "true": "ui-text-pass",
63934             "false": "ui-text-fail",
63935             "missing": "ui-text-missing"
63936         }
63937     },
63938
63939     "SETTINGS": {
63940         "TOOLTIPS_TOGGLE_DIV": "#settings-toggletooltips",
63941         "TOOLTIPS_KEY": "tool-tips-key"
63942     },
63943
63944     "PANEL": {
63945         "PANEL_CONFIG_ENABLE": "panel-config-enable"
63946     },
63947
63948     "UI": {
63949         "JQUERY_UI_BUTTON_CLASSES": "ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only",
63950         "JQUERY_UI_INPUT_CLASSES": "ui-state-default ui-corner-all",
63951         "PANEL_TABLE_CLASS": "panel-table",
63952         "RIGHT_RANGE_LABEL_CLASS": "range-label",
63953         "LEFT_RANGE_LABEL_CLASS": "range-label-left",
63954         "TEXT_LABEL_CLASS": "ui-text-label",
63955         "SCREEN_PPI": 96
63956     },
63957
63958     "MULTIMEDIA": {
63959         "AUDIO_STATES": {
63960             "OPENED": "opened",
63961             "STOPPED": "stopped",
63962             "PAUSED": "paused",
63963             "PLAYING": "playing",
63964             "COMPLETED": "completed"
63965         }
63966     },
63967
63968     "LANG": {
63969         "ISO6392_LIST": ["abk", "ace", "ach", "ada", "ady", "aar", "afh", "afr", "afa", "ain", "aka", "akk", "alb/sqi", "gsw", "ale", "alg", "tut", "amh", "anp", "apa", "ara", "arg", "arp", "arw", "arm/hye", "rup", "art", "asm", "ast", "ath", "aus", "map", "ava", "ave", "awa", "aym", "aze", "ban", "bat", "bal", "bam", "bai", "bad", "bnt", "bas", "bak", "baq/eus", "btk", "bej", "bel", "bem", "ben", "ber", "bho", "bih", "bik", "byn", "bin", "bis", "zbl", "nob", "bos", "bra", "bre", "bug", "bul", "bua", "bur/mya", "cad", "spa", "cat", "cau", "ceb", "cel", "cai", "khm", "chg", "cmc", "cha", "che", "chr", "nya", "chy", "chb", "chi/zho", "chn", "chp", "cho", "zha", "chu", "chk", "chv", "nwc", "syc", "rar", "cop", "cor", "cos", "cre", "mus", "crp", "cpe", "cpf", "cpp", "crh", "hrv", "cus", "cze/ces", "dak", "dan", "dar", "del", "div", "zza", "din", "doi", "dgr", "dra", "dua", "dut/nld", "dum", "dyu", "dzo", "frs", "efi", "egy", "eka", "elx", "eng", "enm", "ang", "myv", "epo", "est", "ewe", "ewo", "fan", "fat", "fao", "fij", "fil", "fin", "fiu", "fon", "fre/fra", "frm", "fro", "fur", "ful", "gaa", "gla", "car", "glg", "lug", "gay", "gba", "gez", "geo/kat", "ger/deu", "nds", "gmh", "goh", "gem", "kik", "gil", "gon", "gor", "got", "grb", "grc", "gre/ell", "kal", "grn", "guj", "gwi", "hai", "hat", "hau", "haw", "heb", "her", "hil", "him", "hin", "hmo", "hit", "hmn", "hun", "hup", "iba", "ice/isl", "ido", "ibo", "ijo", "ilo", "arc", "smn", "inc", "ine", "ind", "inh", "ina", "ile", "iku", "ipk", "ira", "gle", "mga", "sga", "iro", "ita", "jpn", "jav", "kac", "jrb", "jpr", "kbd", "kab", "xal", "kam", "kan", "kau", "pam", "kaa", "krc", "krl", "kar", "kas", "csb", "kaw", "kaz", "kha", "khi", "kho", "kmb", "kin", "kir", "tlh", "kom", "kon", "kok", "kor", "kos", "kpe", "kro", "kua", "kum", "kur", "kru", "kut", "lad", "lah", "lam", "day", "lao", "lat", "lav", "ltz", "lez", "lim", "lin", "lit", "jbo", "dsb", "loz", "lub", "lua", "lui", "smj", "lun", "luo", "lus", "mac/mkd", "mad", "mag", "mai", "mak", "mlg", "may/msa", "mal", "mlt", "mnc", "mdr", "man", "mni", "mno", "glv", "mao/mri", "arn", "mar", "chm", "mah", "mwr", "mas", "myn", "men", "mic", "min", "mwl", "moh", "mdf", "rum/ron", "mkh", "lol", "mon", "mos", "mul", "mun", "nqo", "nah", "nau", "nav", "nde", "nbl", "ndo", "nap", "new", "nep", "nia", "nic", "ssa", "niu", "zxx", "nog", "non", "nai", "frr", "sme", "nso", "nor", "nno", "nub", "iii", "nym", "nyn", "nyo", "nzi", "oci", "pro", "oji", "ori", "orm", "osa", "oss", "oto", "pal", "pau", "pli", "pag", "pan", "pap", "paa", "pus", "per/fas", "peo", "phi", "phn", "pon", "pol", "por", "pra", "que", "raj", "rap", "qaa-qtz", "roa", "roh", "rom", "run", "rus", "sal", "sam", "smi", "smo", "sad", "sag", "san", "sat", "srd", "sas", "sco", "sel", "sem", "srp", "srr", "shn", "sna", "scn", "sid", "sgn", "bla", "snd", "sin", "sit", "sio", "sms", "den", "sla", "slo/slk", "slv", "sog", "som", "son", "snk", "wen", "sot", "sai", "alt", "sma", "srn", "suk", "sux", "sun", "sus", "swa", "ssw", "swe", "syr", "tgl", "tah", "tai", "tgk", "tmh", "tam", "tat", "tel", "ter", "tet", "tha", "tib/bod", "tig", "tir", "tem", "tiv", "tli", "tpi", "tkl", "tog", "ton", "tsi", "tso", "tsn", "tum", "tup", "tur", "ota", "tuk", "tvl", "tyv", "twi", "udm", "uga", "uig", "ukr", "umb", "mis", "und", "hsb", "urd", "uzb", "vai", "ven", "vie", "vol", "vot", "wak", "wln", "war", "was", "wel/cym", "fry", "wal", "wol", "xho", "sah", "yao", "yap", "yid", "yor", "ypk", "znd", "zap", "zen", "zul", "zun"]
63970     },
63971
63972     "XHR": {
63973         "PROXY_DISABLED_BUTTON": "settings-xhrproxy-disabled"
63974     },
63975
63976     "PLATFORMS": {
63977         "WAC": {
63978             "APPLICATIONS": [
63979                 "ALARM",
63980                 "BROWSER",
63981                 "CALCULATOR",
63982                 "CALENDAR",
63983                 "CAMERA",
63984                 "CONTACTS",
63985                 "FILES",
63986                 "GAMES",
63987                 "MAIL",
63988                 "MEDIAPLAYER",
63989                 "MESSAGING",
63990                 "PHONECALL",
63991                 "PICTURES",
63992                 "PROG_MANAGER",
63993                 "SETTINGS",
63994                 "TASKS",
63995                 "WIDGET_MANAGER"
63996             ],
63997             "DEVICE": {
63998                 "WIDGET_ENGINE_NAME": "Generic",
63999                 "WIDGET_ENGINE_PROVIDER": "tinyHippos",
64000                 "WIDGET_ENGINE_VERSION": "x.x"
64001             }
64002         }
64003     },
64004
64005     "POWER_RESOURCE": {
64006         "SCREEN": {
64007             "NAME": "SCREEN",
64008             "STATE": {
64009                 "SCREEN_OFF": {
64010                     "NAME": "SCREEN_OFF",
64011                     "MIN": 0,
64012                     "MAX": 0,
64013                     "VALUE": 0
64014                 },
64015                 "SCREEN_DIM": {
64016                     "NAME": "SCREEN_DIM",
64017                     "MIN": 0,
64018                     "MAX": 0.2,
64019                     "VALUE": 0.15
64020                 },
64021                 "SCREEN_NORMAL": {
64022                     "NAME": "SCREEN_NORMAL",
64023                     "MIN": 0.2,
64024                     "MAX": 1,
64025                     "VALUE": 0.8
64026                 },
64027                 "SCREEN_BRIGHT": {
64028                     "NAME": "SCREEN_BRIGHT",
64029                     "MIN": 1,
64030                     "MAX": 1,
64031                     "VALUE": 1
64032                 }
64033             }
64034         },
64035         "CPU": {
64036             "NAME": "CPU",
64037             "STATE": {
64038                 "CPU_AWAKE": {
64039                     "NAME": "CPU_AWAKE",
64040                     "DEFAULT_VALUE" : 0.5
64041                 }
64042             }
64043         }
64044     }
64045 };
64046
64047 });
64048 define('ripple/db', function (require, exports, module) {
64049 /*
64050  *  Copyright 2011 Research In Motion Limited.
64051  *
64052  * Licensed under the Apache License, Version 2.0 (the "License");
64053  * you may not use this file except in compliance with the License.
64054  * You may obtain a copy of the License at
64055  *
64056  * http://www.apache.org/licenses/LICENSE-2.0
64057  *
64058  * Unless required by applicable law or agreed to in writing, software
64059  * distributed under the License is distributed on an "AS IS" BASIS,
64060  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64061  * See the License for the specific language governing permissions and
64062  * limitations under the License.
64063  */
64064 var _self,
64065     _db,
64066     utils = require('ripple/utils'),
64067     constants = require('ripple/constants'),
64068     event = require('ripple/event'),
64069     _cache = {};
64070
64071 function _validateAndSetPrefix(prefix) {
64072     if (prefix) {
64073         utils.validateArgumentType(prefix, "string");
64074     }
64075
64076     return prefix || constants.COMMON.PREFIX;
64077 }
64078
64079 function _createKey(key, prefix) {
64080     return _validateAndSetPrefix(prefix) + key;
64081 }
64082
64083 function _createItem(key, value, prefix) {
64084     return {
64085         id: _createKey(key, prefix),
64086         key: key,
64087         value: value,
64088         prefix: _validateAndSetPrefix(prefix)
64089     };
64090 }
64091
64092 function _save(key, value, prefix, callback) {
64093     var item = _createItem(key, value, prefix);
64094     _cache[item.id] = item;
64095
64096     _db.transaction(function (tx) {
64097         tx.executeSql('REPLACE INTO persistence (id, key, value, prefix) VALUES (?, ?, ?, ?)', [item.id, item.key, item.value, item.prefix], function () {
64098             return callback && callback();
64099         });
64100     });
64101 }
64102
64103 function _retrieve(key, prefix) {
64104     var item = _cache[_createKey(key, prefix)];
64105     return item ? item.value : undefined;
64106 }
64107
64108 function _retrieveAll(prefix, callback) {
64109     var result = {};
64110
64111     if (prefix) {
64112         utils.forEach(_cache, function (value, key) {
64113             if (value.prefix === prefix) {
64114                 result[value.key] = value.value;
64115             }
64116         });
64117     }
64118
64119     callback.apply(null, [result]);
64120 }
64121
64122 function _remove(key, prefix, callback) {
64123     delete _cache[_createKey(key, prefix)];
64124
64125     _db.transaction(function (tx) {
64126         tx.executeSql('DELETE FROM persistence WHERE key = ? AND prefix = ?', [key, _validateAndSetPrefix(prefix)], function () {
64127             return callback && callback();
64128         });
64129     });
64130 }
64131
64132 function _removeAll(prefix, callback) {
64133     utils.forEach(_cache, function (value, key) {
64134         if (!prefix || key.indexOf(prefix) === 0) {
64135             delete _cache[key];
64136         }
64137     });
64138
64139     _db.transaction(function (tx) {
64140         if (prefix) {
64141             tx.executeSql('DELETE FROM persistence WHERE prefix = ?', [prefix], function () {
64142                 return callback && callback();
64143             });
64144         } else {
64145             tx.executeSql('DELETE FROM persistence', [], function () {
64146                 return callback && callback();
64147             });
64148         }
64149     });
64150 }
64151
64152 _self = {
64153     save: function (key, value, prefix, callback) {
64154         _save(key, value, prefix, callback);
64155         event.trigger("StorageUpdatedEvent");
64156     },
64157
64158     saveObject: function (key, obj, prefix, callback) {
64159         _save(key, JSON.stringify(obj), prefix, callback);
64160         event.trigger("StorageUpdatedEvent");
64161     },
64162
64163     retrieve: function (key, prefix) {
64164         return _retrieve(key, prefix);
64165     },
64166
64167     retrieveObject: function (key, prefix) {
64168         var retrievedValue = _retrieve(key, prefix);
64169         return retrievedValue ? JSON.parse(retrievedValue) : retrievedValue;
64170     },
64171
64172     retrieveAll: function (prefix, callback) {
64173         return _retrieveAll(prefix, callback);
64174     },
64175
64176     remove: function (key, prefix, callback) {
64177         event.trigger("StorageUpdatedEvent");
64178         _remove(key, prefix, callback);
64179     },
64180
64181     removeAll: function (prefix, callback) {
64182         _removeAll(prefix, callback);
64183         event.trigger("StorageUpdatedEvent");
64184     },
64185
64186     initialize: function (previous, baton) {
64187         baton.take();
64188
64189         _db = openDatabase('tinyHippos', '1.0', 'tiny Hippos persistence', 2 * 1024 * 1024);
64190         _db.transaction(function (tx) {
64191             tx.executeSql('CREATE TABLE IF NOT EXISTS persistence (id unique, key, value, prefix)');
64192
64193             tx.executeSql('SELECT id, key, value, prefix FROM persistence', [], function (tx, results) {
64194                 var len = results.rows.length, i, item;
64195
64196                 for (i = 0; i < len; i++) {
64197                     item = results.rows.item(i);
64198                     _cache[item.id] = item;
64199                 }
64200
64201                 baton.pass();
64202             });
64203         });
64204     }
64205 };
64206
64207 module.exports = _self;
64208
64209 });
64210 define('ripple/dbfs', function (require, exports, module) {
64211 /*
64212  *  Copyright 2011 Research In Motion Limited.
64213  *
64214  * Licensed under the Apache License, Version 2.0 (the "License");
64215  * you may not use this file except in compliance with the License.
64216  * You may obtain a copy of the License at
64217  *
64218  * http://www.apache.org/licenses/LICENSE-2.0
64219  *
64220  * Unless required by applicable law or agreed to in writing, software
64221  * distributed under the License is distributed on an "AS IS" BASIS,
64222  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64223  * See the License for the specific language governing permissions and
64224  * limitations under the License.
64225  */
64226 var db = require('ripple/db'),
64227     utils = require('ripple/utils'),
64228     event = require('ripple/event'),
64229     _cache = {},
64230     _self;
64231
64232 function _get(path) {
64233     return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
64234         return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
64235     }, _cache);
64236 }
64237
64238 function _getInfo(path) {
64239     var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
64240         name = parent.splice(parent.length - 1, 1).join(""),
64241         ext = name.split(".");
64242
64243     return {
64244         name: name,
64245         extension: ext.length > 1 ? ext[ext.length - 1] : "",
64246         hidden: (name.length > 0 && name[0] === ".") || false,
64247         parent: parent.join("/") || "/"
64248     };
64249 }
64250
64251 function _set(path, obj) {
64252     var parent = _cache,
64253         tokens = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
64254         child = tokens.splice(tokens.length - 1, 1).join("");
64255
64256     tokens.forEach(function (token) {
64257         parent = parent.children[token];
64258     });
64259
64260     parent.children = parent.children || {};
64261     obj.properties = obj.properties || {};
64262     parent.children[child] = obj;
64263 }
64264
64265 function _delete(path) {
64266     var parent = _cache,
64267         tokens = path.replace(/^\//, '').split("/"),
64268         child = tokens.splice(tokens.length - 1, 1).join("");
64269
64270     tokens.forEach(function (token) {
64271         parent = parent.children[token];
64272     });
64273
64274     delete parent.children[child];
64275 }
64276
64277 function _save() {
64278     db.saveObject("db-filesystem", _cache);
64279 }
64280
64281 _self = {
64282
64283     initialize: function (prev, baton) {
64284         _cache = db.retrieveObject("db-filesystem") || {};
64285         event.trigger("FileSystemInitialized", null, true);
64286     },
64287
64288     ls: function (path, success, error) {
64289         try {
64290             var dir = _get(path),
64291                 items = [];
64292
64293             if (dir) {
64294                 utils.forEach(dir.children, function (item) {
64295                     if (!item.isDirectory) {
64296                         item.file = function (callback) {
64297                             callback({});
64298                         };
64299                     }
64300                     items.push(item);
64301                 });
64302             }
64303             else {
64304                 items = {};
64305             }
64306
64307             success(utils.copy(items));
64308         }
64309         catch (e) {
64310             e.code = 1;
64311             error(e);
64312         }
64313     },
64314
64315     rm: function (path, success, error, options) {
64316         _delete(path);
64317         _save();
64318         success();
64319     },
64320
64321     rmdir: function (path, success, error, options) {
64322         _delete(path);
64323         _save();
64324         success();
64325     },
64326
64327     mkdir: function (path, success, error) {
64328         var entry = _get(path),
64329             info = _getInfo(path);
64330
64331         if (!entry) {
64332             _set(path, {
64333                 name: info.name,
64334                 isDirectory: true,
64335                 fullPath: path
64336             });
64337             entry = _get(path);
64338         }
64339         
64340         _save();
64341         if (entry) {
64342             success(utils.copy(entry));
64343         }
64344         else {
64345             error({code: 1});
64346         }
64347     },
64348
64349     mv: function (from, to, success, error) {
64350         try {
64351             var fromEntry = _get(from),
64352                 toInfo = _getInfo(to);
64353
64354             fromEntry.fullPath = to;
64355             fromEntry.name = toInfo.name;
64356
64357             _set(to, fromEntry);
64358             _delete(from);
64359             _save();
64360             success(utils.copy(_get(to)));
64361         }
64362         catch (e) {
64363             e.code = 1;
64364             error(e);
64365         }
64366     },
64367
64368     touch: function (path, success, error) {
64369         if (!_get(path)) {
64370             _set(path, {
64371                 fullPath: path
64372             });
64373         }
64374         _save();
64375         success(utils.copy(_get(path)));
64376     },
64377
64378     cp: function (from, to, success, error) {
64379         try {
64380             var fromEntry = _get(from);
64381             fromEntry.fullPath = to;
64382             _set(to, fromEntry);
64383             _save();
64384             success(utils.copy(_get(to)));
64385         }
64386         catch (e) {
64387             e.code = 1;
64388             error(e);
64389         }
64390     },
64391
64392     stat: function (path, success, error) {
64393         var entry = _get(path);
64394         success(utils.copy(entry));
64395     },
64396
64397     write: function (path, contents, success, error, options) {
64398         var info = _getInfo(path);
64399
64400         _set(path, {
64401             lastModifiedDate: new Date(),
64402             name: info.name,
64403             fullPath: path,
64404             isDirectory: false,
64405             properties: {
64406                 type: "",
64407                 size: contents.size
64408             },
64409             data: contents,
64410             file: function (callback) {
64411                 callback({});
64412             }
64413         });
64414
64415         success(utils.copy(_get(path)));
64416     },
64417
64418     read: function (path, success, error) {
64419         var entry = _get(path);
64420
64421         if (entry) {
64422             success(utils.copy(entry.data));
64423         }
64424         else {
64425             error({code: 1});
64426         }
64427     }
64428 };
64429
64430 module.exports = _self;
64431
64432 });
64433 define('ripple/deviceMotionEmulator', function (require, exports, module) {
64434 /*
64435  *  Copyright 2011 Research In Motion Limited.
64436  *
64437  * Licensed under the Apache License, Version 2.0 (the "License");
64438  * you may not use this file except in compliance with the License.
64439  * You may obtain a copy of the License at
64440  *
64441  * http://www.apache.org/licenses/LICENSE-2.0
64442  *
64443  * Unless required by applicable law or agreed to in writing, software
64444  * distributed under the License is distributed on an "AS IS" BASIS,
64445  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64446  * See the License for the specific language governing permissions and
64447  * limitations under the License.
64448  */
64449
64450 var event = require('ripple/event'),
64451     platform = require('ripple/platform'),
64452     INTERVAL = 60000,
64453     _self;
64454
64455 function _bind(name, win) {
64456     var callback = null;
64457
64458     win.__defineGetter__(name, function () {
64459         return callback;
64460     });
64461
64462     win.__defineSetter__(name, function (cb) {
64463         callback = cb;
64464     });
64465
64466     return {
64467         get: function () {
64468             return callback;
64469         },
64470         set: function (value) {
64471             callback = value;
64472         },
64473         exec: function (arg) {
64474             return callback && callback(arg);
64475         },
64476         unbind: function (cb) {
64477             callback = cb === callback ? null : callback;
64478         }
64479     };
64480 }
64481
64482 _self = {
64483     init: function (win, doc) {
64484         var widgetWindow = win,
64485             _motion,
64486             _orientation,
64487             _calibration,
64488             add = widgetWindow.addEventListener,
64489             remove = widgetWindow.removeEventListener;
64490
64491         //Hang events off window (these are used to check for API existence by developer)
64492         widgetWindow.DeviceMotionEvent = function DeviceMotionEvent() {};
64493         widgetWindow.DeviceOrientationEvent = function DeviceOrientationEvent() {};
64494
64495         _motion = _bind("ondevicemotion", widgetWindow);
64496         _orientation = _bind("ondeviceorientation", widgetWindow);
64497         _calibration = _bind("oncompassneedscalibration", widgetWindow);
64498
64499         widgetWindow.addEventListener = function (e, callback, useCapture) {
64500             switch (e) {
64501             case "deviceorientation":
64502                 _orientation.set(callback);
64503                 event.trigger("DeviceOrientationEventAddedEvent");
64504                 break;
64505             case "devicemotion":
64506                 _motion.set(callback);
64507                 event.trigger("DeviceMotionEventAddedEvent");
64508                 break;
64509             case "compassneedscalibration":
64510                 _calibration.set(callback);
64511                 break;
64512
64513             default:
64514                 add.apply(widgetWindow, arguments);
64515                 break;
64516             }
64517         };
64518
64519         widgetWindow.removeEventListener = function (event, callback) {
64520             _motion.unbind(callback);
64521             _orientation.unbind(callback);
64522             _calibration.unbind(callback);
64523             remove.apply(widgetWindow, arguments);
64524         };
64525
64526         event.on("DeviceMotionEvent", function (motion) {
64527             var _motionEvent, DeviceMotionEvent;
64528
64529             if (platform.current().DeviceMotionEvent) {
64530                 DeviceMotionEvent = platform.current().DeviceMotionEvent;
64531                 if (typeof DeviceMotionEvent !== "function")
64532                     return;
64533
64534                 _motionEvent = new DeviceMotionEvent();
64535                 _motionEvent.initAccelerometerEvent("devicemotion", true, false, motion.acceleration, motion.accelerationIncludingGravity, 
64536                                                     motion.rotationRate, INTERVAL);    
64537             }
64538             else {
64539                 _motionEvent = {
64540                     acceleration: motion.acceleration,
64541                     accelerationIncludingGravity: motion.accelerationIncludingGravity,
64542                     rotationRate: motion.rotationRate
64543                 };
64544             }
64545
64546             _motion.exec(_motionEvent);
64547         });
64548
64549         event.on("DeviceOrientationEvent", function (motion) {
64550             var _orientationEvent, DeviceOrientationEvent;
64551
64552             if (platform.current().DeviceOrientationEvent) {
64553                 DeviceOrientationEvent = platform.current().DeviceOrientationEvent;
64554                 if (typeof DeviceOrientationEvent !== "function")
64555                     return;
64556
64557                 _orientationEvent = new DeviceOrientationEvent();        
64558                 _orientationEvent.initDeviceOrientationEvent("deviceorientation", true, false, motion.orientation.alpha, 
64559                                                               motion.orientation.beta, motion.orientation.gamma, true);
64560             }
64561             else {
64562                 _orientationEvent = motion.orientation;
64563             }
64564
64565             _orientation.exec(_orientationEvent);
64566         });
64567     }
64568 };
64569
64570 module.exports = _self;
64571
64572 });
64573 define('ripple/deviceSettings', function (require, exports, module) {
64574 /*
64575  *  Copyright 2011 Research In Motion Limited.
64576  *
64577  * Licensed under the Apache License, Version 2.0 (the "License");
64578  * you may not use this file except in compliance with the License.
64579  * You may obtain a copy of the License at
64580  *
64581  * http://www.apache.org/licenses/LICENSE-2.0
64582  *
64583  * Unless required by applicable law or agreed to in writing, software
64584  * distributed under the License is distributed on an "AS IS" BASIS,
64585  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64586  * See the License for the specific language governing permissions and
64587  * limitations under the License.
64588  */
64589 /* DeviceSettings
64590  *  A per object store for a platform's settings.
64591  *  For example, RadioInfo object in WAC has isRadioEnabled that can be true/false
64592  *  setting => {key: {key1: "test"}}
64593  */
64594 var _PERSISTENCE_KEY = "devicesettings",
64595     db = require('ripple/db'),
64596     platform = require('ripple/platform'),
64597     _currentDeviceSettings = {},
64598     _self;
64599
64600 function _default(key) {
64601     var keys = key.split("."),
64602         defaults = platform.current().device;
64603     if (keys.length === 1)
64604         return defaults[key];
64605     return keys.length === 2 &&
64606            defaults[keys[0]] &&
64607            defaults[keys[0]][keys[1]] &&
64608            defaults[keys[0]][keys[1]].control ?
64609            defaults[keys[0]][keys[1]].control.value : undefined;
64610 }
64611
64612 _self = {
64613     initialize: function () {
64614         // TODO: remove deprecated DeviceSettings from persisted ones.
64615         _currentDeviceSettings = db.retrieveObject(_PERSISTENCE_KEY) || {};
64616     },
64617     register: function (key, obj) {
64618         _currentDeviceSettings[key] = obj;
64619     },
64620
64621     persist: function (key, obj) {
64622         if (key) {
64623             _currentDeviceSettings[key] = obj;
64624         }
64625         db.saveObject(_PERSISTENCE_KEY, _currentDeviceSettings);
64626     },
64627
64628     retrieve: function (key) {
64629         return _currentDeviceSettings.hasOwnProperty(key) ?
64630                _currentDeviceSettings[key] : _default(key);
64631     },
64632
64633     retrieveAsInt: function (key) {
64634         return parseInt(_self.retrieve(key), 10);
64635     },
64636
64637     retrieveAsBoolean: function (key) {
64638         return !!_self.retrieve(key);
64639     }
64640 };
64641
64642 module.exports = _self;
64643
64644 });
64645 define('ripple/devices/Bold9700', function (require, exports, module) {
64646 /*
64647  *  Copyright 2011 Research In Motion Limited.
64648  *
64649  * Licensed under the Apache License, Version 2.0 (the "License");
64650  * you may not use this file except in compliance with the License.
64651  * You may obtain a copy of the License at
64652  *
64653  * http://www.apache.org/licenses/LICENSE-2.0
64654  *
64655  * Unless required by applicable law or agreed to in writing, software
64656  * distributed under the License is distributed on an "AS IS" BASIS,
64657  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64658  * See the License for the specific language governing permissions and
64659  * limitations under the License.
64660  */
64661 module.exports = {
64662
64663     "id": "Bold9700",
64664     "name": "BlackBerry Bold 9700",
64665     "model": "9700",
64666     "osName": "BlackBerry OS",
64667     "uuid": "42",
64668     "osVersion": "6",
64669     "manufacturer": "Research In Motion",
64670
64671     "skin": "Bold9700",
64672
64673     "capabilities": [
64674         "location.gps",
64675         "location.maps",
64676         "media.audio.capture",
64677         "media.video.capture",
64678         "media.recording",
64679         "storage.memorycard",
64680         "network.bluetooth",
64681         "network.wlan",
64682         "network.3gpp"
64683     ],
64684
64685     "screen": {
64686         "width": 480,
64687         "height": 360
64688     },
64689     "viewPort": {
64690         "portrait": {
64691             "width": 480,
64692             "height": 360,
64693             "paddingTop": 0,
64694             "paddingLeft": 0
64695         }
64696     },
64697
64698     "ppi": 245.00,
64699     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9700; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1",
64700     "platforms": ["web", "phonegap", "webworks.handset", "cordova"]
64701 };
64702
64703 });
64704 define('ripple/devices/Bold9900', function (require, exports, module) {
64705 /*
64706  *  Copyright 2011 Research In Motion Limited.
64707  *
64708  * Licensed under the Apache License, Version 2.0 (the "License");
64709  * you may not use this file except in compliance with the License.
64710  * You may obtain a copy of the License at
64711  *
64712  * http://www.apache.org/licenses/LICENSE-2.0
64713  *
64714  * Unless required by applicable law or agreed to in writing, software
64715  * distributed under the License is distributed on an "AS IS" BASIS,
64716  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64717  * See the License for the specific language governing permissions and
64718  * limitations under the License.
64719  */
64720 module.exports = {
64721
64722     "id": "Bold9900",
64723     "name": "BlackBerry Bold 9900",
64724     "model": "9900",
64725     "osName": "BlackBerry OS",
64726     "uuid": "42",
64727     "osVersion": "7",
64728     "manufacturer": "Research In Motion",
64729
64730     "skin": "Bold9900",
64731
64732     "capabilities": [
64733         "input.touch",
64734         "location.gps",
64735         "location.maps",
64736         "media.audio.capture",
64737         "media.video.capture",
64738         "media.recording",
64739         "storage.memorycard",
64740         "network.bluetooth",
64741         "network.wlan",
64742         "network.3gpp"
64743     ],
64744
64745     "screen": {
64746         "width": 640,
64747         "height": 480
64748     },
64749     "viewPort": {
64750         "portrait": {
64751             "width": 640,
64752             "height": 480,
64753             "paddingTop": 0,
64754             "paddingLeft": 0
64755         }
64756     },
64757
64758     "ppi": 287.00,
64759     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.141 Mobile Safari/534.1",
64760     "platforms": ["web", "phonegap", "webworks.handset", "cordova"]
64761 };
64762
64763 });
64764 define('ripple/devices/Colt', function (require, exports, module) {
64765 /*
64766  *  Copyright 2011 Research In Motion Limited.
64767  *
64768  * Licensed under the Apache License, Version 2.0 (the "License");
64769  * you may not use this file except in compliance with the License.
64770  * You may obtain a copy of the License at
64771  *
64772  * http://www.apache.org/licenses/LICENSE-2.0
64773  *
64774  * Unless required by applicable law or agreed to in writing, software
64775  * distributed under the License is distributed on an "AS IS" BASIS,
64776  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64777  * See the License for the specific language governing permissions and
64778  * limitations under the License.
64779  */
64780 module.exports = {
64781
64782     "id": "Colt",
64783     "name": "BlackBerry 10 Dev Alpha",
64784     "model": "Colt",
64785     "osName": "BlackBerry",
64786     "uuid": "42",
64787     "osVersion": "10.0.6.99",
64788     "manufacturer": "Research In Motion",
64789     "hardwareId": "0x8500240a",
64790
64791     "skin": "Colt",
64792
64793     "capabilities": [
64794         "input.touch",
64795         "location.gps",
64796         "media.audio.capture",
64797         "media.video.capture",
64798         "media.recording",
64799         "network.bluetooth",
64800         "network.wlan"
64801     ],
64802
64803     "screen": {
64804         "width": 768,
64805         "height": 1280
64806     },
64807     "viewPort": {
64808         "portrait": {
64809             "width": 768,
64810             "height": 1280,
64811             "paddingTop": 0,
64812             "paddingLeft": 0
64813         },
64814         "landscape": {
64815             "width": 1280,
64816             "height": 768,
64817             "paddingTop": 0,
64818             "paddingLeft": 0
64819         }
64820     },
64821
64822     "defaultOrientation": "portrait",
64823
64824     "ppi": 355,
64825     "userAgent": "Mozilla/5.0 (BlackBerry) AppleWebKit/536.2+ (KHTML, like Gecko) Version/10.0.4.182 Mobile Safari/536.2+",
64826     "platforms": ["web", "webworks.bb10", "cordova"]
64827 };
64828
64829 });
64830 define('ripple/devices/Curve9300', function (require, exports, module) {
64831 /*
64832  *  Copyright 2011 Research In Motion Limited.
64833  *
64834  * Licensed under the Apache License, Version 2.0 (the "License");
64835  * you may not use this file except in compliance with the License.
64836  * You may obtain a copy of the License at
64837  *
64838  * http://www.apache.org/licenses/LICENSE-2.0
64839  *
64840  * Unless required by applicable law or agreed to in writing, software
64841  * distributed under the License is distributed on an "AS IS" BASIS,
64842  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64843  * See the License for the specific language governing permissions and
64844  * limitations under the License.
64845  */
64846 module.exports = {
64847
64848     "id": "Curve9300",
64849     "name": "BlackBerry Curve 9300",
64850     "model": "9300",
64851     "osName": "BlackBerry OS",
64852     "uuid": "42",
64853     "osVersion": "6",
64854     "manufacturer": "Research In Motion",
64855
64856     "skin": "Curve9300",
64857
64858     "capabilities": [
64859         "location.gps",
64860         "location.maps",
64861         "media.audio.capture",
64862         "media.video.capture",
64863         "media.recording",
64864         "storage.memorycard",
64865         "network.bluetooth",
64866         "network.wlan",
64867         "network.3gpp"
64868     ],
64869
64870     "screen": {
64871         "width": 320,
64872         "height": 240
64873     },
64874     "viewPort": {
64875         "portrait": {
64876             "width": 320,
64877             "height": 240,
64878             "paddingTop": 0,
64879             "paddingLeft": 0
64880         }
64881     },
64882
64883     "ppi": 163,
64884     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9300; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+",
64885     "platforms": ["web", "phonegap", "webworks.handset"]
64886 };
64887
64888 });
64889 define('ripple/devices/Curve9350-9360-9370', function (require, exports, module) {
64890 /*
64891  *  Copyright 2011 Research In Motion Limited.
64892  *
64893  * Licensed under the Apache License, Version 2.0 (the "License");
64894  * you may not use this file except in compliance with the License.
64895  * You may obtain a copy of the License at
64896  *
64897  * http://www.apache.org/licenses/LICENSE-2.0
64898  *
64899  * Unless required by applicable law or agreed to in writing, software
64900  * distributed under the License is distributed on an "AS IS" BASIS,
64901  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64902  * See the License for the specific language governing permissions and
64903  * limitations under the License.
64904  */
64905 module.exports = {
64906
64907     "id": "Curve9350-9360-9370",
64908     "name": "BlackBerry Curve 9350/9360/9370",
64909     "model": "9350-9360-9370",
64910     "osName": "BlackBerry OS",
64911     "uuid": "42",
64912     "osVersion": "7",
64913     "manufacturer": "Research In Motion",
64914
64915     "skin": "Curve9350-9360-9370",
64916
64917     "capabilities": [
64918         "location.gps",
64919         "location.maps",
64920         "media.audio.capture",
64921         "media.video.capture",
64922         "media.recording",
64923         "storage.memorycard",
64924         "network.bluetooth",
64925         "network.wlan",
64926         "network.3gpp"
64927     ],
64928
64929     "screen": {
64930         "width": 480,
64931         "height": 360
64932     },
64933     "viewPort": {
64934         "portrait": {
64935             "width": 480,
64936             "height": 360,
64937             "paddingTop": 0,
64938             "paddingLeft": 0
64939         }
64940     },
64941
64942     "ppi": 246.00,
64943     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9350; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1",
64944     "platforms": ["web", "phonegap", "webworks.handset"]
64945 };
64946
64947 });
64948 define('ripple/devices/FWVGA', function (require, exports, module) {
64949 /*
64950  *  Copyright 2011 Research In Motion Limited.
64951  *
64952  * Licensed under the Apache License, Version 2.0 (the "License");
64953  * you may not use this file except in compliance with the License.
64954  * You may obtain a copy of the License at
64955  *
64956  * http://www.apache.org/licenses/LICENSE-2.0
64957  *
64958  * Unless required by applicable law or agreed to in writing, software
64959  * distributed under the License is distributed on an "AS IS" BASIS,
64960  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64961  * See the License for the specific language governing permissions and
64962  * limitations under the License.
64963  */
64964 module.exports = {
64965     "group": "Generic Devices",
64966
64967     "id": "FWVGA",
64968     "name": "Generic - FWVGA (480x854)",
64969     "osName": "Generic",
64970     "osVersion": "Generic",
64971     "manufacturer": "Generic",
64972     "model": "Generic",
64973     "uuid": "42",
64974
64975     "screen": {
64976         "width": 480,
64977         "height": 854
64978     },
64979     "viewPort": {
64980         "portrait": {
64981             "width": 480,
64982             "height": 854,
64983             "paddingTop": 0,
64984             "paddingLeft": 0
64985         },
64986         "landscape": {
64987             "width": 854,
64988             "height": 480,
64989             "paddingTop": 0,
64990             "paddingLeft": 0
64991         }
64992     },
64993
64994     "ppi": 96,
64995     "platforms": ["web", "phonegap", "cordova"],
64996     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
64997 };
64998
64999 });
65000 define('ripple/devices/G1', function (require, exports, module) {
65001 /*
65002  *  Copyright 2011 Research In Motion Limited.
65003  *
65004  * Licensed under the Apache License, Version 2.0 (the "License");
65005  * you may not use this file except in compliance with the License.
65006  * You may obtain a copy of the License at
65007  *
65008  * http://www.apache.org/licenses/LICENSE-2.0
65009  *
65010  * Unless required by applicable law or agreed to in writing, software
65011  * distributed under the License is distributed on an "AS IS" BASIS,
65012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65013  * See the License for the specific language governing permissions and
65014  * limitations under the License.
65015  */
65016 module.exports = {
65017
65018     "id": "G1",
65019     "name": "HTC G1",
65020     "model": "G1",
65021     "osName": "Android",
65022     "osVersion": "1.6",
65023     "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
65024     "manufacturer": "HTC",
65025
65026     "screen": {
65027         "width": 320,
65028         "height": 480
65029     },
65030     "viewPort": {
65031         "portrait": {
65032             "width": 320,
65033             "height": 480,
65034             "paddingTop": 0,
65035             "paddingLeft": 0
65036         },
65037         "landscape": {
65038             "width": 480,
65039             "height": 320,
65040             "paddingTop": 0,
65041             "paddingLeft": 0
65042         }
65043     },
65044
65045     "ppi": 180.28,
65046     "platforms": ["web", "phonegap"],
65047     "userAgent": "Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2",
65048
65049     "notes": {
65050         "1": "<a href=\"http://www.htc.com/www/product/g1/specification.html\" target=\"_blank\">Specs</a>"
65051     }
65052 };
65053
65054 });
65055 define('ripple/devices/HD', function (require, exports, module) {
65056 /*
65057  *  Copyright 2012 Intel Corporation
65058  *
65059  * Licensed under the Apache License, Version 2.0 (the "License");
65060  * you may not use this file except in compliance with the License.
65061  * You may obtain a copy of the License at
65062  *
65063  * http://www.apache.org/licenses/LICENSE-2.0
65064  *
65065  * Unless required by applicable law or agreed to in writing, software
65066  * distributed under the License is distributed on an "AS IS" BASIS,
65067  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65068  * See the License for the specific language governing permissions and
65069  * limitations under the License.
65070  */
65071
65072 module.exports = {
65073     "id": "HD",
65074     "name": "HD (720x1280)",
65075     "osName": "Generic",
65076     "osVersion": "Generic",
65077     "manufacturer": "Generic",
65078     "model": "Generic",
65079     "uuid": "42",
65080     "firmware": "Generic",
65081
65082     "screen": {
65083         "width": 720,
65084         "height": 1280
65085     },
65086     "viewPort": {
65087         "portrait": {
65088             "width": 720,
65089             "height": 1280,
65090             "paddingTop": 0,
65091             "paddingLeft": 0
65092         },
65093         "landscape": {
65094             "width": 1280,
65095             "height": 720,
65096             "paddingTop": 0,
65097             "paddingLeft": 0
65098         }
65099     },
65100
65101     "ppi": 316,
65102     "browser": ["Generic"],
65103     "platforms": ["wac", "web", "phonegap", "tizen", "cordova"],
65104     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
65105 };
65106
65107 });
65108 define('ripple/devices/HPPre3', function (require, exports, module) {
65109 /*
65110  *  Copyright 2011 Research In Motion Limited.
65111  *
65112  * Licensed under the Apache License, Version 2.0 (the "License");
65113  * you may not use this file except in compliance with the License.
65114  * You may obtain a copy of the License at
65115  *
65116  * http://www.apache.org/licenses/LICENSE-2.0
65117  *
65118  * Unless required by applicable law or agreed to in writing, software
65119  * distributed under the License is distributed on an "AS IS" BASIS,
65120  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65121  * See the License for the specific language governing permissions and
65122  * limitations under the License.
65123  */
65124 module.exports = {
65125     "id": "HPPre3",
65126     "name": "HP Pre 3",
65127     "manufacturer": "HP",
65128     "model": "Pre",
65129     "osName": "WebOS",
65130     "osVersion": "2.x",
65131
65132     "screen": {
65133         "width": 480,
65134         "height": 800
65135     },
65136     "viewPort": {
65137         "portrait": {
65138             "width": 480,
65139             "height": 800,
65140             "paddingTop": 0,
65141             "paddingLeft": 0
65142         },
65143         "landscape": {
65144             "width": 800,
65145             "height": 480,
65146             "paddingTop": 0,
65147             "paddingLeft": 0
65148         }
65149     },
65150
65151     "ppi": 260,
65152     // TODO :: not exactly the correct userAgent webkit version is probably different
65153     "userAgent": "Mozilla/5.0 (webOS/2.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/2.0",
65154     "platforms": ["web", "phonegap"],
65155
65156     "notes": {
65157         "1": "<a href=\"http://www.palm.com/us/products/phones/pre3/index.html\" target=\"_blank\">Specs</a>"
65158     }
65159 };
65160
65161 });
65162 define('ripple/devices/HPVeer', function (require, exports, module) {
65163 /*
65164  *  Copyright 2011 Research In Motion Limited.
65165  *
65166  * Licensed under the Apache License, Version 2.0 (the "License");
65167  * you may not use this file except in compliance with the License.
65168  * You may obtain a copy of the License at
65169  *
65170  * http://www.apache.org/licenses/LICENSE-2.0
65171  *
65172  * Unless required by applicable law or agreed to in writing, software
65173  * distributed under the License is distributed on an "AS IS" BASIS,
65174  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65175  * See the License for the specific language governing permissions and
65176  * limitations under the License.
65177  */
65178 module.exports = {
65179     "id": "HPVeer",
65180     "name": "HP Veer",
65181     "manufacturer": "HP",
65182     "model": "Veer",
65183     "osName": "WebOS",
65184     "osVersion": "2.x",
65185
65186     "screen": {
65187         "width": 320,
65188         "height": 400
65189     },
65190     "viewPort": {
65191         "portrait": {
65192             "width": 320,
65193             "height": 400,
65194             "paddingTop": 0,
65195             "paddingLeft": 0
65196         },
65197         "landscape": {
65198             "width": 400,
65199             "height": 320,
65200             "paddingTop": 0,
65201             "paddingLeft": 0
65202         }
65203     },
65204
65205     "ppi": 197,
65206     // TODO :: not exactly the correct userAgent webkit version is probably different
65207     "userAgent": "Mozilla/5.0 (webOS/2.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/2.0",
65208     "platforms": ["web", "phonegap"],
65209
65210     "notes": {
65211         "1": "<a href=\"http://www.palm.com/us/products/phones/veer/index.html\" target=\"_blank\">Specs</a>"
65212     }
65213 };
65214
65215 });
65216 define('ripple/devices/HVGA', function (require, exports, module) {
65217 /*
65218  *  Copyright 2011 Research In Motion Limited.
65219  *
65220  * Licensed under the Apache License, Version 2.0 (the "License");
65221  * you may not use this file except in compliance with the License.
65222  * You may obtain a copy of the License at
65223  *
65224  * http://www.apache.org/licenses/LICENSE-2.0
65225  *
65226  * Unless required by applicable law or agreed to in writing, software
65227  * distributed under the License is distributed on an "AS IS" BASIS,
65228  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65229  * See the License for the specific language governing permissions and
65230  * limitations under the License.
65231  */
65232 module.exports = {
65233     "group": "Generic Devices",
65234
65235     "id": "HVGA",
65236     "name": "HVGA (320x480)",
65237     "osName": "Generic",
65238     "osVersion": "Generic",
65239     "manufacturer": "Generic",
65240     "model": "Generic",
65241     "uuid": "42",
65242
65243     "screen": {
65244         "width": 320,
65245         "height": 480
65246     },
65247     "viewPort": {
65248         "portrait": {
65249             "width": 320,
65250             "height": 480,
65251             "paddingTop": 0,
65252             "paddingLeft": 0
65253         },
65254         "landscape": {
65255             "width": 480,
65256             "height": 320,
65257             "paddingTop": 0,
65258             "paddingLeft": 0
65259         }
65260     },
65261
65262     "ppi": 316,
65263     "platforms": ["wac", "web", "phonegap", "tizen", "cordova"],
65264     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
65265 };
65266
65267 });
65268 define('ripple/devices/IVI-HD', function (require, exports, module) {
65269 /*
65270  *  Copyright 2012 Intel Corporation
65271  *
65272  * Licensed under the Apache License, Version 2.0 (the "License");
65273  * you may not use this file except in compliance with the License.
65274  * You may obtain a copy of the License at
65275  *
65276  * http://www.apache.org/licenses/LICENSE-2.0
65277  *
65278  * Unless required by applicable law or agreed to in writing, software
65279  * distributed under the License is distributed on an "AS IS" BASIS,
65280  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65281  * See the License for the specific language governing permissions and
65282  * limitations under the License.
65283  */
65284
65285 module.exports = {
65286     "id": "IVI-HD",
65287     "name": "IVI HD (800x480)",
65288     "osName": "Generic",
65289     "osVersion": "Generic",
65290     "manufacturer": "Tizen",
65291     "model": "Generic",
65292     "uuid": "42",
65293     "firmware": "Generic",
65294
65295     "screen": {
65296         "width": 800,
65297         "height": 480
65298     },
65299     "viewPort": {
65300         "portrait": {
65301             "width": 1024,
65302             "height": 640,
65303             "paddingTop": 0,
65304             "paddingLeft": 0
65305         },
65306         "landscape": {
65307             "width": 640,
65308             "height": 1024,
65309             "paddingTop": 0,
65310             "paddingLeft": 0
65311         }
65312     },
65313
65314     "ppi": 316,
65315     "browser": ["Generic"],
65316     "platforms": ["ivi"],
65317     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
65318 };
65319
65320 });
65321 define('ripple/devices/Legend', function (require, exports, module) {
65322 /*
65323  *  Copyright 2011 Research In Motion Limited.
65324  *
65325  * Licensed under the Apache License, Version 2.0 (the "License");
65326  * you may not use this file except in compliance with the License.
65327  * You may obtain a copy of the License at
65328  *
65329  * http://www.apache.org/licenses/LICENSE-2.0
65330  *
65331  * Unless required by applicable law or agreed to in writing, software
65332  * distributed under the License is distributed on an "AS IS" BASIS,
65333  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65334  * See the License for the specific language governing permissions and
65335  * limitations under the License.
65336  */
65337 module.exports = {
65338     "id": "Legend",
65339     "name": "HTC Legend",
65340     "osName": "Android",
65341     "osVersion": "1.6",
65342     "manufacturer": "HTC",
65343     "model": "Legend",
65344     "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
65345
65346     "screen": {
65347         "width": 320,
65348         "height": 480
65349     },
65350     "viewPort": {
65351         "portrait": {
65352             "width": 320,
65353             "height": 480,
65354             "paddingTop": 0,
65355             "paddingLeft": 0
65356         },
65357         "landscape": {
65358             "width": 480,
65359             "height": 320,
65360             "paddingTop": 0,
65361             "paddingLeft": 0
65362         }
65363     },
65364
65365     "ppi": 180.3,
65366     "userAgent": "Mozilla/5.0 (Linux; U; Android 2.1; fr-fr; HTC Legend 1.32.163.1 Build/ERD79) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17",
65367     "platforms": ["web", "phonegap"]
65368 };
65369
65370 });
65371 define('ripple/devices/Nexus', function (require, exports, module) {
65372 /*
65373  *  Copyright 2011 Research In Motion Limited.
65374  *
65375  * Licensed under the Apache License, Version 2.0 (the "License");
65376  * you may not use this file except in compliance with the License.
65377  * You may obtain a copy of the License at
65378  *
65379  * http://www.apache.org/licenses/LICENSE-2.0
65380  *
65381  * Unless required by applicable law or agreed to in writing, software
65382  * distributed under the License is distributed on an "AS IS" BASIS,
65383  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65384  * See the License for the specific language governing permissions and
65385  * limitations under the License.
65386  */
65387 module.exports = {
65388     "id": "Nexus",
65389     "name": "Nexus One",
65390     "manufacturer": "HTC",
65391     "model": "Nexux One",
65392     "osName": "Android",
65393     "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
65394     "osVersion": "2.x.x",
65395
65396     "screen": {
65397         "width": 480,
65398         "height": 800
65399     },
65400     "viewPort": {
65401         "portrait": {
65402             "width": 480,
65403             "height": 800,
65404             "paddingTop": 0,
65405             "paddingLeft": 0
65406         },
65407         "landscape": {
65408             "width": 800,
65409             "height": 480,
65410             "paddingTop": 0,
65411             "paddingLeft": 0
65412         }
65413     },
65414
65415     "ppi": 252.15,
65416     "userAgent": "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17",
65417     "platforms": ["web", "phonegap"],
65418
65419     "notes": {
65420         "1": "<a href=\"http://www.google.com/phone/static/en_US-nexusone_tech_specs.html\" target=\"_blank\">Specs</a>"
65421     }
65422 };
65423
65424 });
65425 define('ripple/devices/Nexus7', function (require, exports, module) {
65426 /*
65427  *  Copyright 2011 Research In Motion Limited.
65428  *
65429  * Licensed under the Apache License, Version 2.0 (the "License");
65430  * you may not use this file except in compliance with the License.
65431  * You may obtain a copy of the License at
65432  *
65433  * http://www.apache.org/licenses/LICENSE-2.0
65434  *
65435  * Unless required by applicable law or agreed to in writing, software
65436  * distributed under the License is distributed on an "AS IS" BASIS,
65437  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65438  * See the License for the specific language governing permissions and
65439  * limitations under the License.
65440  */
65441 module.exports = {
65442     "id" : "Nexus7",
65443     "name": "Nexus 7 (Tablet)",
65444     "manufacturer": "Asus",
65445     "model": "Nexus 7 8/16 GB",
65446     "osName": "Android",
65447     "uuid" : "903802EA-1786-4175-B0F1-1FDF87813CAA",
65448     "osVersion": "4.x.x",
65449
65450     "screen": {
65451         "width": 800,
65452         "height": 1280
65453     },
65454     "viewPort": {
65455         "portrait": {
65456             "width": 800,
65457             "height": 1280,
65458             "paddingTop": 0,
65459             "paddingLeft": 0
65460         },
65461         "landscape": {
65462             "width": 1280,
65463             "height": 800,
65464             "paddingTop": 0,
65465             "paddingLeft": 0
65466         }
65467     },
65468
65469     "ppi": 215,
65470     "userAgent": "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166  Safari/535.19",
65471     "platforms": ["web", "phonegap", "cordova"],
65472
65473     "notes": {
65474         "1": "<a href=\"http://www.google.com/nexus/#/7/specs\" target=\"_blank\">Specs</a>"
65475     }
65476
65477 };
65478
65479 });
65480 define('ripple/devices/NexusGalaxy', function (require, exports, module) {
65481 /*
65482  *  Copyright 2011 Research In Motion Limited.
65483  *
65484  * Licensed under the Apache License, Version 2.0 (the "License");
65485  * you may not use this file except in compliance with the License.
65486  * You may obtain a copy of the License at
65487  *
65488  * http://www.apache.org/licenses/LICENSE-2.0
65489  *
65490  * Unless required by applicable law or agreed to in writing, software
65491  * distributed under the License is distributed on an "AS IS" BASIS,
65492  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65493  * See the License for the specific language governing permissions and
65494  * limitations under the License.
65495  */
65496 module.exports = {
65497     "id" : "NexusGalaxy",
65498     "name": "Nexus (Galaxy)",
65499     "manufacturer": "Samsung",
65500     "model": "Galaxy Nexus (generic)",
65501     "osName": "Android",
65502     "uuid" : "3D0AD03B-8B46-431A-BEF5-FF01B96BA990",
65503     "osVersion": "4.x.x",
65504
65505     "screen": {
65506         "width": 720,
65507         "height": 1280
65508     },
65509     "viewPort": {
65510         "portrait": {
65511             "width": 720,
65512             "height": 1280,
65513             "paddingTop": 0,
65514             "paddingLeft": 0
65515         },
65516         "landscape": {
65517             "width": 1280,
65518             "height": 720,
65519             "paddingTop": 0,
65520             "paddingLeft": 0
65521         }
65522     },
65523
65524     "ppi": 315,
65525     "userAgent": "Mozilla/5.0 (Linux; Android 4.0.1; Galaxy Nexus Build/ITL41F) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
65526     "platforms": ["web", "phonegap", "cordova"],
65527
65528     "notes": {
65529         "1": "<a href=\"http://www.google.com/nexus/#/tech-specs\" target=\"_blank\">Specs</a>"
65530     }
65531
65532 };
65533
65534 });
65535 define('ripple/devices/NexusS', function (require, exports, module) {
65536 /*
65537  *  Copyright 2011 Research In Motion Limited.
65538  *
65539  * Licensed under the Apache License, Version 2.0 (the "License");
65540  * you may not use this file except in compliance with the License.
65541  * You may obtain a copy of the License at
65542  *
65543  * http://www.apache.org/licenses/LICENSE-2.0
65544  *
65545  * Unless required by applicable law or agreed to in writing, software
65546  * distributed under the License is distributed on an "AS IS" BASIS,
65547  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65548  * See the License for the specific language governing permissions and
65549  * limitations under the License.
65550  */
65551 module.exports = {
65552     "id" : "NexusS",
65553     "name": "Nexus S",
65554     "manufacturer": "Samsung",
65555     "model": "Nexux S",
65556     "osName": "Android",
65557     "uuid" : "F54E13F1-C1B7-4212-BFA8-AB3C9C3F088F",
65558     "osVersion": "2.3.x",
65559
65560     "screen": {
65561         "width": 480,
65562         "height": 800
65563     },
65564     "viewPort": {
65565         "portrait": {
65566             "width": 480,
65567             "height": 800,
65568             "paddingTop": 0,
65569             "paddingLeft": 0
65570         },
65571         "landscape": {
65572             "width": 800,
65573             "height": 480,
65574             "paddingTop": 0,
65575             "paddingLeft": 0
65576         }
65577     },
65578
65579     "ppi": 235,
65580     "userAgent": "Mozilla/5.0 (Linux; U; Android 2.3.2; en-us; Nexus S Build/GRH78C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
65581     "platforms": ["web", "phonegap", "cordova"],
65582
65583     "notes": {
65584         "1": "<a href=\"http://www.google.com/nexus/#/tech-specs\" target=\"_blank\">Specs</a>"
65585     }
65586
65587 };
65588
65589 });
65590 define('ripple/devices/NokiaN8', function (require, exports, module) {
65591 /*
65592  *  Copyright 2011 Research In Motion Limited.
65593  *
65594  * Licensed under the Apache License, Version 2.0 (the "License");
65595  * you may not use this file except in compliance with the License.
65596  * You may obtain a copy of the License at
65597  *
65598  * http://www.apache.org/licenses/LICENSE-2.0
65599  *
65600  * Unless required by applicable law or agreed to in writing, software
65601  * distributed under the License is distributed on an "AS IS" BASIS,
65602  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65603  * See the License for the specific language governing permissions and
65604  * limitations under the License.
65605  */
65606 module.exports = {
65607
65608     "id": "NokiaN8",
65609     "name": "Nokia N8",
65610     "model": "N8",
65611     "osName": "SymbianOS",
65612     "uuid": "42",
65613     "osVersion": "3",
65614     "manufacturer": "Nokia",
65615
65616     "screen": {
65617         "width": 360,
65618         "height": 640
65619     },
65620     "viewPort": {
65621         "portrait": {
65622             "width": 360,
65623             "height": 640,
65624             "paddingTop": 0,
65625             "paddingLeft": 0
65626         },
65627         "landscape": {
65628             "width": 640,
65629             "height": 360,
65630             "paddingTop": 0,
65631             "paddingLeft": 0
65632         }
65633     },
65634
65635     "ppi": 209.8,
65636     "userAgent": "(Symbian/3; S60/5.2 Mozilla/5.0; NokiaN8-00/10.0.000; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.2",
65637     "platforms": ["web", "phonegap"],
65638
65639     "notes": {
65640         "1": "<a href=\"http://www.forum.nokia.com/Devices/Device_specifications/N8-00/\" target=\"_blank\">Specs</a>"
65641     }
65642 };
65643
65644 });
65645 define('ripple/devices/NokiaN97', function (require, exports, module) {
65646 /*
65647  *  Copyright 2011 Research In Motion Limited.
65648  *
65649  * Licensed under the Apache License, Version 2.0 (the "License");
65650  * you may not use this file except in compliance with the License.
65651  * You may obtain a copy of the License at
65652  *
65653  * http://www.apache.org/licenses/LICENSE-2.0
65654  *
65655  * Unless required by applicable law or agreed to in writing, software
65656  * distributed under the License is distributed on an "AS IS" BASIS,
65657  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65658  * See the License for the specific language governing permissions and
65659  * limitations under the License.
65660  */
65661 module.exports = {
65662     "id": "NokiaN97",
65663     "name": "Nokia N97/5800 (touch)",
65664     "manufacturer": "Nokia",
65665     "model": "N97",
65666     "osName": "S60",
65667     "osVersion": "v5",
65668     "uuid": "42",
65669
65670     "screen": {
65671         "width": 360,
65672         "height": 640
65673     },
65674     "viewPort": {
65675         "portrait": {
65676             "width": 360,
65677             "height": 640,
65678             "paddingTop": 0,
65679             "paddingLeft": 0
65680         },
65681         "landscape": {
65682             "width": 640,
65683             "height": 360,
65684             "paddingTop": 0,
65685             "paddingLeft": 0
65686         }
65687     },
65688
65689     "ppi": 232,
65690     "userAgent": "?",
65691     "platforms": ["web", "phonegap"]
65692 };
65693
65694 });
65695 define('ripple/devices/PalmPre', function (require, exports, module) {
65696 /*
65697  *  Copyright 2011 Research In Motion Limited.
65698  *
65699  * Licensed under the Apache License, Version 2.0 (the "License");
65700  * you may not use this file except in compliance with the License.
65701  * You may obtain a copy of the License at
65702  *
65703  * http://www.apache.org/licenses/LICENSE-2.0
65704  *
65705  * Unless required by applicable law or agreed to in writing, software
65706  * distributed under the License is distributed on an "AS IS" BASIS,
65707  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65708  * See the License for the specific language governing permissions and
65709  * limitations under the License.
65710  */
65711 module.exports = {
65712     "id": "PalmPre",
65713     "name": "Palm Pre",
65714     "manufacturer": "Palm",
65715     "model": "Pre",
65716     "osName": "WebOS",
65717     "osVersion": "1.x",
65718
65719     "screen": {
65720         "width": 320,
65721         "height": 480
65722     },
65723     "viewPort": {
65724         "portrait": {
65725             "width": 320,
65726             "height": 480,
65727             "paddingTop": 0,
65728             "paddingLeft": 0
65729         },
65730         "landscape": {
65731             "width": 480,
65732             "height": 320,
65733             "paddingTop": 0,
65734             "paddingLeft": 0
65735         }
65736     },
65737
65738     "ppi": 186.09,
65739     "userAgent": "Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0",
65740     "platforms": ["web", "phonegap"],
65741
65742     "notes": {
65743         "1": "<a href=\"http://www.palm.com/us/products/phones/pre/#tab2\" target=\"_blank\">Specs</a>"
65744     }
65745 };
65746
65747 });
65748 define('ripple/devices/PalmPre2', function (require, exports, module) {
65749 /*
65750  *  Copyright 2011 Research In Motion Limited.
65751  *
65752  * Licensed under the Apache License, Version 2.0 (the "License");
65753  * you may not use this file except in compliance with the License.
65754  * You may obtain a copy of the License at
65755  *
65756  * http://www.apache.org/licenses/LICENSE-2.0
65757  *
65758  * Unless required by applicable law or agreed to in writing, software
65759  * distributed under the License is distributed on an "AS IS" BASIS,
65760  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65761  * See the License for the specific language governing permissions and
65762  * limitations under the License.
65763  */
65764 module.exports = {
65765     "id": "PalmPre2",
65766     "name": "Palm Pre 2",
65767     "manufacturer": "Palm",
65768     "model": "Pre",
65769     "osName": "WebOS",
65770     "osVersion": "2.x",
65771
65772     "screen": {
65773         "width": 320,
65774         "height": 480
65775     },
65776     "viewPort": {
65777         "portrait": {
65778             "width": 320,
65779             "height": 480,
65780             "paddingTop": 0,
65781             "paddingLeft": 0
65782         },
65783         "landscape": {
65784             "width": 480,
65785             "height": 320,
65786             "paddingTop": 0,
65787             "paddingLeft": 0
65788         }
65789     },
65790
65791     "ppi": 186.09,
65792     // TODO :: not exactly the correct userAgent webkit version is probably different
65793     "userAgent": "Mozilla/5.0 (webOS/2.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/2.0",
65794     "platforms": ["web", "phonegap"],
65795
65796     "notes": {
65797         "1": "<a href=\"http://www.palm.com/us/products/phones/pre2/#tab2\" target=\"_blank\">Specs</a>"
65798     }
65799 };
65800
65801 });
65802 define('ripple/devices/Pearl9100', function (require, exports, module) {
65803 /*
65804  *  Copyright 2011 Research In Motion Limited.
65805  *
65806  * Licensed under the Apache License, Version 2.0 (the "License");
65807  * you may not use this file except in compliance with the License.
65808  * You may obtain a copy of the License at
65809  *
65810  * http://www.apache.org/licenses/LICENSE-2.0
65811  *
65812  * Unless required by applicable law or agreed to in writing, software
65813  * distributed under the License is distributed on an "AS IS" BASIS,
65814  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65815  * See the License for the specific language governing permissions and
65816  * limitations under the License.
65817  */
65818 module.exports = {
65819
65820     "id": "Pearl9100",
65821     "name": "BlackBerry Pearl 9100",
65822     "model": "9100",
65823     "osName": "BlackBerry OS",
65824     "uuid": "42",
65825     "osVersion": "6",
65826     "manufacturer": "Research In Motion",
65827
65828     "skin": "Pearl9100",
65829
65830     "capabilities": [
65831         "input.keyboard.issuretype",
65832         "location.gps",
65833         "location.maps",
65834         "media.audio.capture",
65835         "media.video.capture",
65836         "media.recording",
65837         "storage.memorycard",
65838         "network.bluetooth",
65839         "network.wlan",
65840         "network.3gpp"
65841     ],
65842
65843     "screen": {
65844         "width": 360,
65845         "height": 400
65846     },
65847     "viewPort": {
65848         "portrait": {
65849             "width": 360,
65850             "height": 400,
65851             "paddingTop": 0,
65852             "paddingLeft": 0
65853         }
65854     },
65855
65856     "ppi": 239,
65857     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9100; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+",
65858     "platforms": ["web", "phonegap", "webworks.handset"]
65859 };
65860
65861 });
65862 define('ripple/devices/Playbook', function (require, exports, module) {
65863 /*
65864  *  Copyright 2011 Research In Motion Limited.
65865  *
65866  * Licensed under the Apache License, Version 2.0 (the "License");
65867  * you may not use this file except in compliance with the License.
65868  * You may obtain a copy of the License at
65869  *
65870  * http://www.apache.org/licenses/LICENSE-2.0
65871  *
65872  * Unless required by applicable law or agreed to in writing, software
65873  * distributed under the License is distributed on an "AS IS" BASIS,
65874  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65875  * See the License for the specific language governing permissions and
65876  * limitations under the License.
65877  */
65878 module.exports = {
65879
65880     "id": "Playbook",
65881     "name": "BlackBerry Playbook",
65882     "model": "100669958",
65883     "osName": "BlackBerry PlayBook OS",
65884     "uuid": "42",
65885     "osVersion": "BlackBerry PlayBook OS",
65886     "manufacturer": "Research In Motion",
65887
65888     "skin": "Playbook",
65889
65890     "capabilities": [
65891         "input.touch",
65892         "location.gps",
65893         "media.audio.capture",
65894         "media.video.capture",
65895         "media.recording",
65896         "network.bluetooth",
65897         "network.wlan"
65898     ],
65899
65900     "screen": {
65901         "width": 1024,
65902         "height": 600
65903     },
65904     "viewPort": {
65905         "portrait": {
65906             "width": 1024,
65907             "height": 600,
65908             "paddingTop": 0,
65909             "paddingLeft": 0
65910         },
65911         "landscape": {
65912             "width": 600,
65913             "height": 1024,
65914             "paddingTop": 0,
65915             "paddingLeft": 0
65916         }
65917     },
65918
65919     "defaultOrientation": "landscape",
65920
65921     "ppi": 169.55,
65922     "userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+",
65923     "platforms": ["web", "webworks.tablet", "phonegap", "cordova"]
65924 };
65925
65926 });
65927 define('ripple/devices/QVGA', function (require, exports, module) {
65928 /*
65929  *  Copyright 2011 Research In Motion Limited.
65930  *
65931  * Licensed under the Apache License, Version 2.0 (the "License");
65932  * you may not use this file except in compliance with the License.
65933  * You may obtain a copy of the License at
65934  *
65935  * http://www.apache.org/licenses/LICENSE-2.0
65936  *
65937  * Unless required by applicable law or agreed to in writing, software
65938  * distributed under the License is distributed on an "AS IS" BASIS,
65939  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65940  * See the License for the specific language governing permissions and
65941  * limitations under the License.
65942  */
65943 module.exports = {
65944     "id": "QVGA",
65945     "name": "Generic - QVGA (240X320)",
65946     "osName": "Generic",
65947     "osVersion": "Generic",
65948     "manufacturer": "Generic",
65949     "model": "Generic",
65950     "uuid": "42",
65951
65952     "screen": {
65953         "width": 240,
65954         "height": 320
65955     },
65956     "viewPort": {
65957         "portrait": {
65958             "width": 240,
65959             "height": 320,
65960             "paddingTop": 0,
65961             "paddingLeft": 0
65962         },
65963         "landscape": {
65964             "width": 320,
65965             "height": 240,
65966             "paddingTop": 0,
65967             "paddingLeft": 0
65968         }
65969     },
65970
65971     "ppi": 96,
65972     "platforms": ["web", "phonegap", "cordova", "tizen"],
65973     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
65974 };
65975
65976 });
65977 define('ripple/devices/Style9670', function (require, exports, module) {
65978 /*
65979  *  Copyright 2011 Research In Motion Limited.
65980  *
65981  * Licensed under the Apache License, Version 2.0 (the "License");
65982  * you may not use this file except in compliance with the License.
65983  * You may obtain a copy of the License at
65984  *
65985  * http://www.apache.org/licenses/LICENSE-2.0
65986  *
65987  * Unless required by applicable law or agreed to in writing, software
65988  * distributed under the License is distributed on an "AS IS" BASIS,
65989  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65990  * See the License for the specific language governing permissions and
65991  * limitations under the License.
65992  */
65993 module.exports = {
65994
65995     "id": "Style9670",
65996     "name": "BlackBerry Style 9670",
65997     "model": "9670",
65998     "osName": "BlackBerry OS",
65999     "uuid": "42",
66000     "osVersion": "6",
66001     "manufacturer": "Research In Motion",
66002
66003     "skin": "Style9670",
66004
66005     "capabilities": [
66006         "location.gps",
66007         "location.maps",
66008         "media.audio.capture",
66009         "media.video.capture",
66010         "media.recording",
66011         "storage.memorycard",
66012         "network.bluetooth",
66013         "network.wlan",
66014         "network.3gpp"
66015     ],
66016
66017     "screen": {
66018         "width": 360,
66019         "height": 400
66020     },
66021     "viewPort": {
66022         "portrait": {
66023             "width": 360,
66024             "height": 400,
66025             "paddingTop": 0,
66026             "paddingLeft": 0
66027         }
66028     },
66029
66030     "ppi": 200,
66031     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9670; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+",
66032     "platforms": ["web", "phonegap", "webworks.handset"]
66033 };
66034
66035 });
66036 define('ripple/devices/Tattoo', function (require, exports, module) {
66037 /*
66038  *  Copyright 2011 Research In Motion Limited.
66039  *
66040  * Licensed under the Apache License, Version 2.0 (the "License");
66041  * you may not use this file except in compliance with the License.
66042  * You may obtain a copy of the License at
66043  *
66044  * http://www.apache.org/licenses/LICENSE-2.0
66045  *
66046  * Unless required by applicable law or agreed to in writing, software
66047  * distributed under the License is distributed on an "AS IS" BASIS,
66048  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66049  * See the License for the specific language governing permissions and
66050  * limitations under the License.
66051  */
66052 module.exports = {
66053     "id": "Tattoo",
66054     "name": "HTC Tattoo",
66055     "manufacturer": "HTC",
66056     "model": "Tattoo",
66057     "osVersion": "1.6",
66058     "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
66059     "osName": "Android",
66060
66061     "screen": {
66062         "width": 240,
66063         "height": 320
66064     },
66065     "viewPort": {
66066         "portrait": {
66067             "width": 240,
66068             "height": 320,
66069             "paddingTop": 0,
66070             "paddingLeft": 0
66071         }
66072     },
66073
66074     "ppi": 142.9,
66075     "userAgent": "Mozilla/5.0 (Linux; U; Android 1.6; en-us; HTC_TATTOO_A3288 Build/DRC79) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1",
66076     "platforms": ["web", "phonegap"]
66077 };
66078
66079 });
66080 define('ripple/devices/Torch9800', function (require, exports, module) {
66081 /*
66082  *  Copyright 2011 Research In Motion Limited.
66083  *
66084  * Licensed under the Apache License, Version 2.0 (the "License");
66085  * you may not use this file except in compliance with the License.
66086  * You may obtain a copy of the License at
66087  *
66088  * http://www.apache.org/licenses/LICENSE-2.0
66089  *
66090  * Unless required by applicable law or agreed to in writing, software
66091  * distributed under the License is distributed on an "AS IS" BASIS,
66092  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66093  * See the License for the specific language governing permissions and
66094  * limitations under the License.
66095  */
66096 module.exports = {
66097
66098     "id": "Torch9800",
66099     "name": "BlackBerry Torch 9800",
66100     "model": "9800",
66101     "osName": "BlackBerry OS",
66102     "uuid": "42",
66103     "osVersion": "6",
66104     "manufacturer": "Research In Motion",
66105
66106     "skin": "Torch9800",
66107
66108     "capabilities": [
66109         "input.touch",
66110         "location.gps",
66111         "location.maps",
66112         "media.audio.capture",
66113         "media.video.capture",
66114         "media.recording",
66115         "storage.memorycard",
66116         "network.bluetooth",
66117         "network.wlan",
66118         "network.3gpp"
66119     ],
66120
66121     "screen": {
66122         "width": 360,
66123         "height": 480
66124     },
66125     "viewPort": {
66126         "portrait": {
66127             "width": 360,
66128             "height": 480,
66129             "paddingTop": 0,
66130             "paddingLeft": 0
66131         },
66132         "landscape": {
66133             "width": 480,
66134             "height": 360,
66135             "paddingTop": 0,
66136             "paddingLeft": 0
66137         }
66138     },
66139
66140     "ppi": 188.68,
66141     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1",
66142     "platforms": ["web", "phonegap", "webworks.handset"]
66143 };
66144
66145 });
66146 define('ripple/devices/Torch9810', function (require, exports, module) {
66147 /*
66148  *  Copyright 2011 Research In Motion Limited.
66149  *
66150  * Licensed under the Apache License, Version 2.0 (the "License");
66151  * you may not use this file except in compliance with the License.
66152  * You may obtain a copy of the License at
66153  *
66154  * http://www.apache.org/licenses/LICENSE-2.0
66155  *
66156  * Unless required by applicable law or agreed to in writing, software
66157  * distributed under the License is distributed on an "AS IS" BASIS,
66158  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66159  * See the License for the specific language governing permissions and
66160  * limitations under the License.
66161  */
66162 module.exports = {
66163
66164     "id": "Torch9810",
66165     "name": "BlackBerry Torch 9810",
66166     "model": "9810",
66167     "osName": "BlackBerry OS",
66168     "uuid": "42",
66169     "osVersion": "7",
66170     "manufacturer": "Research In Motion",
66171
66172     "skin": "Torch9810",
66173
66174     "capabilities": [
66175         "input.touch",
66176         "location.gps",
66177         "location.maps",
66178         "media.audio.capture",
66179         "media.video.capture",
66180         "media.recording",
66181         "storage.memorycard",
66182         "network.bluetooth",
66183         "network.wlan",
66184         "network.3gpp"
66185     ],
66186
66187     "screen": {
66188         "width": 480,
66189         "height": 640
66190     },
66191     "viewPort": {
66192         "portrait": {
66193             "width": 480,
66194             "height": 640,
66195             "paddingTop": 0,
66196             "paddingLeft": 0
66197         },
66198         "landscape": {
66199             "width": 640,
66200             "height": 480,
66201             "paddingTop": 0,
66202             "paddingLeft": 0
66203         }
66204     },
66205
66206     "ppi": 253,
66207     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9810; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1",
66208     "platforms": ["web", "phonegap", "webworks.handset"]
66209 };
66210
66211 });
66212 define('ripple/devices/Torch9860-9850', function (require, exports, module) {
66213 /*
66214  *  Copyright 2011 Research In Motion Limited.
66215  *
66216  * Licensed under the Apache License, Version 2.0 (the "License");
66217  * you may not use this file except in compliance with the License.
66218  * You may obtain a copy of the License at
66219  *
66220  * http://www.apache.org/licenses/LICENSE-2.0
66221  *
66222  * Unless required by applicable law or agreed to in writing, software
66223  * distributed under the License is distributed on an "AS IS" BASIS,
66224  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66225  * See the License for the specific language governing permissions and
66226  * limitations under the License.
66227  */
66228 module.exports = {
66229
66230     "id": "Torch9860-9850",
66231     "name": "BlackBerry Torch 9860/9850",
66232     "model": "9860-9850",
66233     "osName": "BlackBerry OS",
66234     "uuid": "42",
66235     "osVersion": "7",
66236     "manufacturer": "Research In Motion",
66237
66238     "skin": "Torch9860-9850",
66239
66240     "capabilities": [
66241         "input.touch",
66242         "location.gps",
66243         "location.maps",
66244         "media.audio.capture",
66245         "media.video.capture",
66246         "media.recording",
66247         "storage.memorycard",
66248         "network.bluetooth",
66249         "network.wlan",
66250         "network.3gpp"
66251     ],
66252
66253     "screen": {
66254         "width": 480,
66255         "height": 800
66256     },
66257     "viewPort": {
66258         "portrait": {
66259             "width": 480,
66260             "height": 800,
66261             "paddingTop": 0,
66262             "paddingLeft": 0
66263         },
66264         "landscape": {
66265             "width": 800,
66266             "height": 480,
66267             "paddingTop": 0,
66268             "paddingLeft": 0
66269         }
66270     },
66271
66272     "ppi": 253,
66273     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9860; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1",
66274     "platforms": ["web", "phonegap", "webworks.handset"]
66275 };
66276
66277 });
66278 define('ripple/devices/WQVGA', function (require, exports, module) {
66279 /*
66280  *  Copyright 2011 Research In Motion Limited.
66281  *
66282  * Licensed under the Apache License, Version 2.0 (the "License");
66283  * you may not use this file except in compliance with the License.
66284  * You may obtain a copy of the License at
66285  *
66286  * http://www.apache.org/licenses/LICENSE-2.0
66287  *
66288  * Unless required by applicable law or agreed to in writing, software
66289  * distributed under the License is distributed on an "AS IS" BASIS,
66290  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66291  * See the License for the specific language governing permissions and
66292  * limitations under the License.
66293  */
66294 module.exports = {
66295     "id": "WQVGA",
66296     "name": "Generic - WQVGA (240x480)",
66297     "osName": "Generic",
66298     "osVersion": "Generic",
66299     "manufacturer": "Generic",
66300     "model": "Generic",
66301     "uuid": "42",
66302
66303     "screen": {
66304         "width": 240,
66305         "height": 480
66306     },
66307     "viewPort": {
66308         "portrait": {
66309             "width": 240,
66310             "height": 480,
66311             "paddingTop": 0,
66312             "paddingLeft": 0
66313         },
66314         "landscape": {
66315             "width": 480,
66316             "height": 240,
66317             "paddingTop": 0,
66318             "paddingLeft": 0
66319         }
66320     },
66321
66322     "ppi": 96,
66323     "browser": ["Generic"],
66324     "platforms": ["web", "phonegap", "tizen"],
66325     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
66326 };
66327
66328 });
66329 define('ripple/devices/WSVGA', function (require, exports, module) {
66330 /*
66331  *  Copyright 2011 Research In Motion Limited.
66332  *
66333  * Licensed under the Apache License, Version 2.0 (the "License");
66334  * you may not use this file except in compliance with the License.
66335  * You may obtain a copy of the License at
66336  *
66337  * http://www.apache.org/licenses/LICENSE-2.0
66338  *
66339  * Unless required by applicable law or agreed to in writing, software
66340  * distributed under the License is distributed on an "AS IS" BASIS,
66341  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66342  * See the License for the specific language governing permissions and
66343  * limitations under the License.
66344  */
66345 module.exports = {
66346     "id": "WSVGA",
66347     "name": "WSVGA (600x1024)",
66348     "osName": "Generic",
66349     "osVersion": "Generic",
66350     "manufacturer": "Generic",
66351     "model": "Generic",
66352     "uuid": "42",
66353     "firmware": "Generic",
66354
66355     "screen": {
66356         "width": 600,
66357         "height": 1024
66358     },
66359     "viewPort": {
66360         "portrait": {
66361             "width": 600,
66362             "height": 1024,
66363             "paddingTop": 0,
66364             "paddingLeft": 0
66365         },
66366         "landscape": {
66367             "width": 1024,
66368             "height": 600,
66369             "paddingTop": 0,
66370             "paddingLeft": 0
66371         }
66372     },
66373
66374     "ppi": 316,
66375     "browser": ["Generic"],
66376     "platforms": ["wac", "web", "phonegap", "tizen", "cordova"],
66377     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
66378 };
66379
66380 });
66381 define('ripple/devices/WVGA', function (require, exports, module) {
66382 /*
66383  *  Copyright 2011 Research In Motion Limited.
66384  *
66385  * Licensed under the Apache License, Version 2.0 (the "License");
66386  * you may not use this file except in compliance with the License.
66387  * You may obtain a copy of the License at
66388  *
66389  * http://www.apache.org/licenses/LICENSE-2.0
66390  *
66391  * Unless required by applicable law or agreed to in writing, software
66392  * distributed under the License is distributed on an "AS IS" BASIS,
66393  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66394  * See the License for the specific language governing permissions and
66395  * limitations under the License.
66396  */
66397 module.exports = {
66398     "id": "WVGA",
66399     "name": "WVGA (480x800)",
66400     "osName": "Generic",
66401     "osVersion": "Generic",
66402     "manufacturer": "Generic",
66403     "model": "Generic",
66404     "uuid": "42",
66405
66406     "screen": {
66407         "width": 480,
66408         "height": 800
66409     },
66410     "viewPort": {
66411         "portrait": {
66412             "width": 480,
66413             "height": 800,
66414             "paddingTop": 0,
66415             "paddingLeft": 0
66416         },
66417         "landscape": {
66418             "width": 800,
66419             "height": 480,
66420             "paddingTop": 0,
66421             "paddingLeft": 0
66422         }
66423     },
66424
66425     "ppi": 316,
66426     "browser": ["Generic"],
66427     "platforms": ["web", "phonegap", "tizen", "cordova"],
66428     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
66429 };
66430
66431 });
66432 define('ripple/devices/Wave', function (require, exports, module) {
66433 /*
66434  *  Copyright 2011 Research In Motion Limited.
66435  *
66436  * Licensed under the Apache License, Version 2.0 (the "License");
66437  * you may not use this file except in compliance with the License.
66438  * You may obtain a copy of the License at
66439  *
66440  * http://www.apache.org/licenses/LICENSE-2.0
66441  *
66442  * Unless required by applicable law or agreed to in writing, software
66443  * distributed under the License is distributed on an "AS IS" BASIS,
66444  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66445  * See the License for the specific language governing permissions and
66446  * limitations under the License.
66447  */
66448 module.exports = {
66449     "id": "Wave",
66450     "name": "Samsung Wave",
66451     "manufacturer": "Samsung",
66452     "model": "Wave",
66453     "osName": "Bada",
66454     "osVersion": "n/a",
66455
66456     "screen": {
66457         "width": 480,
66458         "height": 800
66459     },
66460     "viewPort": {
66461         "portrait": {
66462             "width": 480,
66463             "height": 800,
66464             "paddingTop": 0,
66465             "paddingLeft": 0
66466         },
66467         "landscape": {
66468             "width": 800,
66469             "height": 480,
66470             "paddingTop": 0,
66471             "paddingLeft": 0
66472         }
66473     },
66474
66475     "ppi": 283,
66476     "userAgent": "?",
66477     "platforms": ["web"]
66478 };
66479
66480 });
66481 define('ripple/devices/custom', function (require, exports, module) {
66482 /*
66483  *  Copyright 2012 Intel Corporation
66484  *
66485  * Licensed under the Apache License, Version 2.0 (the "License");
66486  * you may not use this file except in compliance with the License.
66487  * You may obtain a copy of the License at
66488  *
66489  * http://www.apache.org/licenses/LICENSE-2.0
66490  *
66491  * Unless required by applicable law or agreed to in writing, software
66492  * distributed under the License is distributed on an "AS IS" BASIS,
66493  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66494  * See the License for the specific language governing permissions and
66495  * limitations under the License.
66496  */
66497
66498 module.exports = {
66499     "id": "CUSTOM",
66500     "name": "Custom",
66501     "osName": "Generic",
66502     "osVersion": "Generic",
66503     "manufacturer": "Generic",
66504     "model": "Generic",
66505     "uuid": "42",
66506     "firmware": "Generic",
66507
66508     "screen": {
66509         "width": 600,
66510         "height": 800
66511     },
66512     "viewPort": {
66513         "portrait": {
66514             "width": 600,
66515             "height": 800,
66516             "paddingTop": 0,
66517             "paddingLeft": 0
66518         },
66519         "landscape": {
66520             "width": 600,
66521             "height": 800,
66522             "paddingTop": 0,
66523             "paddingLeft": 0
66524         }
66525     },
66526
66527     "ppi": 316,
66528     "browser": ["Generic"],
66529     "platforms": [],
66530     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
66531 };
66532
66533 });
66534 define('ripple/devices/iPad', function (require, exports, module) {
66535 /*
66536  *  Copyright 2011 Research In Motion Limited.
66537  *
66538  * Licensed under the Apache License, Version 2.0 (the "License");
66539  * you may not use this file except in compliance with the License.
66540  * You may obtain a copy of the License at
66541  *
66542  * http://www.apache.org/licenses/LICENSE-2.0
66543  *
66544  * Unless required by applicable law or agreed to in writing, software
66545  * distributed under the License is distributed on an "AS IS" BASIS,
66546  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66547  * See the License for the specific language governing permissions and
66548  * limitations under the License.
66549  */
66550 module.exports = {
66551
66552     "id": "iPad",
66553     "name": "iPad",
66554     "model": "iPad",
66555     "osName": "iOS",
66556     "uuid": "e0101010d38bde8e6740011221af335301010333",
66557     "osVersion": "1.6",
66558     "manufacturer": "Apple",
66559
66560     "screen": {
66561         "width": 768,
66562         "height": 1024
66563     },
66564     "viewPort": {
66565         "portrait": {
66566             "width": 768,
66567             "height": 1024,
66568             "paddingTop": 0,
66569             "paddingLeft": 0
66570         },
66571         "landscape": {
66572             "width": 1024,
66573             "height": 768,
66574             "paddingTop": 0,
66575             "paddingLeft": 0
66576         }
66577     },
66578
66579     "ppi": 132,
66580     "userAgent": "Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10",
66581     "platforms": ["web", "phonegap", "cordova"],
66582
66583     "notes": {
66584         "1": "<a href=\"http://www.apple.com/ipad/specs/\" target=\"_blank\">Specs</a>"
66585     }
66586 };
66587
66588 });
66589 define('ripple/devices/iPhone3', function (require, exports, module) {
66590 /*
66591  *  Copyright 2011 Research In Motion Limited.
66592  *
66593  * Licensed under the Apache License, Version 2.0 (the "License");
66594  * you may not use this file except in compliance with the License.
66595  * You may obtain a copy of the License at
66596  *
66597  * http://www.apache.org/licenses/LICENSE-2.0
66598  *
66599  * Unless required by applicable law or agreed to in writing, software
66600  * distributed under the License is distributed on an "AS IS" BASIS,
66601  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66602  * See the License for the specific language governing permissions and
66603  * limitations under the License.
66604  */
66605 module.exports = {
66606
66607     "id": "iPhone3",
66608     "name": "iPhone 3G/3Gs/4/4s",
66609     "model": "3G",
66610     "osName": "iPhone",
66611     "osVersion": "3",
66612     "uuid": "e0101010d38bde8e6740011221af335301010333",
66613     "manufacturer": "Apple",
66614
66615     "screen": {
66616         "width": 320,
66617         "height": 480
66618     },
66619     "viewPort": {
66620         "portrait": {
66621             "width": 320,
66622             "height": 480,
66623             "paddingTop": 0,
66624             "paddingLeft": 0
66625         },
66626         "landscape": {
66627             "width": 480,
66628             "height": 320,
66629             "paddingTop": 0,
66630             "paddingLeft": 0
66631         }
66632     },
66633
66634     "ppi": 164.8,
66635     "userAgent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/1A542a Safari/419.3",
66636     "platforms": ["web", "phonegap", "cordova"]
66637 };
66638
66639 });
66640 define('ripple/devices/tizen-HD', function (require, exports, module) {
66641 /*
66642  *  Copyright 2012 Intel Corporation
66643  *
66644  * Licensed under the Apache License, Version 2.0 (the "License");
66645  * you may not use this file except in compliance with the License.
66646  * You may obtain a copy of the License at
66647  *
66648  * http://www.apache.org/licenses/LICENSE-2.0
66649  *
66650  * Unless required by applicable law or agreed to in writing, software
66651  * distributed under the License is distributed on an "AS IS" BASIS,
66652  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66653  * See the License for the specific language governing permissions and
66654  * limitations under the License.
66655  */
66656
66657 module.exports = {
66658     "id": "tizen-HD",
66659     "name": "Tizen HD (720x1280)",
66660     "osName": "Generic",
66661     "osVersion": "Generic",
66662     "manufacturer": "Tizen",
66663     "model": "Generic",
66664     "uuid": "42",
66665     "firmware": "Generic",
66666
66667     "screen": {
66668         "width": 720,
66669         "height": 1280
66670     },
66671     "viewPort": {
66672         "portrait": {
66673             "width": 360,
66674             "height": 640,
66675             "paddingTop": 0,
66676             "paddingLeft": 0
66677         },
66678         "landscape": {
66679             "width": 640,
66680             "height": 360,
66681             "paddingTop": 0,
66682             "paddingLeft": 0
66683         }
66684     },
66685
66686     "ppi": 316,
66687     "browser": ["Generic"],
66688     "platforms": ["wac", "web", "phonegap", "tizen", "cordova"],
66689     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
66690 };
66691
66692 });
66693 define('ripple/devices/tizen-WVGA', function (require, exports, module) {
66694 /*
66695  *  Copyright 2011 Research In Motion Limited.
66696  *
66697  * Licensed under the Apache License, Version 2.0 (the "License");
66698  * you may not use this file except in compliance with the License.
66699  * You may obtain a copy of the License at
66700  *
66701  * http://www.apache.org/licenses/LICENSE-2.0
66702  *
66703  * Unless required by applicable law or agreed to in writing, software
66704  * distributed under the License is distributed on an "AS IS" BASIS,
66705  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66706  * See the License for the specific language governing permissions and
66707  * limitations under the License.
66708  */
66709 module.exports = {
66710     "id": "tizen-WVGA",
66711     "name": "Tizen WVGA (480x800)",
66712     "osName": "Generic",
66713     "osVersion": "Generic",
66714     "manufacturer": "Tizen",
66715     "model": "Generic",
66716     "uuid": "42",
66717
66718     "screen": {
66719         "width": 480,
66720         "height": 800
66721     },
66722     "viewPort": {
66723         "portrait": {
66724             "width": 320,
66725             "height": 534,
66726             "paddingTop": 0,
66727             "paddingLeft": 0
66728         },
66729         "landscape": {
66730             "width": 534,
66731             "height": 320,
66732             "paddingTop": 0,
66733             "paddingLeft": 0
66734         }
66735     },
66736
66737     "ppi": 316,
66738     "browser": ["Generic"],
66739     "platforms": ["web", "phonegap", "tizen", "cordova"],
66740     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
66741 };
66742
66743 });
66744 define('ripple/devices', function (require, exports, module) {
66745 /*
66746  *  Copyright 2011 Research In Motion Limited.
66747  *
66748  * Licensed under the Apache License, Version 2.0 (the "License");
66749  * you may not use this file except in compliance with the License.
66750  * You may obtain a copy of the License at
66751  *
66752  * http://www.apache.org/licenses/LICENSE-2.0
66753  *
66754  * Unless required by applicable law or agreed to in writing, software
66755  * distributed under the License is distributed on an "AS IS" BASIS,
66756  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66757  * See the License for the specific language governing permissions and
66758  * limitations under the License.
66759  */
66760 var _self,
66761     db = require('ripple/db'),
66762     utils = require('ripple/utils'),
66763     platform = require('ripple/platform'),
66764     event = require('ripple/event'),
66765     _devices = {};
66766
66767 event.on("HardwareKeyDefault", function (key) {
66768     if (key === 0 || key === "0") { //back button key
66769         require('ripple/emulatorBridge').window().history.back();
66770     }
66771 });
66772
66773 _self = module.exports = {
66774     initialize: function () {
66775         _devices = [
66776 /* 
66777            "Bold9700",
66778             "Bold9900",
66779             "Colt",
66780             "Curve9300",
66781             "Curve9350-9360-9370",
66782             "FWVGA",
66783             "G1",
66784 */          "IVI-HD",
66785             "tizen-WVGA",
66786 /*
66787             "HPPre3",
66788             "HPVeer",
66789 */
66790 //            "HVGA",
66791 /*
66792             "iPad",
66793             "iPhone3",
66794             "Legend",
66795             "Nexus",
66796             "NexusS",
66797             "NexusGalaxy",
66798             "Nexus7",
66799             "NokiaN8",
66800             "NokiaN97",
66801             "PalmPre",
66802             "PalmPre2",
66803             "Pearl9100",
66804             "Playbook",
66805             "QVGA",
66806             "Style9670",
66807             "Tattoo",
66808             "Torch9800",
66809             "Torch9810",
66810             "Torch9860-9850",
66811             "Wave",
66812             "WQVGA",
66813 */
66814 //            "WSVGA",
66815             "WVGA",
66816             "HD",
66817             "tizen-HD",
66818             "custom"
66819         ].reduce(function (hash, deviceID) {
66820             hash[deviceID] = require('ripple/devices/' + deviceID);
66821             return hash;
66822         }, {});
66823
66824         var current = this.getCurrentDevice();
66825         require('ripple/bus').send('userAgent', current.userAgent);
66826     },
66827
66828     getCurrentDevice: function () {
66829         var deviceId = db.retrieve("device-key"),
66830             device = this.getDevice(deviceId),
66831             platformId = platform.current().id,
66832             does = function (device) {
66833                 return {
66834                     include: function (platformId) {
66835                         return device.platforms.some(function (id) {
66836                             return platformId === id;
66837                         });
66838                     }
66839                 };
66840             };
66841
66842         if (deviceId !== "custom" && (!device || !does(device).include(platformId))) {
66843             deviceId = utils.reduce(_devices, function (current, device, id) {
66844                 return does(device).include(platformId) ? id : current;
66845             });
66846             device = this.getDevice(deviceId);
66847         }
66848
66849         return device;
66850     },
66851
66852     getDevice: function (deviceId) {
66853         var device, width, height, viewportWidth, viewportHeight, layout, viewportTag, ratio;
66854
66855         device = _devices[deviceId] ? utils.copy(_devices[deviceId]) : null;
66856         width = db.retrieve("custom_width") || 600;
66857         height = db.retrieve("custom_height") || 800;
66858         viewportTag = db.retrieveObject("viewportTag");
66859         layout = db.retrieve("layout") || "portrait" ;
66860
66861         if (deviceId === undefined)
66862             return null;
66863         width =  parseInt(width, 10);
66864         height =  parseInt(height, 10);
66865
66866         if (viewportTag !== undefined) {
66867             if (viewportTag['width'] !== undefined) {
66868                 if (viewportTag['width'] === "device-width") {
66869                     viewportWidth = device.viewPort[layout].width;
66870                 } else if (viewportTag['width'] === "device-height") {
66871                     viewportWidth = device.viewPort[layout].height;
66872                 }
66873                 else {
66874                     viewportWidth = parseInt(viewportTag['width'], 10);
66875                     if (isNaN(viewportWidth)) {
66876                         viewportWidth = device.viewPort[layout].width;
66877                     }
66878                 }
66879                 db.saveObject("viewport_width", viewportWidth);
66880
66881                 if (layout === "portrait") {
66882                     if (deviceId !== "custom") {
66883                         ratio = device.screen.height / device.screen.width;
66884                     } else {
66885                         ratio = height / width;
66886                     }
66887                     viewportHeight = viewportWidth * ratio;
66888                     db.saveObject("viewport_height", viewportHeight);
66889                 } else {
66890                     if (deviceId !== "custom") {
66891                         ratio = device.screen.width / device.screen.height;
66892                     } else {
66893                         ratio = width / height;
66894                     }
66895                     viewportHeight = viewportWidth * ratio;
66896                     db.saveObject("viewport_height", viewportHeight);
66897                 }
66898             } else if(viewportTag['height'] !== undefined) {
66899                 if (viewportTag['height'] === "device-height") {
66900                     viewportHeight = device.viewPort[layout].height;
66901                 } else if (viewportTag['height'] === "device-width") {
66902                     viewportHeight = device.viewPort[layout].width;
66903                 }
66904                 else {
66905                     viewportHeight = parseInt(viewportTag['height'], 10);
66906                     if (isNaN(viewportHeight)) {
66907                         viewportHeight = device.viewPort[layout].height;
66908                     }
66909                 }
66910                 db.saveObject("viewport_height", viewportHeight);
66911
66912                 if (layout === "portrait") {
66913                     if (deviceId !== "custom") {
66914                         ratio = device.screen.height / device.screen.width;
66915                     } else {
66916                         ratio = height / width;
66917                     }
66918                     viewportWidth = viewportHeight / ratio;
66919                     db.saveObject("viewport_width", viewportWidth);
66920                 } else {
66921                     if (deviceId !== "custom") {
66922                         ratio = device.screen.width / device.screen.height;
66923                     } else {
66924                         ratio = width / height;
66925                     }
66926                     viewportWidth = viewportHeight / ratio;
66927                     db.saveObject("viewport_width", viewportWidth);
66928                 }
66929             }
66930         }
66931
66932         if (viewportWidth === undefined) {
66933             if (deviceId === "custom") {
66934                 viewportWidth = width;
66935             } else {
66936                 viewportWidth = device.viewPort[layout].width;
66937             }
66938         }
66939
66940         if (viewportHeight === undefined) {
66941             if (deviceId === "custom") {
66942                 viewportHeight = height;
66943             } else {
66944                 viewportHeight = device.viewPort[layout].height;
66945             }
66946         }
66947
66948         $('#resolution-custom-width').val(width);
66949         $('#resolution-custom-height').val(height);
66950
66951         if (deviceId === "custom") {
66952             device.screen.width = width;
66953             device.screen.height = height;
66954             $('input:radio[name="resolution-type"][value="custom"]').click();
66955         }
66956
66957         if (layout === "portrait") {
66958             device.viewPort.portrait.width = viewportWidth;
66959             device.viewPort.portrait.height = viewportHeight;
66960             device.viewPort.landscape.width = viewportHeight;
66961             device.viewPort.landscape.height = viewportWidth;
66962         } else {
66963             device.viewPort.portrait.width = viewportHeight;
66964             device.viewPort.portrait.height = viewportWidth;
66965             device.viewPort.landscape.width = viewportWidth;
66966             device.viewPort.landscape.height = viewportHeight;
66967         }
66968         return device;
66969     },
66970
66971     getDevicesForPlatform: function (platformId) {
66972         return utils.filter(_devices, function (device) {
66973             return device.platforms.indexOf(platformId) > -1;
66974         });
66975     }
66976 };
66977
66978 });
66979 define('ripple/documentEventListener', function (require, exports, module) {
66980 /*
66981  *  Copyright 2012 Intel Corporation.
66982  *
66983  * Licensed under the Apache License, Version 2.0 (the "License");
66984  * you may not use this file except in compliance with the License.
66985  * You may obtain a copy of the License at
66986  *
66987  * http://www.apache.org/licenses/LICENSE-2.0
66988  *
66989  * Unless required by applicable law or agreed to in writing, software
66990  * distributed under the License is distributed on an "AS IS" BASIS,
66991  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66992  * See the License for the specific language governing permissions and
66993  * limitations under the License.
66994  */
66995
66996 var event = require('ripple/event'),
66997     constants = require('ripple/constants'),
66998     deviceSettings = require('ripple/deviceSettings'),
66999     ui = require('ripple/ui'),
67000     _self,
67001     _ComWinShow = false;
67002
67003 function _bind(name, win) {
67004     var _listeners = [];
67005
67006     return {
67007         add: function (callback, useCapture) {
67008             // ignore non-function
67009             if (typeof callback === "function") {
67010                 // ignore useCapture as we could not handle it
67011                 if (!useCapture) {
67012                     if (!_listeners.some(function (listener) {
67013                         return (listener === callback);
67014                     })) {
67015                         _listeners.push(callback);
67016                     }
67017                 }
67018             }
67019         },
67020         exec: function (arg) {
67021             _listeners.forEach(function (listener) {
67022                 listener.apply(win, arg);
67023             });
67024         },
67025         remove: function (callback, useCapture) {
67026             // ignore non-function
67027             if (typeof callback === "function") {
67028                 // ignore useCapture as we do not add them into _listeners
67029                 if (!useCapture) {
67030                     _listeners = _listeners.filter(function (listener) {
67031                         return (listener !== callback);
67032                     });
67033                 }
67034             }
67035         }
67036     };
67037 }
67038
67039 function _isComWinSHow() {
67040     return _ComWinShow;
67041 }
67042
67043 _self = {
67044     mask: function (frame, doc) {
67045         /* 
67046          * The current issue is that "document.addEventListener(visibilitychange, function(){...})" 
67047          * does not work if it is invoked in the document.DOMContentLoaded listeners, for example, at 
67048          * JQuery(document).ready function.
67049
67050          * The reason is that window.DOMContentLoaded is fired after the document.DOMContentLoaded. 
67051          * Currently we have not found a proper event to override the document.addEventListener. 
67052          * The beforeload is fine for window.addEventListener, while does not work for document.addEventListener 
67053          * because the contentDocument will be reset after loading. 
67054          */
67055         frame.addEventListener("DOMContentLoaded", function () {
67056             var widgetDocument = doc,
67057                 _pageVisibility,
67058                 add = widgetDocument.addEventListener,
67059                 remove = widgetDocument.removeEventListener;
67060
67061             widgetDocument.PAGE_HIDDEN  = "hidden";
67062             widgetDocument.PAGE_VISIBLE = "visible";
67063             widgetDocument.PAGE_PREVIEW = "preview";
67064
67065             function _lockScreen(on) {
67066                 var hidden = on;
67067
67068                 if (on) {
67069                     ui.showOverlay("lock-screen-window", function (background) {});
67070                 } else {
67071                     ui.hideOverlay("lock-screen-window", function (background) {});
67072                 }
67073
67074                 event.trigger("visibilitychange", [hidden]);
67075             }
67076
67077             function _isLockScreenOn() {
67078                 return deviceSettings.retrieve("Config.lockScreen");
67079             }
67080
67081             _lockScreen(_isLockScreenOn());
67082
67083             _pageVisibility = _bind("visibilitychange", frame.contentWindow);
67084
67085             widgetDocument.addEventListener = function (event, callback, useCapture) {
67086                 switch (event) {
67087                 case "visibilitychange":
67088                     _pageVisibility.add(callback, useCapture);
67089                     break;
67090
67091                 default:
67092                     add.apply(widgetDocument, arguments);
67093                     break;
67094                 }
67095             };
67096
67097             widgetDocument.removeEventListener = function (event, callback, useCapture) {
67098                 _pageVisibility.remove(callback, useCapture);
67099                 remove.apply(widgetDocument, arguments);
67100             };
67101
67102             event.on("LockScreenChanged", function (on) {
67103                 if (_isComWinSHow() === false) {
67104                     _lockScreen(on);
67105                 }
67106                 else {
67107                     if (on === true) {
67108                         ui.hideOverlay("communication-window");
67109                         _lockScreen(on);
67110                     }
67111                     else {
67112                         _lockScreen(on);
67113                         ui.showOverlay("communication-window");
67114                     }
67115                 }
67116             });
67117
67118             event.on("CommWinShow", function (status) {
67119                 _ComWinShow = status;
67120                 if (_isLockScreenOn() === true) {
67121                     if (status === false) {
67122                         _lockScreen(true);
67123                     }
67124                     else {
67125                         jQuery("#lock-screen-window").hide();
67126                     }
67127                 }
67128             });
67129
67130             event.on("visibilitychange", function (hidden) {
67131                 widgetDocument.hidden = hidden;
67132                 widgetDocument.visibilityState = hidden ? widgetDocument.PAGE_HIDDEN : widgetDocument.PAGE_VISIBLE;
67133                 _pageVisibility.exec();
67134             });
67135         });
67136     }
67137 };
67138
67139 module.exports = _self;
67140
67141 });
67142 define('ripple/emulatorBridge', function (require, exports, module) {
67143 /*
67144  *  Copyright 2011 Research In Motion Limited.
67145  *
67146  * Licensed under the Apache License, Version 2.0 (the "License");
67147  * you may not use this file except in compliance with the License.
67148  * You may obtain a copy of the License at
67149  *
67150  * http://www.apache.org/licenses/LICENSE-2.0
67151  *
67152  * Unless required by applicable law or agreed to in writing, software
67153  * distributed under the License is distributed on an "AS IS" BASIS,
67154  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67155  * See the License for the specific language governing permissions and
67156  * limitations under the License.
67157  */
67158 var platform = require('ripple/platform'),
67159     builder = require('ripple/platform/builder'),
67160     utils = require('ripple/utils'),
67161     _xhr, _win, _doc;
67162
67163 function _getEmulatedViewportStyle(attr) {
67164     var vp = document.getElementById("viewport-container");
67165     return vp["client" + attr];
67166 }
67167
67168 function _getEmulatedDeviceStyle(attr) {
67169     var vp = document.getElementById("device-container"), value;
67170     value = vp.style[attr].replace(/\s/g, '');
67171     value = value.split("px")[0] - 4;
67172     return (value);
67173 }
67174
67175 function _screenAvailWidth() {
67176     return _getEmulatedDeviceStyle("width");
67177 }
67178
67179 function _screenAvailHeight() {
67180     return _getEmulatedDeviceStyle("height");
67181 }
67182
67183 function _screenWidth() {
67184     return _getEmulatedDeviceStyle("width");
67185 }
67186
67187 function _screenHeight() {
67188     return _getEmulatedDeviceStyle("height");
67189 }
67190
67191 function _window_innerWidth() {
67192     return _getEmulatedViewportStyle("Width");
67193 }
67194
67195 function _window_innerHeight() {
67196     return _getEmulatedViewportStyle("Height");
67197 }
67198
67199 function _marshalScreen(win) {
67200     utils.forEach({
67201         "availWidth": _screenAvailWidth,
67202         "availHeight": _screenAvailHeight,
67203         "width": _screenWidth,
67204         "height": _screenHeight
67205     }, function (mappedFunc, prop) {
67206         win.screen.__defineGetter__(prop, mappedFunc);
67207     });
67208
67209     utils.forEach({
67210         "innerWidth": _window_innerWidth,
67211         "innerHeight": _window_innerHeight
67212     }, function (mappedFunc, prop) {
67213         win.__defineGetter__(prop, mappedFunc);
67214     });
67215 }
67216
67217 module.exports = {
67218     link: function  (win, doc) {
67219         // Only cache the device window and route onmessage to it
67220         if (win.parent.parent === win.parent &&
67221                 win.frameElement.getAttribute('id') === 'document') {
67222             _win = win;
67223             _doc = doc;
67224             _xhr = win.XMLHttpRequest;
67225
67226             window.onmessage = function (e) {
67227                 if (typeof win.onmessage === 'function') {
67228                     win.onmessage(e);
67229                 }
67230             };
67231         }
67232
67233         require('ripple/widgetConfig').initialize();
67234
67235         var marshal = function (obj, key) {
67236                 window[key] = win[key] = obj;
67237             },
67238             currentPlatform = platform.current(),
67239             sandbox = {};
67240
67241         marshal(window.tinyHippos, "tinyHippos");
67242         marshal(window.XMLHttpRequest, "XMLHttpRequest");
67243         marshal(window.Date, "Date");
67244
67245         if (currentPlatform.initialize) {
67246             currentPlatform.initialize(win);
67247         }
67248
67249         builder.build(platform.current().objects).into(sandbox);
67250         utils.forEach(sandbox, marshal);
67251
67252         _marshalScreen(win);
67253         _marshalScreen(window);
67254     },
67255
67256     document: function () {
67257         return _doc;
67258     },
67259
67260     window: function () {
67261         return _win;
67262     },
67263
67264     xhr: function () {
67265         return _xhr;
67266     }
67267 };
67268
67269 });
67270 define('ripple/event', function (require, exports, module) {
67271 /*
67272  *  Copyright 2011 Research In Motion Limited.
67273  *
67274  * Licensed under the Apache License, Version 2.0 (the "License");
67275  * you may not use this file except in compliance with the License.
67276  * You may obtain a copy of the License at
67277  *
67278  * http://www.apache.org/licenses/LICENSE-2.0
67279  *
67280  * Unless required by applicable law or agreed to in writing, software
67281  * distributed under the License is distributed on an "AS IS" BASIS,
67282  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67283  * See the License for the specific language governing permissions and
67284  * limitations under the License.
67285  */
67286 var utils = require('ripple/utils'),
67287     exception = require('ripple/exception'),
67288     _listeners = {};
67289
67290 function _on(eventType, listener, scope, once) {
67291     if (!eventType) {
67292         throw "eventType must be truthy";
67293     }
67294     _listeners[eventType] = _listeners[eventType] || [];
67295     _listeners[eventType].push({
67296         func: listener,
67297         scope: scope,
67298         once: !!once
67299     });
67300 }
67301
67302 function _deleteEventHandler(eventType, listenerFunc, scope) {
67303     var i, listeners;
67304
67305     if (!eventType) {
67306         throw "eventType must be truthy";
67307     }
67308
67309     listeners = _listeners[eventType];
67310
67311     // only delete once
67312     for (i = 0; i < listeners.length; i++) {
67313         if (listeners[i].func === listenerFunc) {
67314             listeners.splice(i, 1);
67315             break;
67316         }
67317     }
67318 }
67319
67320 function _trigger(listener, args, sync) {
67321     try {
67322         if (sync) {
67323             listener.func.apply(listener.scope, args);
67324         }
67325         else {
67326             setTimeout(function () {
67327                 listener.func.apply(listener.scope, args);
67328             }, 1);
67329         }
67330     }
67331     catch (e) {
67332         exception.handle(e);
67333     }
67334 }
67335
67336 module.exports = {
67337     on: function (eventType, listener, scope) {
67338         _on(eventType, listener, scope, false);
67339     },
67340
67341     once: function (eventType, listener, scope) {
67342         _on(eventType, listener, scope, true);
67343     },
67344
67345     trigger: function (eventType, args, sync) {
67346         args = args || [];
67347         sync = sync || false;
67348
67349         var listeners = _listeners[eventType];
67350
67351         if (listeners) {
67352             listeners.forEach(function (listener) {
67353                 _trigger(listener, args, sync);
67354             });
67355
67356             _listeners[eventType] = listeners.filter(function (listener) {
67357                 return !listener.once;
67358             });
67359         }
67360     },
67361
67362     eventHasSubscriber: function (eventType) {
67363         return !!_listeners[eventType];
67364     },
67365
67366     getEventSubscribers: function (eventType) {
67367         return utils.copy(_listeners[eventType]) || [];
67368     },
67369
67370     clear: function (eventType) {
67371         if (eventType) {
67372             delete _listeners[eventType];
67373         }
67374     },
67375
67376     deleteEventHandler: function (eventType, listener, scope) {
67377         _deleteEventHandler(eventType, listener, scope);
67378     }
67379 };
67380
67381 });
67382 define('ripple/exception', function (require, exports, module) {
67383 /*
67384  *  Copyright 2011 Research In Motion Limited.
67385  *
67386  * Licensed under the Apache License, Version 2.0 (the "License");
67387  * you may not use this file except in compliance with the License.
67388  * You may obtain a copy of the License at
67389  *
67390  * http://www.apache.org/licenses/LICENSE-2.0
67391  *
67392  * Unless required by applicable law or agreed to in writing, software
67393  * distributed under the License is distributed on an "AS IS" BASIS,
67394  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67395  * See the License for the specific language governing permissions and
67396  * limitations under the License.
67397  */
67398 var _console = require('ripple/console');
67399
67400 function _getStack(depth) {
67401     var caller,
67402         stack = "",
67403         count = 0;
67404
67405     try {
67406         caller = arguments.callee.caller.arguments.callee.caller;
67407
67408         while (count <= depth && caller) {
67409             stack += "function: " + caller.toString().match(/function\s?(.*)\{/)[1] + "\n";
67410             caller = caller.arguments.callee.caller;
67411             count++;
67412         }
67413     } catch (e) {
67414         stack = "failed to determine stack trace (" + (e.name || e.type) + " :: " + e.message + ")";
67415     }
67416
67417     return stack;
67418 }
67419
67420 module.exports = {
67421
67422     types: {
67423         Application: "Application",
67424         ArgumentLength: "ArgumentLength",
67425         ArgumentType: "ArgumentType",
67426         Argument: "Argument",
67427         NotificationType: "NotificationType",
67428         NotificationStateType: "NotificationStateType",
67429         DomObjectNotFound: "DomObjectNotFound",
67430         LayoutType: "LayoutType",
67431         OrientationType: "OrientationType",
67432         DeviceNotFound: "DeviceNotFound",
67433         tinyHipposMaskedException: "tinyHipposMaskedException",
67434         Geo: "Geo",
67435         Accelerometer: "Accelerometer",
67436         MethodNotImplemented: "MethodNotImplemented",
67437         InvalidState: "InvalidState",
67438         ApplicationState: "ApplicationState"
67439     },
67440
67441     handle: function handle(exception, reThrow) {
67442         reThrow = reThrow || false;
67443
67444         var eMsg = exception.message || "exception caught!",
67445         msg = eMsg + "\n\n" + (exception.stack || "*no stack provided*") + "\n\n";
67446
67447         _console.error(msg);
67448
67449         if (reThrow) {
67450             throw exception;
67451         }
67452     },
67453
67454     raise: function raise(exceptionType, message, customExceptionObject) {
67455         var obj = customExceptionObject || {
67456                 type: "",
67457                 message: "",
67458
67459                 toString: function () {
67460                     var result = this.name + ': "' + this.message + '"';
67461
67462                     if (this.stack) {
67463                         result += "\n" + this.stack;
67464                     }
67465                     return result;
67466                 }
67467             };
67468
67469         message = message || "";
67470
67471         obj.name = exceptionType;
67472         obj.type = exceptionType;
67473         // TODO: include the exception objects original message if exists
67474         obj.message = message;
67475         obj.stack = _getStack(5);
67476
67477         throw obj;
67478     },
67479
67480     throwMaskedException: function throwMaskedException(exceptionType, message, customExceptionObject) {
67481         try {
67482             this.raise.apply(this, arguments);
67483         } catch (e) {
67484             this.handle(e);
67485         }
67486         this.raise(this.types.tinyHipposMaskedException, "tinyhippos terminated your script due to exception");
67487     }
67488
67489 };
67490
67491 });
67492 define('ripple/fileSystem', function (require, exports, module) {
67493 /*
67494  *  Copyright 2011 Research In Motion Limited.
67495  *
67496  * Licensed under the Apache License, Version 2.0 (the "License");
67497  * you may not use this file except in compliance with the License.
67498  * You may obtain a copy of the License at
67499  *
67500  * http://www.apache.org/licenses/LICENSE-2.0
67501  *
67502  * Unless required by applicable law or agreed to in writing, software
67503  * distributed under the License is distributed on an "AS IS" BASIS,
67504  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67505  * See the License for the specific language governing permissions and
67506  * limitations under the License.
67507  */
67508 var constants = require('ripple/constants'),
67509     db = require('ripple/db'),
67510     exception = require('ripple/exception'),
67511     event = require('ripple/event'),
67512     _console = require('ripple/console'),
67513     utils = require('ripple/utils'),
67514     _fileSystemPaths = {
67515         "photos": { "uri": "" },
67516         "videos": { "uri": "" },
67517         "music": { "uri": "" },
67518         "downloads": { "uri": "" },
67519         "widgethome": { "uri": "" }
67520     },
67521     _fileSystemRegex = {
67522         "photos": { "virtualPathRegex": /^\/virtual\/photos\//i },
67523         "videos": { "virtualPathRegex": /^\/virtual\/videos\//i },
67524         "music": { "virtualPathRegex": /^\/virtual\/music\//i },
67525         "downloads": { "virtualPathRegex": /^\/virtual\/downloads\//i },
67526         "widgethome": { "virtualPathRegex": /^\/virtual\/widgethome\//i }
67527     },
67528     _overrides = {};
67529
67530 module.exports = {
67531     initialize: function () {
67532         _fileSystemPaths = db.retrieveObject(constants.FILESYSTEM.PERSISTENCE_KEY) || _fileSystemPaths;
67533         _fileSystemPaths.widgethome.uri = window.location.protocol + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/') + 1);
67534     },
67535
67536     getURI: function getURI(origURI) {
67537         var newURI = origURI,
67538             found = false;
67539
67540         if (_overrides[origURI]) {
67541             return _overrides[origURI];
67542         }
67543
67544         utils.forEach(_fileSystemPaths, function (value, key) {
67545             if (found) {
67546                 return;
67547             }
67548
67549             var uri = value.uri.replace(/\/$/, "");
67550             if (origURI.match(_fileSystemRegex[key].virtualPathRegex)) {
67551                 newURI = origURI.replace(_fileSystemRegex[key].virtualPathRegex, uri + "/");
67552                 found = true;
67553             }
67554         });
67555
67556         return newURI;
67557     },
67558
67559     exists: function (path) {
67560         try {
67561             var scrubbedUri = this.getURI(path),
67562                 xhr = new XMLHttpRequest();
67563
67564             xhr.open("GET", scrubbedUri, false);
67565             xhr.send();
67566
67567             //HACK: this should return maybe for 403
67568             return xhr.status !== 404;
67569         }
67570         catch (e) {
67571             exception.handle(e);
67572             _console.log("failed to check if [" + path + "] exists");
67573             return false;
67574         }
67575     },
67576
67577
67578     getFileSystemPaths: function getFileSystemPaths() {
67579         return utils.copy(_fileSystemPaths);
67580     },
67581
67582     updateFileSystemPaths: function updateFileSystemPaths(filePathsObject) {
67583         _fileSystemPaths = utils.copy(filePathsObject);
67584         _fileSystemPaths.widgethome.uri = window.location.protocol + "//" + window.location.host + window.location.pathname;
67585         db.saveObject(constants.FILESYSTEM.PERSISTENCE_KEY, filePathsObject);
67586     },
67587
67588     override : function (from, to) {
67589         _overrides[from] = to;
67590     }
67591 };
67592
67593 });
67594 define('ripple/fs', function (require, exports, module) {
67595 /*
67596  *  Copyright 2011 Research In Motion Limited.
67597  *
67598  * Licensed under the Apache License, Version 2.0 (the "License");
67599  * you may not use this file except in compliance with the License.
67600  * You may obtain a copy of the License at
67601  *
67602  * http://www.apache.org/licenses/LICENSE-2.0
67603  *
67604  * Unless required by applicable law or agreed to in writing, software
67605  * distributed under the License is distributed on an "AS IS" BASIS,
67606  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67607  * See the License for the specific language governing permissions and
67608  * limitations under the License.
67609  */
67610 var utils = require('ripple/utils'),
67611     constants = require('ripple/constants'),
67612     event = require('ripple/event'),
67613     _console = require('ripple/console'),
67614     _self, _fs;
67615
67616 function _map(array, callback) {
67617     var map = [], i;
67618     for (i = 0; i < array.length; i++) {
67619         map[i] = callback(array[i], i);
67620     }
67621     return map;
67622 }
67623
67624 function _resolveLocalFileSystemURL(path, success, error) {
67625     return (window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL)(path, success, error);
67626 }
67627
67628 function _blobBuilder() {
67629     var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
67630     return new BlobBuilder();
67631 }
67632
67633 function _error(e) {
67634     var msg = '';
67635
67636     switch (e.code) {
67637     case FileError.QUOTA_EXCEEDED_ERR:
67638         msg = 'QUOTA_EXCEEDED_ERR';
67639         break;
67640     case FileError.NOT_FOUND_ERR:
67641         msg = 'NOT_FOUND_ERR';
67642         break;
67643     case FileError.SECURITY_ERR:
67644         msg = 'SECURITY_ERR';
67645         break;
67646     case FileError.INVALID_MODIFICATION_ERR:
67647         msg = 'INVALID_MODIFICATION_ERR';
67648         break;
67649     case FileError.INVALID_STATE_ERR:
67650         msg = 'INVALID_STATE_ERR';
67651         break;
67652     default:
67653         msg = 'Unknown Error';
67654         break;
67655     }
67656
67657     _console.log('FileSystem error: ' + msg);
67658 }
67659
67660 _self = {
67661     initialize: function (prev, baton) {
67662         try {
67663             var requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
67664
67665             if (requestFileSystem) {
67666                 baton.take();
67667             }
67668
67669             requestFileSystem(window.TEMPORARY, constants.FS_SIZE, function (fs) {
67670                 _fs = fs;
67671                 event.trigger("FileSystemInitialized", null, true);
67672                 baton.pass();
67673             }, _error);
67674         }
67675         catch (e) {
67676             console.log("File System Not Available");
67677         }
67678     },
67679
67680     ls: function (path, success, error) {
67681         path = path || "/";
67682
67683         _fs.root.getDirectory(path, {}, function (dirEntry) {
67684             var dirReader = dirEntry.createReader();
67685             dirReader.readEntries(function (entries) {
67686                 success(_map(entries, function (entry, index) {
67687                     return entry;
67688                 }));
67689             }, error);
67690         }, error);
67691     },
67692
67693     rm: function (path, success, error, options) {
67694         options = options || {};
67695
67696         _fs.root[options.recursive ? "getDirectory" : "getFile"](path, {create: false}, function (entry) {
67697             entry[options.recursive ? "removeRecursively" : "remove"](function () {
67698                 success();
67699             }, error);
67700         }, error);
67701     },
67702
67703     rmdir: function (path, success, error, options) {
67704         options = options || {};
67705
67706         _fs.root.getDirectory(path, {create: false}, function (entry) {
67707             entry.remove(function () {
67708                 success();
67709             }, error);
67710         }, error);
67711     },
67712
67713     mkdir: function (path, success, error) {
67714         _fs.root.getDirectory(path, {create: true}, function (dirEntry) {
67715             success(dirEntry);
67716         }, error);
67717     },
67718
67719     mv: function (from, to, success, error) {
67720         var path = to.replace(/^\//, "").split("/"),
67721             fileName = path.splice(path.length - 1, 1).toString();
67722
67723         _self.stat(from, function (entry) {
67724             _self.stat(path.length > 0 ? path.join("/") : "/", function (dest) {
67725                 entry.moveTo(dest, fileName, function (finalDestination) {
67726                     success(finalDestination);
67727                 }, error);
67728             }, error);
67729         }, error);
67730     },
67731
67732     touch: function (path, success, error) {
67733         _fs.root.getFile(path, {create: true}, function (fileEntry) {
67734             success(fileEntry);
67735         }, error);
67736     },
67737
67738     cp: function (from, to, success, error) {
67739         var path = to.replace(/^\//, "").split("/"),
67740             fileName = path.splice(path.length - 1, 1).toString();
67741
67742         _self.stat(from, function (entry) {
67743             _self.stat(path.length > 0 ? path.join("/") : "/", function (dest) {
67744                 entry.copyTo(dest, fileName, function (finalDestination) {
67745                     success(finalDestination);
67746                 }, error);
67747             }, error);
67748         }, error);
67749     },
67750
67751     stat: function (path, success, error) {
67752         var url = "filesystem:" + utils.location().origin + "/temporary/" + path;
67753         _resolveLocalFileSystemURL(url, function (entry) {
67754             success(entry);
67755         }, error);
67756     },
67757
67758     write: function (path, contents, success, error, options) {
67759         options = options || {};
67760
67761         function write(entry) {
67762             entry.createWriter(function (fileWriter) {
67763                 var bb = _blobBuilder();
67764
67765                 fileWriter.onwriteend = function (progressEvent) {
67766                     success(entry);
67767                 };
67768                 fileWriter.onerror = error;
67769
67770                 if (options.mode === "append") {
67771                     fileWriter.seek(fileWriter.length);
67772                 }
67773
67774                 bb.append(contents);
67775                 fileWriter.write(bb.getBlob('text/plain'));
67776             }, error);
67777         }
67778
67779         _self.stat(path, function (entry) {
67780             if (options.mode === "append") {
67781                 write(entry);
67782             } else {
67783                 _self.rm(path, function () {
67784                     _self.touch(path, write, error);
67785                 }, error);
67786             }
67787         }, function (e) {
67788             if (e.code === FileError.NOT_FOUND_ERR) {
67789                 _self.touch(path, write, error);
67790             } else {
67791                 error(e);
67792             }
67793         });
67794     },
67795
67796     read: function (path, success, error) {
67797         _self.stat(path, function (entry) {
67798             entry.file(function (file) {
67799                 var reader = new FileReader();
67800
67801                 reader.onloadend = function (progressEvent) {
67802                     success(progressEvent.target.result);
67803                 };
67804                 reader.onerror = error;
67805
67806                 reader.readAsText(file);
67807             }, error);
67808         }, error);
67809     }
67810 };
67811
67812 module.exports = _self;
67813
67814 });
67815 define('ripple/geo', function (require, exports, module) {
67816 /*
67817  *  Copyright 2011 Research In Motion Limited.
67818  *
67819  * Licensed under the Apache License, Version 2.0 (the "License");
67820  * you may not use this file except in compliance with the License.
67821  * You may obtain a copy of the License at
67822  *
67823  * http://www.apache.org/licenses/LICENSE-2.0
67824  *
67825  * Unless required by applicable law or agreed to in writing, software
67826  * distributed under the License is distributed on an "AS IS" BASIS,
67827  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67828  * See the License for the specific language governing permissions and
67829  * limitations under the License.
67830  */
67831 var db = require('ripple/db'),
67832     exception = require('ripple/exception'),
67833     event = require('ripple/event'),
67834     utils = require('ripple/utils'),
67835     _positionInfo = {
67836         "latitude": 39.968362,
67837         "longitude": 116.410186,
67838         "altitude": 50,
67839         "accuracy": 150,
67840         "altitudeAccuracy": 80,
67841         "heading": 0,
67842         "speed": 0,
67843         "cellID": 1130433
67844     },
67845     self;
67846
67847 function _serialize(settings) {
67848     var tempSettings = utils.copy(settings);
67849     tempSettings.position.timeStamp = "new Date(" + tempSettings.position.timeStamp.getTime() + ")";
67850     return tempSettings;
67851 }
67852
67853 function _validatePositionInfo(pInfo) {
67854     return (pInfo &&
67855         !(isNaN(pInfo.latitude) ||
67856         isNaN(pInfo.longitude) ||
67857         isNaN(pInfo.altitude) ||
67858         isNaN(pInfo.accuracy) ||
67859         isNaN(pInfo.altitudeAccuracy) ||
67860         isNaN(pInfo.heading) ||
67861         isNaN(pInfo.speed) ||
67862         isNaN(pInfo.cellID))) ? true : false;
67863 }
67864
67865 self = module.exports = {
67866     initialize: function () {
67867         var settings = db.retrieveObject("geosettings");
67868         if (settings) {
67869             utils.forEach(_positionInfo, function (value, key) {
67870                 _positionInfo[key] = parseFloat(settings.position[key] || value);
67871             });
67872
67873             self.timeout = settings.timeout;
67874             self.delay = settings.delay || 0;
67875
67876         }
67877     },
67878
67879     getPositionInfo: function () {
67880         var pi = utils.copy(_positionInfo);
67881         pi.timeStamp = new Date();
67882
67883         return pi;
67884     },
67885
67886     updatePositionInfo: function (newPositionInfo, delay, timeout) {
67887         if (!_validatePositionInfo(newPositionInfo)) {
67888             exception.raise(exception.types.Geo, "invalid positionInfo object");
67889         }
67890
67891         _positionInfo = utils.copy(newPositionInfo);
67892         _positionInfo.timeStamp = new Date();
67893
67894         self.delay = delay || 0;
67895         self.timeout = timeout;
67896
67897         db.saveObject("geosettings", _serialize({
67898             position: _positionInfo,
67899             delay: self.delay,
67900             timeout: self.timeout
67901         }));
67902
67903         event.trigger("PositionInfoUpdatedEvent", [_positionInfo]);
67904     },
67905
67906     timeout: false,
67907     delay: 0,
67908     map: {}
67909 };
67910
67911 });
67912 define('ripple/honeypot', function (require, exports, module) {
67913 /*
67914  *  Copyright 2011 Research In Motion Limited.
67915  *
67916  * Licensed under the Apache License, Version 2.0 (the "License");
67917  * you may not use this file except in compliance with the License.
67918  * You may obtain a copy of the License at
67919  *
67920  * http://www.apache.org/licenses/LICENSE-2.0
67921  *
67922  * Unless required by applicable law or agreed to in writing, software
67923  * distributed under the License is distributed on an "AS IS" BASIS,
67924  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67925  * See the License for the specific language governing permissions and
67926  * limitations under the License.
67927  */
67928
67929 var noop = function () {};
67930
67931 module.exports = {
67932     monitor: function (context, target) {
67933
67934         var setup = function (get, set) {
67935             set = set || noop;
67936
67937             context.__defineGetter__(target, noop);
67938             context.__defineSetter__(target, function (value) {
67939                 context.__defineGetter__(target, get);
67940                 set(value);
67941             });
67942         };
67943
67944         return {
67945             andReturn: function (value) {
67946                 setup(function () {
67947                     return value;
67948                 });
67949             },
67950             andRun: function (get, set) {
67951                 setup(get, set);
67952             }
67953         };
67954     }
67955 };
67956
67957 });
67958 define('ripple/hwKeyEmulator', function (require, exports, module) {
67959 /*
67960  *  Copyright 2011 Research In Motion Limited.
67961  *
67962  * Licensed under the Apache License, Version 2.0 (the "License");
67963  * you may not use this file except in compliance with the License.
67964  * You may obtain a copy of the License at
67965  *
67966  * http://www.apache.org/licenses/LICENSE-2.0
67967  *
67968  * Unless required by applicable law or agreed to in writing, software
67969  * distributed under the License is distributed on an "AS IS" BASIS,
67970  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67971  * See the License for the specific language governing permissions and
67972  * limitations under the License.
67973  */
67974
67975 var event = require('ripple/event'),
67976    _self;
67977
67978 function _HWKeyEvent(keyName) {
67979     var doc = document.getElementById('document').contentDocument,
67980     event;
67981
67982     event = doc.createEvent('Event');
67983     event.initEvent("tizenhwkey", true, false);
67984     event.__defineGetter__("keyName", function () {
67985         return keyName;
67986     });
67987     doc.dispatchEvent(event);
67988 }
67989
67990
67991 _self = {
67992     init: function (win, doc) {
67993         event.clear("tizenhwkeyEvent");
67994         event.on("tizenhwkeyEvent", function (keyName) {
67995             _HWKeyEvent(keyName);
67996         });
67997     }
67998 };
67999
68000 module.exports = _self;
68001
68002 });
68003 define('ripple/notifications', function (require, exports, module) {
68004 /*
68005  *  Copyright 2011 Research In Motion Limited.
68006  *
68007  * Licensed under the Apache License, Version 2.0 (the "License");
68008  * you may not use this file except in compliance with the License.
68009  * You may obtain a copy of the License at
68010  *
68011  * http://www.apache.org/licenses/LICENSE-2.0
68012  *
68013  * Unless required by applicable law or agreed to in writing, software
68014  * distributed under the License is distributed on an "AS IS" BASIS,
68015  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68016  * See the License for the specific language governing permissions and
68017  * limitations under the License.
68018  */
68019 var constants = require('ripple/constants'),
68020     exception = require('ripple/exception'),
68021     utils = require('ripple/utils'),
68022     event = require('ripple/event');
68023
68024 function _validateAndInitNType(nType) {
68025     nType = nType || "normal";
68026
68027     if (nType !== "normal" && nType !== "error") {
68028         exception.raise(exception.types.NotificationType, "Unknown Notification Type == " + nType + ",when dealing with Console notification.");
68029     }
68030
68031     return nType;
68032 }
68033
68034 function _processNotification(nType, stateType, message) {
68035     nType = _validateAndInitNType(nType);
68036     message = message || "";
68037
68038     var display,
68039         displayText,
68040         className,
68041         notificationIcon,
68042         box = document.getElementById(constants.NOTIFICATIONS.MAIN_CONTAINER_CLASS),
68043         msgBox = document.getElementById(constants.NOTIFICATIONS.MESSAGE_TEXT_CONTAINER_CLASS);
68044
68045     className = "ui-widget";
68046
68047     switch (stateType) {
68048
68049     case constants.NOTIFICATIONS.STATE_TYPES.CLOSE:
68050         display = "display: none;"; //need to do this better.
68051         displayText = "";
68052         break;
68053
68054     case constants.NOTIFICATIONS.STATE_TYPES.OPEN:
68055         display = "display: block;"; //need to do this better.
68056         displayText = message;
68057         if (nType === "error") {
68058             displayText = "Oh Snap!\n\n" + displayText;
68059             className += " ui-state-error ui-corner-all";
68060             notificationIcon = '<span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span>';
68061         }
68062         else {
68063             className += " ui-state-highlight ui-corner-all";
68064             notificationIcon = '<span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>';
68065         }
68066         break;
68067
68068     default:
68069         exception.raise(exception.types.NotificationStateType, "Unknown StateType == " + stateType.toString());
68070     }
68071
68072     msgBox.innerHTML = notificationIcon + displayText;
68073     box.setAttribute("class", className);
68074     box.setAttribute("style", display);
68075
68076 }
68077
68078 module.exports = {
68079     openNotification: function (nType, msg) {
68080         _processNotification(nType, constants.NOTIFICATIONS.STATE_TYPES.OPEN, msg);
68081     },
68082
68083     closeNotification: function (nType) {
68084         _processNotification(nType, constants.NOTIFICATIONS.STATE_TYPES.CLOSE);
68085     }
68086 };
68087
68088 });
68089 define('ripple/omgwtf', function (require, exports, module) {
68090 /*
68091  *  Copyright 2011 Research In Motion Limited.
68092  *
68093  * Licensed under the Apache License, Version 2.0 (the "License");
68094  * you may not use this file except in compliance with the License.
68095  * You may obtain a copy of the License at
68096  *
68097  * http://www.apache.org/licenses/LICENSE-2.0
68098  *
68099  * Unless required by applicable law or agreed to in writing, software
68100  * distributed under the License is distributed on an "AS IS" BASIS,
68101  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68102  * See the License for the specific language governing permissions and
68103  * limitations under the License.
68104  */
68105 var event = require('ripple/event'),
68106     db = require('ripple/db'),
68107     _loaded = false,
68108     _self;
68109
68110 function _delay(action) {
68111     window.setTimeout(function () {
68112         if (!_loaded) {
68113             if (jQuery(".first-run-window").is(":visible")) {
68114                 _delay(action);
68115             } else {
68116                 action();
68117             }
68118         }
68119     }, 10000);
68120 }
68121
68122 function _hide() {
68123     jQuery(".error-window").css({display: 'none'});
68124     jQuery(".error-dialog").css({display: 'none'});
68125 }
68126
68127 function _show() {
68128     jQuery(".error-window").css({display: 'block'});
68129
68130     jQuery(".error-dialog").css({
68131         display: 'block',
68132         left: (jQuery(document).width() / 2) - 277 + "px"
68133     });
68134
68135     jQuery("#error-wait").click(function () {
68136         _hide();
68137         _delay(_show);
68138     });
68139
68140     jQuery("#error-panic").click(function () {
68141         db.removeAll(null, function () {
68142             window.tinyHipposReload = true;
68143             localStorage.clear();
68144             location.reload();
68145         });
68146     });
68147 }
68148
68149 _delay(_show);
68150
68151 _self = {
68152     initialize: function (previous, baton) {
68153         event.on("TinyHipposLoaded", function () {
68154             _loaded = true;
68155         });
68156     },
68157     show: _show,
68158     hide: _hide
68159 };
68160
68161 module.exports = _self;
68162
68163 });
68164 define('ripple/platform/builder', function (require, exports, module) {
68165 /*
68166  *  Copyright 2011 Research In Motion Limited.
68167  *
68168  * Licensed under the Apache License, Version 2.0 (the "License");
68169  * you may not use this file except in compliance with the License.
68170  * You may obtain a copy of the License at
68171  *
68172  * http://www.apache.org/licenses/LICENSE-2.0
68173  *
68174  * Unless required by applicable law or agreed to in writing, software
68175  * distributed under the License is distributed on an "AS IS" BASIS,
68176  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68177  * See the License for the specific language governing permissions and
68178  * limitations under the License.
68179  */
68180
68181 var utils = require('ripple/utils'),
68182     app = require('ripple/app');
68183
68184 function _objectFactory(context, objects/*, allowed*/) {
68185     utils.forEach(objects, function (obj, key) {
68186         var result = {}, objFeatures = {}, rst, f, widgetFeatures;
68187
68188 //        if (allowed(obj)) {
68189         result = obj.path ? require('ripple/platform/' + obj.path) : {};
68190         if (typeof result === "function" && obj.handleSubfeatures && obj.handleSubfeatures === true) {
68191             rst = new result();
68192             if (obj.feature) {
68193                 objFeatures = obj.feature.split('|');
68194                 if (rst.handleSubFeatures) {
68195                     widgetFeatures = app.getInfo().features; // features in config.xml
68196                     f = {};
68197                     utils.forEach(objFeatures, function (o) {
68198                         if (widgetFeatures && !!widgetFeatures[o]) {
68199                             f[widgetFeatures[o].id] = widgetFeatures[o];
68200                         }
68201                     });
68202                     rst.handleSubFeatures(f);
68203                     delete rst.handleSubFeatures;
68204                 }
68205             }
68206             result = rst;
68207         }
68208 //        }
68209
68210         if (obj.children) {
68211             _objectFactory(result, obj.children/*, allowed*/);
68212         }
68213
68214         context.__defineGetter__(key, function () {
68215             return result;
68216         });
68217         // inject into the context if it is allowed or it has children that were allowed
68218 //        if (allowed(obj) || utils.count(result)) {
68219 //        context[key] = result;
68220 //        }
68221 //        else {
68222 //            if (context.hasOwnProperty(key))
68223 //                console.log("delete " + key);
68224 //            delete context[key];
68225 //        }
68226     });
68227 }
68228
68229 module.exports = {
68230     build: function (objects) {
68231         return {
68232             into: function (sandbox) {
68233 /*                var features = utils.copy(app.getInfo().features);
68234                     allowed = function (obj) {
68235                         var contains = function (requirements) {
68236                             return requirements.split('|').some(function (feature) {
68237                                 return !!features[feature];
68238                             });
68239                         };
68240                         //object is allowed if:
68241                         // 1. it has no feature requirement
68242                         // 2. the config file doesn't exist (features collection is null)
68243                         // 3. the feature exists in the defined features
68244                         return !obj.feature || !features || (features && contains(obj.feature));
68245                     };
68246 */
68247
68248                 _objectFactory(sandbox, objects/*, allowed*/);
68249             }
68250         };
68251     }
68252 };
68253
68254 });
68255 define('ripple/platform/cordova/2.0.0/JavaPluginManager', function (require, exports, module) {
68256 module.exports = {
68257     exec: function () {
68258         throw "this really shouldn't be called. like ever!";
68259     },
68260     resume: function () {
68261         throw "this shouldn't be called";
68262     },
68263     pause: function () {
68264         throw "this shouldn't be called";
68265     },
68266     destroy: function () {
68267         throw "this shouldn't be called";
68268     }
68269 };
68270
68271 });
68272 define('ripple/platform/cordova/2.0.0/MediaError', function (require, exports, module) {
68273 /*
68274  *  Copyright 2011 Research In Motion Limited.
68275  *
68276  * Licensed under the Apache License, Version 2.0 (the "License");
68277  * you may not use this file except in compliance with the License.
68278  * You may obtain a copy of the License at
68279  *
68280  * http://www.apache.org/licenses/LICENSE-2.0
68281  *
68282  * Unless required by applicable law or agreed to in writing, software
68283  * distributed under the License is distributed on an "AS IS" BASIS,
68284  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68285  * See the License for the specific language governing permissions and
68286  * limitations under the License.
68287  */
68288 var MediaError = function (code, msg) {
68289     this.code = (code !== undefined ? code : null);
68290     this.message = msg || "";
68291 };
68292
68293 MediaError.MEDIA_ERR_NONE_ACTIVE    = 0;
68294 MediaError.MEDIA_ERR_ABORTED        = 1;
68295 MediaError.MEDIA_ERR_NETWORK        = 2;
68296 MediaError.MEDIA_ERR_DECODE         = 3;
68297 MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
68298
68299 module.exports = MediaError;
68300
68301 });
68302 define('ripple/platform/cordova/2.0.0/bridge/accelerometer', function (require, exports, module) {
68303 /*
68304  *  Copyright 2011 Research In Motion Limited.
68305  *
68306  * Licensed under the Apache License, Version 2.0 (the "License");
68307  * you may not use this file except in compliance with the License.
68308  * You may obtain a copy of the License at
68309  *
68310  * http://www.apache.org/licenses/LICENSE-2.0
68311  *
68312  * Unless required by applicable law or agreed to in writing, software
68313  * distributed under the License is distributed on an "AS IS" BASIS,
68314  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68315  * See the License for the specific language governing permissions and
68316  * limitations under the License.
68317  */
68318 var event = require('ripple/event'),
68319     _success,
68320     _error,
68321     _current = {x: 0, y: 0, z: 0, timestamp: (new Date()).getTime()},
68322     _interval;
68323
68324 event.on("AccelerometerInfoChangedEvent", function (accelerometerInfo) {
68325     _current.x = accelerometerInfo.accelerationIncludingGravity.x;
68326     _current.y = accelerometerInfo.accelerationIncludingGravity.y;
68327     _current.z = accelerometerInfo.accelerationIncludingGravity.z;
68328     _current.timestamp = (new Date()).getTime();
68329 });
68330
68331 module.exports = {
68332     start: function (success, error, args) {
68333         _success = success;
68334         _error = error;
68335         // Possible HACK? update the timestamp of the last data to something current
68336         _interval = window.setInterval(function () {
68337             _current.timestamp = (new Date()).getTime();
68338             _success(_current);
68339         }, 50);
68340     },
68341
68342     stop: function () {
68343         _success = null;
68344         _error = null;
68345         window.clearInterval(_interval);
68346     }
68347 };
68348
68349 });
68350 define('ripple/platform/cordova/2.0.0/bridge/app', function (require, exports, module) {
68351 /*
68352  *  Copyright 2011 Research In Motion Limited.
68353  *
68354  * Licensed under the Apache License, Version 2.0 (the "License");
68355  * you may not use this file except in compliance with the License.
68356  * You may obtain a copy of the License at
68357  *
68358  * http://www.apache.org/licenses/LICENSE-2.0
68359  *
68360  * Unless required by applicable law or agreed to in writing, software
68361  * distributed under the License is distributed on an "AS IS" BASIS,
68362  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68363  * See the License for the specific language governing permissions and
68364  * limitations under the License.
68365  */
68366 var camera = require('ripple/ui/plugins/camera'),
68367     event = require('ripple/event');
68368
68369 module.exports = {
68370     show: function (success, error, args) {
68371         return success && success();
68372     }
68373 };
68374
68375 });
68376 define('ripple/platform/cordova/2.0.0/bridge/camera', function (require, exports, module) {
68377 /*
68378  *  Copyright 2011 Research In Motion Limited.
68379  *
68380  * Licensed under the Apache License, Version 2.0 (the "License");
68381  * you may not use this file except in compliance with the License.
68382  * You may obtain a copy of the License at
68383  *
68384  * http://www.apache.org/licenses/LICENSE-2.0
68385  *
68386  * Unless required by applicable law or agreed to in writing, software
68387  * distributed under the License is distributed on an "AS IS" BASIS,
68388  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68389  * See the License for the specific language governing permissions and
68390  * limitations under the License.
68391  */
68392 var camera = require('ripple/ui/plugins/camera'),
68393     event = require('ripple/event');
68394
68395 module.exports = {
68396     takePicture: function (success, error, args) {
68397         event.once("captured-image", function (uri, file) {
68398             success(uri);
68399         });
68400         camera.show();
68401     },
68402     cleanup: function (success, error, args) {
68403         success();
68404     }
68405 };
68406
68407 });
68408 define('ripple/platform/cordova/2.0.0/bridge/capture', function (require, exports, module) {
68409 /*
68410  *  Copyright 2011 Research In Motion Limited.
68411  *
68412  * Licensed under the Apache License, Version 2.0 (the "License");
68413  * you may not use this file except in compliance with the License.
68414  * You may obtain a copy of the License at
68415  *
68416  * http://www.apache.org/licenses/LICENSE-2.0
68417  *
68418  * Unless required by applicable law or agreed to in writing, software
68419  * distributed under the License is distributed on an "AS IS" BASIS,
68420  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68421  * See the License for the specific language governing permissions and
68422  * limitations under the License.
68423  */
68424
68425 var camera = require('ripple/ui/plugins/camera'),
68426     event = require('ripple/event');
68427
68428 module.exports = {
68429     captureImage: function (success, error, args) {
68430         event.once("captured-image", function (uri, file) {
68431             file.fullPath = uri;
68432             success([file]);
68433         });
68434         camera.show();
68435     }
68436 };
68437
68438 });
68439 define('ripple/platform/cordova/2.0.0/bridge/compass', function (require, exports, module) {
68440 /*
68441  *  Copyright 2011 Research In Motion Limited.
68442  *
68443  * Licensed under the Apache License, Version 2.0 (the "License");
68444  * you may not use this file except in compliance with the License.
68445  * You may obtain a copy of the License at
68446  *
68447  * http://www.apache.org/licenses/LICENSE-2.0
68448  *
68449  * Unless required by applicable law or agreed to in writing, software
68450  * distributed under the License is distributed on an "AS IS" BASIS,
68451  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68452  * See the License for the specific language governing permissions and
68453  * limitations under the License.
68454  */
68455 var geo = require('ripple/geo');
68456
68457 module.exports = {
68458     getHeading: function (success, error, args) {
68459         // TODO: build facility to trigger onError() from emulator
68460         // see pivotal item: https://www.pivotaltracker.com/story/show/7040343
68461         success({
68462             magneticHeading: geo.getPositionInfo().heading, 
68463             trueHeading: geo.getPositionInfo().heading, 
68464             headingAccuracy: 100, 
68465             timestamp: new Date().getSeconds()
68466         });
68467     },
68468
68469     stopHeading: function () { 
68470         //do nothing
68471     }
68472 };
68473
68474 });
68475 define('ripple/platform/cordova/2.0.0/bridge/console', function (require, exports, module) {
68476 /*
68477  *  Copyright 2011 Research In Motion Limited.
68478  *
68479  * Licensed under the Apache License, Version 2.0 (the "License");
68480  * you may not use this file except in compliance with the License.
68481  * You may obtain a copy of the License at
68482  *
68483  * http://www.apache.org/licenses/LICENSE-2.0
68484  *
68485  * Unless required by applicable law or agreed to in writing, software
68486  * distributed under the License is distributed on an "AS IS" BASIS,
68487  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68488  * See the License for the specific language governing permissions and
68489  * limitations under the License.
68490  */
68491
68492 module.exports = {
68493     log: function (win, fail, args) {
68494         console.log(args[0]);
68495     }
68496 };
68497
68498 });
68499 define('ripple/platform/cordova/2.0.0/bridge/contacts', function (require, exports, module) {
68500 /*
68501  *  Copyright 2011 Research In Motion Limited.
68502  *
68503  * Licensed under the Apache License, Version 2.0 (the "License");
68504  * you may not use this file except in compliance with the License.
68505  * You may obtain a copy of the License at
68506  *
68507  * http://www.apache.org/licenses/LICENSE-2.0
68508  *
68509  * Unless required by applicable law or agreed to in writing, software
68510  * distributed under the License is distributed on an "AS IS" BASIS,
68511  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68512  * See the License for the specific language governing permissions and
68513  * limitations under the License.
68514  */
68515 var db = require('ripple/db'),
68516     utils = require('ripple/utils'),
68517     _self;
68518
68519 function _default() {
68520     return [{
68521         "name": {formatted: "Brent Lintner"},
68522         "displayName": "Brent Lintner",
68523         "emails": [{type: "work", value: "brent@tinyhippos.com", pref: false}]
68524     }, {
68525         "name": {formatted: "PJ Lowe"},
68526         "displayName": "PJ Lowe",
68527         "emails": [{type: "work", value: "pj@tinyhippos.com", pref: false}]
68528     }, {
68529         "name": {formatted: "Dan Silivestru"},
68530         "displayName": "Dan Silivestru",
68531         "emails": [{type: "work", value: "dan@tinyhippos.com", pref: false}]
68532     }, {
68533         "name": {formatted: "Gord Tanner"},
68534         "displayName": "Gord Tanner",
68535         "emails": [{type: "work", value: "gord@tinyhippos.com", pref: true}]
68536     }, {
68537         "name": {formatted: "Mark McArdle"},
68538         "displayName": "Mark McArdle",
68539         "emails": [{type: "work", value: "mark@tinyhippos.com", pref: false}]
68540     }].map(function (obj) {
68541         obj.id = Math.uuid(undefined, 16);
68542         return navigator.contacts.create(obj);
68543     });
68544 }
68545
68546 function _get() {
68547     return db.retrieveObject("cordova-contacts") || _default();
68548 }
68549
68550 function _save(contacts) {
68551     db.saveObject("cordova-contacts", contacts);
68552 }
68553
68554 function _filtered(compare, options) {
68555     // this could be done a lot better..
68556     var found = false;
68557     if (!options.filter || options.filter === "") {
68558         found = true;
68559     } else if (typeof compare === "string" &&
68560               compare.match(new RegExp(".*" + options.filter + ".*", "i"))) {
68561         found = true;
68562     } else if (typeof compare === "object" || compare instanceof Array) {
68563         utils.forEach(compare, function (value) {
68564             if (!found) {
68565                 found = _filtered(value, options);
68566             }
68567         });
68568     }
68569     return found;
68570 }
68571
68572 _self = {
68573     search: function (success, error, args) {
68574         var fields = args[0],
68575             options = args[1],
68576             foundContacts = [],
68577             tempContact = navigator.contacts.create(),
68578             contacts = _get();
68579
68580         options = options || {};
68581
68582         // handle special case of ["*"] to return all fields
68583         if (fields.length === 1 && fields[0] === "*") {
68584             fields = utils.map(tempContact, function (v, k) {
68585                 return k;
68586             });
68587         }
68588
68589         if (fields.length > 0) {
68590             contacts.forEach(function (contact, index) {
68591                 var newContact = navigator.contacts.create(contact);
68592
68593                 if (options && (!_filtered(contact, options))) {
68594                     return;
68595                 }
68596
68597                 utils.forEach(newContact, function (value, prop) {
68598                     if (typeof newContact[prop] !== "function" && prop !== "id" &&
68599                         !fields.some(function (field) {
68600                             return field === prop;
68601                         })) {
68602                         delete newContact[prop];
68603                     }
68604                 });
68605
68606                 foundContacts.push(newContact);
68607             });
68608         }
68609
68610         // TODO: don't loop over entire db just to slice the array
68611         if (options.multiple === false) {
68612             foundContacts = foundContacts.splice(0, 1);
68613         }
68614         success(foundContacts);
68615     },
68616
68617     save: function (success, error, args) {
68618         var contacts = _get(),
68619             contact = args[0],
68620             index;
68621
68622         if (!contact.id) {
68623             contact.id = Math.uuid(undefined, 16);
68624             contacts.push(contact);
68625         } else {
68626             index = contacts.reduce(function (result, value, index) {
68627                 return value.id === contact.id ? index : result;
68628             }, -1);
68629
68630             if (index >= 0) {
68631                 utils.mixin(contact, contacts[index]);
68632                 contact = contacts[index];
68633             } else {
68634                 contact = null;
68635             }
68636         }
68637
68638         _save(contacts);
68639         if (success) {
68640             success(contact);
68641         }
68642     },
68643
68644     remove: function (success, error, args) {
68645         var contacts = _get(),
68646             id = args[0],
68647             toDelete = contacts.reduce(function (result, current, index) {
68648                 return current.id === id ? index : result;
68649             }, -1);
68650
68651         if (toDelete >= 0) {
68652             contacts.splice(toDelete, 1);
68653             _save(contacts);
68654             if (success) {
68655                 success();
68656             }
68657         } else {
68658             error({code: 3, message: "could not find contact with id (" + id + ")"}); // PENDING_OPERATION_ERROR
68659         }
68660     }
68661 };
68662
68663 module.exports = _self;
68664
68665 });
68666 define('ripple/platform/cordova/2.0.0/bridge/device', function (require, exports, module) {
68667 /*
68668  *  Copyright 2011 Research In Motion Limited.
68669  *
68670  * Licensed under the Apache License, Version 2.0 (the "License");
68671  * you may not use this file except in compliance with the License.
68672  * You may obtain a copy of the License at
68673  *
68674  * http://www.apache.org/licenses/LICENSE-2.0
68675  *
68676  * Unless required by applicable law or agreed to in writing, software
68677  * distributed under the License is distributed on an "AS IS" BASIS,
68678  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68679  * See the License for the specific language governing permissions and
68680  * limitations under the License.
68681  */
68682 var devices = require('ripple/devices');
68683
68684 module.exports = {
68685     getDeviceInfo: function (success, fail, args) {
68686         var device = devices.getCurrentDevice();
68687
68688         success({
68689             available: true,
68690             platform: device.osName,
68691             version: device.osVersion,
68692             name: device.name,
68693             uuid: device.uuid,
68694             cordova: "2.0.0"
68695         });
68696     }
68697 };
68698
68699 });
68700 define('ripple/platform/cordova/2.0.0/bridge/file', function (require, exports, module) {
68701 // HACK: fs keeps a reference to the last-used FileSystem requested via requestFileSystem
68702 // this is a hack because if you keep switching between TEMPORARY vs. PERSISTENT file systems requested,
68703 // and run Cordova File API methods, no parameter is passed into exec specifying the underlying File System.
68704 // This should be fixed in Cordova!
68705 var fs, 
68706     topCordova = require('ripple/platform/cordova/2.0.0/spec'),
68707     rlfsu;
68708
68709 function cleanPath(path) {
68710     while (path[0] && path[0] === '/') {
68711         path = path.substr(1);
68712     }
68713     return path;
68714 }
68715
68716 module.exports = {
68717     requestFileSystem: function (win, fail, args) {
68718         // HACK: may not be webkit
68719         var rfs = window.webkitRequestFileSystem,
68720             type = args[0],
68721             size = args[1];
68722
68723         // HACK: assume any FS requested over a gig in size will throw an error
68724         if (size > (1024 * 1024 * 1024 /* gigabyte */)) {
68725             if (fail) fail(FileError.QUOTA_EXCEEDED_ERR);
68726         } else {
68727             return rfs(type, size, function (effes) {
68728                 fs = effes;
68729                 win(effes);
68730             }, fail);
68731         }
68732     },
68733     resolveLocalFileSystemURI: function (win, fail, args) {
68734         var uri = args[0],
68735             fulluri = fs.root.toURL();
68736
68737         // HACK: iOS-specific bs right here. See lib/ios/plugin/ios/Entry.js in cordova.js for details
68738         // Cordova badly needs a unified File System abstraction.
68739         if (uri.indexOf("file://localhost") === 0) {
68740             uri = uri.substr(16);
68741         }
68742         uri = cleanPath(uri);
68743
68744         fulluri += uri;
68745
68746         return window.webkitResolveLocalFileSystemURL(fulluri, function (entry) {
68747             if (win) win(entry);
68748         }, function (error) {
68749             if (fail) fail(error.code);
68750         });
68751     },
68752     getFile: function (win, fail, args) {
68753         var path = args[0],
68754             filename = args[1],
68755             options = args[2],
68756             file = '';
68757
68758         path = cleanPath(path);
68759         filename = cleanPath(filename);
68760
68761         if (path) {
68762             file = path + '/';
68763         }
68764         file += filename;
68765
68766         fs.root.getFile(file, options, function (entry) {
68767             if (win) win(entry);
68768         }, function (err) {
68769             if (fail) fail(err.code);
68770         });
68771     },
68772     remove: function (win, fail, args) {
68773         var file = args[0];
68774         window.webkitResolveLocalFileSystemURL(fs.root.toURL() + file, function (entry) {
68775             entry.remove(function () {
68776                 if (win) win();
68777             }, function (err) {
68778                 if (fail) fail(err.code);
68779             });
68780         }, fail);
68781     },
68782     readEntries: function (win, fail, args) {
68783         var root = fs.root.toURL(),
68784             path = args[0],
68785             reader;
68786
68787         path = cleanPath(path);
68788         path = root + path;
68789
68790         window.webkitResolveLocalFileSystemURL(path, function (entry) {
68791             reader = entry.createReader();
68792             reader.readEntries(function (entries) {
68793                 if (win) win(entries);
68794             }, function (err) {
68795                 if (fail) fail(err.code);
68796             });
68797         }, function (err) {
68798             if (fail) fail(err.code);
68799         });
68800     },
68801     getDirectory: function (win, fail, args) {
68802         var path = args[0],
68803             filename = args[1],
68804             options = args[2],
68805             file = '';
68806
68807         path = cleanPath(path);
68808         filename = cleanPath(filename);
68809
68810         if (path) {
68811             file = path + '/';
68812         }
68813         file += filename;
68814
68815         fs.root.getDirectory(file, options, function (entry) {
68816             if (win) win(entry);
68817         }, function (err) {
68818             if (fail) fail(err.code);
68819         });
68820     },
68821     removeRecursively: function (win, fail, args) {
68822         var root = fs.root.toURL(),
68823             path = args[0];
68824
68825         path = cleanPath(path);
68826
68827         window.webkitResolveLocalFileSystemURL(root + path, function (dirEntry) {
68828             dirEntry.removeRecursively(function () {
68829                 if (win) win();
68830             }, function (err) {
68831                 if (fail) fail(err.code);
68832             });
68833         }, function (err) {
68834             if (fail) fail(err.code);
68835         });
68836     },
68837     getFileMetadata: function (win, fail, args) {
68838         var path = args[0],
68839             root = fs.root.toURL();
68840
68841         path = cleanPath(path);
68842
68843         window.webkitResolveLocalFileSystemURL(root + path, function (entry) {
68844             entry.file(function (file) {
68845                 if (win) win(file);
68846             }, function (err) {
68847                 if (fail) fail(err.code);
68848             });
68849         }, function (err) {
68850             if (fail) fail(err.code);
68851         });
68852     },
68853     getMetadata: function (win, fail, args) {
68854         var path = args[0],
68855             root = fs.root.toURL();
68856
68857         path = cleanPath(path);
68858         
68859         window.webkitResolveLocalFileSystemURL(root + path, function (entry) {
68860             entry.getMetadata(function (data) {
68861                 if (win) win(data);
68862             }, function (err) {
68863                 if (fail) fail(err.code);
68864             });
68865         }, function (err) {
68866             if (fail) fail(err.code);
68867         });
68868     },
68869     getParent: function (win, fail, args) {
68870         var path = args[0],
68871             root = fs.root.toURL();
68872
68873         path = cleanPath(path);
68874
68875         window.webkitResolveLocalFileSystemURL(root + path, function (entry) {
68876             entry.getParent(function (dirEntry) {
68877                 if (win) win(dirEntry);
68878             }, function (err) {
68879                 if (fail) fail(err.code);
68880             });
68881         }, function (err) {
68882             if (fail) fail(err.code);
68883         });
68884     },
68885     copyTo: function (win, fail, args) {
68886         var src = args[0],
68887             parent = args[1],
68888             name = args[2],
68889             root = fs.root.toURL();
68890
68891         parent = cleanPath(parent);
68892         src = cleanPath(src);
68893
68894         rlfsu = window.webkitResolveLocalFileSystemURL;
68895         // get the directoryentry that we will copy TO
68896         rlfsu(root + parent, function (parentDirToCopyTo) {
68897             rlfsu(root + src, function (sourceDir) {
68898                 sourceDir.copyTo(parentDirToCopyTo, name, function (newEntry) {
68899                     if (win) win(newEntry);
68900                 }, function (err) {
68901                     if (fail) fail(err.code);
68902                 });
68903             }, function (err) {
68904                 if (fail) fail(err.code);
68905             });
68906         }, function (err) {
68907             if (fail) fail(err.code);
68908         });
68909     },
68910     moveTo: function (win, fail, args) {
68911         var src = args[0],
68912             parent = args[1],
68913             name = args[2],
68914             root = fs.root.toURL();
68915
68916         parent = cleanPath(parent);
68917         src = cleanPath(src);
68918
68919         rlfsu = window.webkitResolveLocalFileSystemURL;
68920         // get the directoryentry that we will move TO
68921         rlfsu(root + parent, function (parentDirToMoveTo) {
68922             rlfsu(root + src, function (sourceDir) {
68923                 sourceDir.moveTo(parentDirToMoveTo, name, function (newEntry) {
68924                     if (win) win(newEntry);
68925                 }, function (err) {
68926                     if (fail) fail(err.code);
68927                 });
68928             }, function (err) {
68929                 if (fail) fail(err.code);
68930             });
68931         }, function (err) {
68932             if (fail) fail(err.code);
68933         });
68934     },
68935     write: function (win, fail, args) {
68936         var file = args[0],
68937             text = args[1],
68938             position = args[2],
68939             sourcepath,
68940             BB = window.BlobBuilder || window.WebKitBlobBuilder,
68941             bb = new BB();
68942
68943         // Format source path
68944         sourcepath = (file.fullPath ? file.fullPath : '') + file.name;
68945         sourcepath = cleanPath(sourcepath);
68946
68947         // Create a blob for the text to be written
68948         bb.append(text);
68949
68950         // Get the FileEntry, create if necessary
68951         fs.root.getFile(sourcepath, {create: true}, function (entry) {
68952             // Create a FileWriter for this entry
68953             entry.createWriter(function (writer) {
68954                 writer.onwriteend = function (progressEvt) {
68955                     if (win) win(progressEvt.total);
68956                 };
68957                 writer.onerror = function (err) {
68958                     if (fail) fail(err.code);
68959                 };
68960
68961                 if (position && position > 0) {
68962                     writer.seek(position);
68963                 }
68964                 writer.write(bb.getBlob('text/plain'));
68965             }, function (err) {
68966                 if (fail) fail(err.code);
68967             });
68968         }, function (err) {
68969             if (fail) fail(err.code);
68970         });
68971     },
68972     readAsText: function (win, fail, args) {
68973         var path = args[0],
68974             encoding = args[1],
68975             FileReader = topCordova.nativeMethods.FileReader,
68976             fr = new window.FileReader();
68977
68978         // Set up FileReader events
68979         fr.onerror = function (err) {
68980             if (fail) fail(err.code);
68981         };
68982         fr.onload = function (evt) {
68983             if (win) win(evt.target.result);
68984         };
68985
68986         path = cleanPath(path);
68987
68988         fs.root.getFile(path, {create: false}, function (entry) {
68989             entry.file(function (blob) {
68990                 fr.readAsText(blob, encoding);
68991             }, function (err) {
68992                 if (fail) fail(err.code);
68993             });
68994         }, function (err) {
68995             if (fail) fail(err.code);
68996         });
68997     },
68998     readAsDataURL: function (win, fail, args) {
68999         var path = args[0],
69000             FileReader = topCordova.nativeMethods.FileReader,
69001             fr = new window.FileReader();
69002
69003         // Set up FileReader events
69004         fr.onerror = function (err) {
69005             if (fail) fail(err.code);
69006         };
69007         fr.onload = function (evt) {
69008             if (win) win(evt.target.result);
69009         };
69010
69011         path = cleanPath(path);
69012
69013         fs.root.getFile(path, {create: false}, function (entry) {
69014             entry.file(function (blob) {
69015                 fr.readAsDataURL(blob);
69016             }, function (err) {
69017                 if (fail) fail(err.code);
69018             });
69019         }, function (err) {
69020             if (fail) fail(err.code);
69021         });
69022     },
69023     truncate: function (win, fail, args) {
69024         var file = args[0],
69025             position = args[1],
69026             sourcepath;
69027
69028         // Format source path
69029         sourcepath = (file.fullPath ? file.fullPath : '') + file.name;
69030         sourcepath = cleanPath(sourcepath);
69031
69032         // Get the FileEntry, create if necessary
69033         fs.root.getFile(sourcepath, {create: false}, function (entry) {
69034             // Create a FileWriter for this entry
69035             entry.createWriter(function (writer) {
69036                 writer.onwriteend = function (progressEvt) {
69037                     if (win) win(progressEvt.target.length);
69038                 };
69039                 writer.onerror = function (err) {
69040                     if (fail) fail(err.code);
69041                 };
69042
69043                 writer.truncate(position);
69044             }, function (err) {
69045                 if (fail) fail(err.code);
69046             });
69047         }, function (err) {
69048             if (fail) fail(err.code);
69049         });
69050     }
69051 };
69052
69053 });
69054 define('ripple/platform/cordova/2.0.0/bridge/geolocation', function (require, exports, module) {
69055 /*
69056  *  Copyright 2011 Research In Motion Limited.
69057  *
69058  * Licensed under the Apache License, Version 2.0 (the "License");
69059  * you may not use this file except in compliance with the License.
69060  * You may obtain a copy of the License at
69061  *
69062  * http://www.apache.org/licenses/LICENSE-2.0
69063  *
69064  * Unless required by applicable law or agreed to in writing, software
69065  * distributed under the License is distributed on an "AS IS" BASIS,
69066  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69067  * See the License for the specific language governing permissions and
69068  * limitations under the License.
69069  */
69070 var event = require('ripple/event'),
69071     geo = require('ripple/geo'),
69072     utils = require('ripple/utils'),
69073     PositionError = require('ripple/platform/w3c/1.0/PositionError'),
69074     _watches = {},
69075     _current = {
69076         "latitude": 43.465187,
69077         "longitude": -80.522372,
69078         "altitude": 100,
69079         "accuracy": 150,
69080         "altitudeAccuracy": 80,
69081         "heading": 0,
69082         "velocity": 0,
69083     },
69084     _error;
69085
69086 function _getCurrentPosition(win, fail) {
69087     if (geo.timeout) {
69088         if (fail) {
69089             var positionError = new PositionError();
69090
69091             positionError.code = PositionError.TIMEOUT;
69092             positionError.message = "postion timed out";
69093             fail(positionError);
69094         }
69095     }
69096     else {
69097         win(geo.getPositionInfo());
69098     }
69099 }
69100
69101 event.on("PositionInfoUpdatedEvent", function (pi) {
69102     _current.latitude = pi.latitude;
69103     _current.longitude = pi.longitude;
69104     _current.altitude = pi.altitude;
69105     _current.accuracy = pi.accuracy;
69106     _current.altitudeAccuracy = pi.altitudeAccuracy;
69107     _current.heading = pi.heading;
69108     _current.velocity = pi.speed;
69109
69110     utils.forEach(_watches, function (watch) {
69111         try {
69112             _getCurrentPosition(watch.win, watch.fail);
69113         } catch (e) {
69114             console.log(e);
69115         }
69116     });
69117 });
69118
69119 module.exports = {
69120     getLocation: function (success, error, args) {
69121         _getCurrentPosition(success, error);
69122     },
69123
69124     addWatch: function (success, error, args) {
69125         _watches[args[0]] = {
69126             win: success,
69127             fail: error
69128         };
69129         _getCurrentPosition(success, error);
69130     },
69131
69132     clearWatch: function (id) {
69133         delete _watches[id];
69134     }
69135 };
69136
69137 });
69138 define('ripple/platform/cordova/2.0.0/bridge/media', function (require, exports, module) {
69139 /*
69140  *  Copyright 2011 Research In Motion Limited.
69141  *
69142  * Licensed under the Apache License, Version 2.0 (the "License");
69143  * you may not use this file except in compliance with the License.
69144  * You may obtain a copy of the License at
69145  *
69146  * http://www.apache.org/licenses/LICENSE-2.0
69147  *
69148  * Unless required by applicable law or agreed to in writing, software
69149  * distributed under the License is distributed on an "AS IS" BASIS,
69150  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69151  * See the License for the specific language governing permissions and
69152  * limitations under the License.
69153  */
69154 var audioObjects = {},
69155     noop = function () {};
69156
69157 function createAudio(id, src, error) {
69158     var a = new Audio();
69159     a.addEventListener("error", function (e) {
69160         error(new window.MediaError(1, e.toString()));
69161     });
69162     a.addEventListener("durationchange", function () {
69163         //HACK: I don't like this but best way for us to update the duration
69164         cordova.require("cordova/plugin/Media").onStatus(id, 2, this.duration);
69165     });
69166     a.src = src;
69167
69168     return a;
69169 }
69170
69171 module.exports = {
69172     create: function (success, error, args) {
69173         if (!args.length) {
69174             error("Media Object id was not sent in arguments");
69175             return;
69176         }
69177
69178         var id = args[0],
69179             src = args[1];
69180
69181         error = error || noop;
69182         success = success || noop;
69183
69184         audioObjects[id] = createAudio(id, src, error);
69185         success();
69186     },
69187     startPlayingAudio: function (success, error, args) {
69188         error = error || noop;
69189         success = success || noop;
69190         if (!args.length) {
69191             error("Media Object id was not sent in arguments");
69192             return;
69193         }
69194
69195         var id = args[0],
69196             audio = audioObjects[id];
69197
69198         if (args.length === 1) {
69199             error("Media source argument not found");
69200             return;
69201         }
69202
69203         if (audio) {
69204             audio.pause();
69205             audioObjects[id] = undefined;
69206         }
69207
69208         audio = audioObjects[id] = createAudio(id, args[1], error);
69209         audio.play();
69210
69211         success();
69212     },
69213     stopPlayingAudio: function (success, error, args) {
69214         error = error || noop;
69215         success = success || noop;
69216         if (!args.length) {
69217             error("Media Object id was not sent in arguments");
69218             return;
69219         }
69220
69221         var id = args[0],
69222             audio = audioObjects[id];
69223
69224         if (!audio) {
69225             error("Audio Object has not been initialized");
69226             return;
69227         }
69228
69229         audio.pause();
69230         audioObjects[id] = undefined;
69231
69232         success();
69233     },
69234     seekToAudio: function (success, error, args) {
69235         error = error || noop;
69236         success = success || noop;
69237         if (!args.length) {
69238             error("Media Object id was not sent in arguments");
69239             return;
69240         }
69241
69242         var id = args[0],
69243             audio = audioObjects[id];
69244
69245         if (!audio) {
69246             error("Audio Object has not been initialized");
69247             return;
69248         } else if (args.length === 1) {
69249             error("Media seek time argument not found");
69250             return;
69251         } else {
69252             try {
69253                 audio.currentTime = args[1];
69254             } catch (e) {
69255                 error("Error seeking audio: " + e);
69256             }
69257         }
69258
69259         success();
69260     },
69261     pausePlayingAudio: function (success, error, args) {
69262         error = error || noop;
69263         success = success || noop;
69264         if (!args.length) {
69265             error("Media Object id was not sent in arguments");
69266             return;
69267         }
69268
69269         var id = args[0],
69270             audio = audioObjects[id];
69271
69272         if (!audio) {
69273             error("Audio Object has not been initialized");
69274             return;
69275         }
69276
69277         audio.pause();
69278         success();
69279     },
69280     getCurrentPositionAudio: function (success, error, args) {
69281         error = error || noop;
69282         success = success || noop;
69283         if (!args.length) {
69284             error("Media Object id was not sent in arguments");
69285             return;
69286         }
69287
69288         var id = args[0],
69289             audio = audioObjects[id];
69290
69291         if (!audio) {
69292             error("Audio Object has not been initialized");
69293             return;
69294         }
69295
69296         success(audio.currentTime);
69297     },
69298     getDuration: function (success, error, args) {
69299         error = error || noop;
69300         success = success || noop;
69301         if (!args.length) {
69302             error("Media Object id was not sent in arguments");
69303             return;
69304         }
69305
69306         var id = args[0],
69307             audio = audioObjects[id];
69308
69309         if (!audio) {
69310             error("Audio Object has not been initialized");
69311             return;
69312         }
69313
69314         success(audio.duration);
69315     },
69316     startRecordingAudio: function (success, error, args) {
69317         error = error || noop;
69318         error("Not supported");
69319     },
69320     stopRecordingAudio: function (success, error, args) {
69321         error = error || noop;
69322         error("Not supported");
69323     },
69324     release: function (success, error, args) {
69325         error = error || noop;
69326         success = success || noop;
69327         if (!args.length) {
69328             error("Media Object id was not sent in arguments");
69329             return;
69330         }
69331
69332         var id = args[0],
69333             audio = audioObjects[id];
69334
69335         if (audio) {
69336             audioObjects[id] = undefined;
69337             audio.src = undefined;
69338             //delete audio;
69339         }
69340
69341         success();
69342     }
69343 };
69344
69345 });
69346 define('ripple/platform/cordova/2.0.0/bridge/network', function (require, exports, module) {
69347 /*
69348  *  Copyright 2011 Research In Motion Limited.
69349  *
69350  * Licensed under the Apache License, Version 2.0 (the "License");
69351  * you may not use this file except in compliance with the License.
69352  * You may obtain a copy of the License at
69353  *
69354  * http://www.apache.org/licenses/LICENSE-2.0
69355  *
69356  * Unless required by applicable law or agreed to in writing, software
69357  * distributed under the License is distributed on an "AS IS" BASIS,
69358  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69359  * See the License for the specific language governing permissions and
69360  * limitations under the License.
69361  */
69362
69363 var deviceSettings = require('ripple/deviceSettings'),
69364     event = require('ripple/event'),
69365     _success;
69366
69367 event.on("ConnectionChanged", function () {
69368     return _success && _success(deviceSettings.retrieve("NetworkStatus.connectionType"));
69369 });
69370
69371 module.exports = {
69372     getConnectionInfo: function (success, fail, args) {
69373         _success = success;
69374         success(deviceSettings.retrieve("NetworkStatus.connectionType"));
69375     }
69376 };
69377
69378 });
69379 define('ripple/platform/cordova/2.0.0/bridge/notification', function (require, exports, module) {
69380 /*
69381  *  Copyright 2011 Research In Motion Limited.
69382  *
69383  * Licensed under the Apache License, Version 2.0 (the "License");
69384  * you may not use this file except in compliance with the License.
69385  * You may obtain a copy of the License at
69386  *
69387  * http://www.apache.org/licenses/LICENSE-2.0
69388  *
69389  * Unless required by applicable law or agreed to in writing, software
69390  * distributed under the License is distributed on an "AS IS" BASIS,
69391  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69392  * See the License for the specific language governing permissions and
69393  * limitations under the License.
69394  */
69395 var notifications = require('ripple/notifications'),
69396     _console = require('ripple/console'),
69397     goodVibrations = require('ripple/ui/plugins/goodVibrations');
69398
69399 module.exports = {
69400     alert: function (success, error, args) {
69401         notifications.openNotification("normal", args[0]);
69402         return success && success();
69403     },
69404
69405     confirm: function (success, error, args) {
69406         throw "Not Implemented";
69407     },
69408
69409     activityStart: function (success, error, args) {
69410     },
69411
69412     activityStop: function (success, error, args) { 
69413     },
69414
69415     progressStart: function (success, error, args) {
69416     },
69417
69418     vibrate: function (success, error, args) {
69419         var ms = args[0] || 500;
69420         goodVibrations.vibrateDevice(ms);
69421     },
69422
69423     beep: function (success, error, args) {
69424         for (var i = args[0]; i > 0; i--) {
69425             _console.log("beep!");
69426         }
69427         notifications.openNotification("normal", "BEEP x " + args[0]);
69428     }
69429 };
69430
69431 });
69432 define('ripple/platform/cordova/2.0.0/bridge', function (require, exports, module) {
69433 /*
69434  *  Copyright 2011 Research In Motion Limited.
69435  *
69436  * Licensed under the Apache License, Version 2.0 (the "License");
69437  * you may not use this file except in compliance with the License.
69438  * You may obtain a copy of the License at
69439  *
69440  * http://www.apache.org/licenses/LICENSE-2.0
69441  *
69442  * Unless required by applicable law or agreed to in writing, software
69443  * distributed under the License is distributed on an "AS IS" BASIS,
69444  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69445  * See the License for the specific language governing permissions and
69446  * limitations under the License.
69447  */
69448 var _prompt = require('ripple/ui/plugins/exec-dialog');
69449
69450 module.exports = {
69451     exec: function (success, fail, service, action, args) {
69452         var emulator = {
69453             "App": require('ripple/platform/cordova/2.0.0/bridge/app'),
69454             "Accelerometer": require('ripple/platform/cordova/2.0.0/bridge/accelerometer'),
69455             "Compass": require('ripple/platform/cordova/2.0.0/bridge/compass'),
69456             "Camera": require('ripple/platform/cordova/2.0.0/bridge/camera'),
69457             "Capture": require('ripple/platform/cordova/2.0.0/bridge/capture'),
69458             "Contacts": require('ripple/platform/cordova/2.0.0/bridge/contacts'),
69459             "Debug Console": require('ripple/platform/cordova/2.0.0/bridge/console'),
69460             "Device": require('ripple/platform/cordova/2.0.0/bridge/device'),
69461             "File": require('ripple/platform/cordova/2.0.0/bridge/file'),
69462             "Geolocation": require('ripple/platform/cordova/2.0.0/bridge/geolocation'),
69463             "Media": require('ripple/platform/cordova/2.0.0/bridge/media'),
69464             "Network Status": require('ripple/platform/cordova/2.0.0/bridge/network'),
69465             "NetworkStatus": require('ripple/platform/cordova/2.0.0/bridge/network'),
69466             "Notification": require('ripple/platform/cordova/2.0.0/bridge/notification')
69467         };
69468
69469         try {
69470             emulator[service][action](success, fail, args);
69471         }
69472         catch (e) {
69473             console.log("missing exec:" + service + "." + action);
69474             console.log(args);
69475             console.log(e);
69476             console.log(e.stack);
69477             //TODO: this should really not log the above lines, but they are very nice for development right now
69478             _prompt.show(service, action, success, fail);
69479         }
69480     }
69481 };
69482
69483 });
69484 define('ripple/platform/cordova/2.0.0/logger', function (require, exports, module) {
69485 module.exports = {
69486     log: function (msg) {
69487         console.log(msg);
69488     }
69489 };
69490
69491 });
69492 define('ripple/platform/cordova/2.0.0/spec/config', function (require, exports, module) {
69493 /*
69494  *  Copyright 2011 Research In Motion Limited.
69495  *
69496  * Licensed under the Apache License, Version 2.0 (the "License");
69497  * you may not use this file except in compliance with the License.
69498  * You may obtain a copy of the License at
69499  *
69500  * http://www.apache.org/licenses/LICENSE-2.0
69501  *
69502  * Unless required by applicable law or agreed to in writing, software
69503  * distributed under the License is distributed on an "AS IS" BASIS,
69504  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69505  * See the License for the specific language governing permissions and
69506  * limitations under the License.
69507  */
69508 var constants = require('ripple/constants');
69509
69510 module.exports = {
69511     fileName: "config.xml",
69512     validateVersion: function (configValidationObject) {
69513         var valid = true;
69514         valid = !((!configValidationObject.widget.validationResult[0].attributes.xmlns.valid) ||
69515             (!configValidationObject.widget.validationResult[0].attributes["xmlns:gap"].valid));
69516
69517         return valid;
69518     },
69519     extractInfo: function (configValidationObject) {
69520         if (!configValidationObject) {
69521             return null;
69522         }
69523
69524         var widgetInfo = {};
69525
69526         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
69527         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
69528         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
69529         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
69530
69531         return widgetInfo;
69532     },
69533     schema: {
69534         rootElement: "widget",
69535         widget: {
69536             nodeName: "widget",
69537             required: true,
69538             occurrence: 1,
69539             attributes: {
69540                 xmlns: {
69541                     attributeName: "xmlns",
69542                     required: true,
69543                     type: "list",
69544                     listValues: ["http://www.w3.org/ns/widgets"]
69545                 },
69546                 "xmlns:gap": {
69547                     attributeName: "xmlns:gap",
69548                     required: true,
69549                     type: "list",
69550                     listValues: ["http://phonegap.com/ns/1.0"]
69551                 },
69552                 "xml:lang": {
69553                     attributeName: "xml:lang",
69554                     required: false,
69555                     type: "iso-language"
69556                 },
69557                 dir: {
69558                     attributeName: "dir",
69559                     required: false,
69560                     type: "list",
69561                     listValues: ["ltr", "rtl", "lro", "rlo"]
69562                 },
69563                 id: {
69564                     attributeName: "id",
69565                     required: false,
69566                     type: "string"
69567                 },
69568                 version: {
69569                     attributeName: "version",
69570                     required: false,
69571                     type: "string"
69572                 },
69573                 height: {
69574                     attributeName: "height",
69575                     required: false,
69576                     type: "integer"
69577                 },
69578                 width: {
69579                     attributeName: "width",
69580                     required: false,
69581                     type: "integer"
69582                 },
69583                 viewmodes: {
69584                     attributeName: "viewmodes",
69585                     required: false,
69586                     type: "list",
69587                     listValues: ["floating", "fullscreen"]
69588                 }
69589             },
69590             children: {
69591                 name: {
69592                     nodeName: "name",
69593                     required: false,
69594                     occurrence: 0,
69595                     type: "string",
69596                     attributes: {
69597                         "short": {
69598                             attributeName: "short",
69599                             type: "string",
69600                             required: false
69601                         },
69602                         "xml:lang": {
69603                             attributeName: "xml:lang",
69604                             type: "string",
69605                             required: false,
69606                             unique: true
69607                         }
69608                     }
69609                 },
69610                 description: {
69611                     nodeName: "description",
69612                     required: false,
69613                     occurrence: 0,
69614                     type: "string",
69615                     attributes: {
69616                         "xml:lang": {
69617                             attributeName: "xml:lang",
69618                             type: "string",
69619                             required: false,
69620                             unique: true
69621                         }
69622                     }
69623                 },
69624                 author: {
69625                     nodeName: "author",
69626                     required: false,
69627                     occurrence: 1,
69628                     type: "string",
69629                     attributes: {
69630                         email: {
69631                             attributeName: "email",
69632                             type: "regex",
69633                             required: false,
69634                             regex: constants.REGEX.EMAIL
69635                         },
69636                         href: {
69637                             attributeName: "href",
69638                             type: "regex",
69639                             required: false,
69640                             regex: constants.REGEX.URL
69641                         }
69642                     }
69643                 },
69644                 license: {
69645                     nodeName: "license",
69646                     required: false,
69647                     occurrence: 1,
69648                     type: "string",
69649                     attributes: {
69650                         href: {
69651                             attributeName: "href",
69652                             type: "regex",
69653                             required: false,
69654                             regex: constants.REGEX.URL
69655                         },
69656                         "xml:lang": {
69657                             attributeName: "xml:lang",
69658                             type: "string",
69659                             required: false,
69660                             unique: true
69661                         }
69662                     }
69663                 },
69664                 icon: {
69665                     nodeName: "icon",
69666                     required: false,
69667                     occurrence: 0,
69668                     attributes: {
69669                         src: {
69670                             attributeName: "src",
69671                             type: "string",
69672                             required: true
69673                         },
69674                         height: {
69675                             attributeName: "height",
69676                             required: false,
69677                             type: "integer"
69678                         },
69679                         width: {
69680                             attributeName: "width",
69681                             required: false,
69682                             type: "integer"
69683                         }
69684                     }
69685                 },
69686                 content: {
69687                     nodeName: "content",
69688                     required: false,
69689                     occurrence: 1,
69690                     attributes: {
69691                         src: {
69692                             attributeName: "src",
69693                             type: "string",
69694                             required: true
69695                         },
69696                         encoding: {
69697                             attributeName: "encoding",
69698                             type: "string",
69699                             required: false
69700                         },
69701                         type: {
69702                             attributeName: "type",
69703                             type: "string",
69704                             required: false
69705                         }
69706                     }
69707                 },
69708                 feature: {
69709                     nodeName: "feature",
69710                     required: false,
69711                     occurrence: 0,
69712                     attributes: {
69713                         name: {
69714                             attributeName: "name",
69715                             type: "list",
69716                             required: true,
69717                             listValues: ["http://api.phonegap.com/1.0/accelerometer", "http://api.phonegap.com/1.0/camera",
69718                                 "http://api.phonegap.com/1.0/compass", "http://api.phonegap.com/1.0/contacts", "http://api.phonegap.com/1.0/device",
69719                                 "http://api.phonegap.com/1.0/events", "http://api.phonegap.com/1.0/file", "http://api.phonegap.com/1.0/geolocation",
69720                                 "http://api.phonegap.com/1.0/media", "http://api.phonegap.com/1.0/network", "http://api.phonegap.com/1.0/notification",
69721                                 "http://api.phonegap.com/1.0/storage"]
69722                         },
69723                         required: {
69724                             attributeName: "required",
69725                             type: "boolean",
69726                             required: false
69727                         }
69728                     }
69729                 },
69730                 preference: {
69731                     nodeName: "preference",
69732                     required: false,
69733                     occurrence: 0,
69734                     attributes: {
69735                         name: {
69736                             attributeName: "name",
69737                             type: "string",
69738                             required: true
69739                         },
69740                         value: {
69741                             type: "string",
69742                             attributeName: "value",
69743                             required: false
69744                         },
69745                         readonly: {
69746                             attributeName: "readonly",
69747                             type: "boolean",
69748                             required: false
69749                         }
69750                     }
69751                 }
69752             }
69753         }
69754     }
69755 };
69756
69757 });
69758 define('ripple/platform/cordova/2.0.0/spec/device', function (require, exports, module) {
69759 /*
69760  *  Copyright 2011 Research In Motion Limited.
69761  *
69762  * Licensed under the Apache License, Version 2.0 (the "License");
69763  * you may not use this file except in compliance with the License.
69764  * You may obtain a copy of the License at
69765  *
69766  * http://www.apache.org/licenses/LICENSE-2.0
69767  *
69768  * Unless required by applicable law or agreed to in writing, software
69769  * distributed under the License is distributed on an "AS IS" BASIS,
69770  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69771  * See the License for the specific language governing permissions and
69772  * limitations under the License.
69773  */
69774 var event = require('ripple/event');
69775
69776 module.exports = {
69777     "NetworkStatus": {
69778         "connectionType": {
69779             "name": "Connection Type",
69780             "control": {
69781                 "type": "select",
69782                 "value": "ethernet"
69783             },
69784             "options": {
69785                 "unknown": "UNKNOWN",
69786                 "ethernet": "ETHERNET",
69787                 "wifi": "WIFI",
69788                 "2g": "CELL_2G",
69789                 "3g": "CELL_3G",
69790                 "4g": "CELL_4G",
69791                 "none": "none"
69792             },
69793             "callback": function (setting) {
69794                 var connected = setting !== "none";
69795                 require('ripple/bus').send("network", connected);
69796             }
69797         },
69798         "lag": {
69799             "name": "Lag the network",
69800             "control": {
69801                 type: "checkbox",
69802                 value: false
69803             },
69804             "callback": function (setting) {
69805                 require('ripple/bus').send("lag", setting);
69806             }
69807         },
69808     }
69809 };
69810
69811 });
69812 define('ripple/platform/cordova/2.0.0/spec/events', function (require, exports, module) {
69813 /*
69814  *  Copyright 2011 Research In Motion Limited.
69815  *
69816  * Licensed under the Apache License, Version 2.0 (the "License");
69817  * you may not use this file except in compliance with the License.
69818  * You may obtain a copy of the License at
69819  *
69820  * http://www.apache.org/licenses/LICENSE-2.0
69821  *
69822  * Unless required by applicable law or agreed to in writing, software
69823  * distributed under the License is distributed on an "AS IS" BASIS,
69824  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69825  * See the License for the specific language governing permissions and
69826  * limitations under the License.
69827  */
69828 function _fires(name, data) {
69829     return function () {
69830         cordova.fireDocumentEvent(name, data);
69831     };
69832 }
69833
69834 module.exports = {
69835     "deviceready": {
69836         callback: _fires("deviceready")
69837     },
69838     "backbutton": {
69839         callback: _fires("backbutton")
69840     },
69841     "menubutton": {
69842         callback: _fires("menubutton")
69843     },
69844     "pause": {
69845         callback: _fires("pause")
69846     },
69847     "resume": {
69848         callback: _fires("resume")
69849     },
69850     "searchbutton": {
69851         callback: _fires("searchbutton")
69852     },
69853     "online": {
69854         callback: _fires("online")
69855     },
69856     "offline": {
69857         callback: _fires("offline")
69858     }
69859 };
69860
69861 });
69862 define('ripple/platform/cordova/2.0.0/spec/ui', function (require, exports, module) {
69863 /*
69864  *  Copyright 2011 Research In Motion Limited.
69865  *
69866  * Licensed under the Apache License, Version 2.0 (the "License");
69867  * you may not use this file except in compliance with the License.
69868  * You may obtain a copy of the License at
69869  *
69870  * http://www.apache.org/licenses/LICENSE-2.0
69871  *
69872  * Unless required by applicable law or agreed to in writing, software
69873  * distributed under the License is distributed on an "AS IS" BASIS,
69874  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69875  * See the License for the specific language governing permissions and
69876  * limitations under the License.
69877  */
69878 module.exports = {
69879     plugins: [
69880         "accelerometer",
69881         "deviceSettings",
69882         "geoView",
69883         "widgetConfig",
69884         "platformEvents"
69885     ]
69886 };
69887
69888 });
69889 define('ripple/platform/cordova/2.0.0/spec', function (require, exports, module) {
69890 function loadWebworks(win, device) {
69891     var builder = require('ripple/platform/builder'),
69892         platform = device.id === "Playbook" || device.id === "Colt" ? "tablet" : "handset",
69893         webworks = require('ripple/platform/webworks.' + platform + '/2.0.0/spec');
69894
69895     builder.build(webworks.objects).into(win);
69896     builder.build(webworks.objects).into(window);
69897 }
69898
69899 module.exports = {
69900     id: "cordova",
69901     version: "2.0.0",
69902     name: "Apache Cordova",
69903     type: "platform",
69904     nativeMethods: {},
69905
69906     config: require('ripple/platform/cordova/2.0.0/spec/config'),
69907     device: require('ripple/platform/cordova/2.0.0/spec/device'),
69908     ui: require('ripple/platform/cordova/2.0.0/spec/ui'),
69909     events: require('ripple/platform/cordova/2.0.0/spec/events'),
69910
69911     initialize: function (win) {
69912         var honeypot = require('ripple/honeypot'),
69913             devices = require('ripple/devices'),
69914             device = devices.getCurrentDevice(),
69915             bridge = require('ripple/platform/cordova/2.0.0/bridge'),
69916             cordova,
69917             topCordova = window.top.require('ripple/platform/cordova/2.0.0/spec'),
69918             get = function () {
69919                 return cordova;
69920             },
69921             set = function (orig) {
69922                 if (cordova) {
69923                     return;
69924                 }
69925
69926                 cordova = orig;
69927
69928                 cordova.define.remove("cordova/exec");
69929                 cordova.define("cordova/exec", function (require, exports, module) {
69930                     module.exports = bridge.exec;
69931                 });
69932
69933                 cordova.UsePolling = true;
69934
69935                 //do nothing here as we will just call the callbacks ourselves
69936                 cordova.define.remove("cordova/plugin/android/polling");
69937                 cordova.define("cordova/plugin/android/polling", function (require, exports, module) {
69938                     module.exports = function () {};
69939                 });
69940
69941                 var builder = cordova.require('cordova/builder'),
69942                     allTheThings = window,
69943                     base = cordova.require('cordova/common'),
69944                     iosPlugin;
69945
69946                 //HACK: Overwrite all the things, handles when cordova.js executes before we start booting
69947                 builder.build(base.objects).intoAndClobber(allTheThings);
69948                 cordova.require('cordova/channel').onNativeReady.fire();
69949                 //  DIRTY HACK: once cordova is cleaned up, we do not
69950                 //  need this.
69951                 // reference issue: https://issues.apache.org/jira/browse/CB-1013
69952                 try {
69953                     iosPlugin = cordova.require('cordova/plugin/ios/device');
69954                     bridge.exec(function (info) {
69955                         iosPlugin.setInfo(info);
69956                     }, null, 'Device', 'getDeviceInfo', []);
69957                 } catch (e) {
69958                     cordova.require('cordova/channel').onCordovaInfoReady.fire();
69959                 }
69960             };
69961
69962         if (window.FileReader && !topCordova.nativeMethods.FileReader) {
69963             topCordova.nativeMethods.FileReader = window.FileReader;
69964         }
69965
69966         if (device.manufacturer === "Research In Motion") {
69967             loadWebworks(win, device);
69968         }
69969
69970         honeypot.monitor(win, "cordova").andRun(get, set);
69971     },
69972
69973     objects: {
69974         MediaError: {
69975             path: "cordova/2.0.0/MediaError"
69976         },
69977         org: {
69978             children: {
69979                 apache: {
69980                     children: {
69981                         cordova: {
69982                             children: {
69983                                 Logger: {
69984                                     path: "cordova/2.0.0/logger"
69985                                 },
69986                                 JavaPluginManager: {
69987                                     path: "cordova/2.0.0/JavaPluginManager"
69988                                 }
69989                             }
69990                         }
69991                     }
69992                 }
69993             }
69994         }
69995     }
69996 };
69997
69998 });
69999 define('ripple/platform/ivi/3.0/VehiclePanelEngine', function (require, exports, module) {
70000
70001 /*
70002  *  Copyright 2013 Intel Corporation.
70003  *
70004  * Licensed under the Apache License, Version 2.0 (the "License");
70005  * you may not use this file except in compliance with the License.
70006  * You may obtain a copy of the License at
70007  *
70008  * http://www.apache.org/licenses/LICENSE-2.0
70009  *
70010  * Unless required by applicable law or agreed to in writing, software
70011  * distributed under the License is distributed on an "AS IS" BASIS,
70012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70013  * See the License for the specific language governing permissions and
70014  * limitations under the License.
70015  */
70016
70017 var utils = require('ripple/utils'),
70018     db = require('ripple/db'),
70019     dbinit = require('ripple/platform/ivi/3.0/dbinit'),
70020     _vehicleMapStack = {},
70021     _databaseName = "ivi-vehicle-database",
70022     VehiclePanelEngine;
70023
70024 function _save (data) {
70025     db.saveObject(_databaseName, data);
70026 }
70027
70028 function _get () {
70029     var database = db.retrieveObject(_databaseName);
70030
70031     if (!database) {
70032         db.saveObject(_databaseName, dbinit.Vehicle);
70033         database = db.retrieveObject(_databaseName);
70034     }
70035
70036     return database;
70037 }
70038
70039 VehiclePanelEngine = function () {
70040     var _CONFIGURATION = "configuration", _AUTO = "auto",
70041         _database,
70042         _configuration, _currentConfiguration,
70043         _supported, _settings, _autoRunning;
70044
70045     function _init () {
70046         _database = _get();
70047
70048         _settings = _database.settingData;
70049
70050         _configuration = _database.configurationData;
70051         _currentConfiguration = _database.currentConfiguration;
70052
70053         _supported = _database.supported;
70054
70055         _autoRunning = _database.autoRunningData;
70056     }
70057
70058     this.saveData = function (supported, currentConfiguration, configuration, settings, autoRunning) {
70059         _database.supported = supported;
70060         _database.currentConfiguration = currentConfiguration;
70061         _database.settingData = settings;
70062         _database.configurationData[currentConfiguration] = configuration;
70063         _database.autoRunningData[0] = autoRunning;
70064
70065         _save(_database);
70066     };
70067
70068     function _formatVehicleDB (map, db) {
70069         var formatSettings = {},
70070             VehicleMap = map, vehicleData = db,
70071             property, name, item, i = 0;
70072
70073         for (property in VehicleMap) {
70074             name = property.split("-")[0];
70075             item = property.split("-")[1];
70076
70077             if (!formatSettings[name]) {
70078                 formatSettings[name] = {};
70079             }
70080
70081             formatSettings[name][item] = utils.copy(VehicleMap[property]);
70082             formatSettings[name][item].value = vehicleData[i];
70083
70084             i++;
70085         }
70086
70087         return formatSettings;
70088     }
70089
70090     /**
70091      * get
70092      * @return {Object}
70093      */
70094     this.getConfiguration = function () {
70095         var configuration = {}, i, j, dataIndex, tempArray,
70096             configurationMap = _vehicleMapStack.vehicleConfigurationMap,
70097             configurationData = _configuration;
70098
70099         for (j = 0; j < configurationData.length; j++) {
70100             dataIndex = _CONFIGURATION + j;
70101             configuration[dataIndex] = {};
70102
70103             for (i = 0; i < configurationMap.length; i++) {
70104                 tempArray = configurationMap[i].split("-");
70105
70106                 if (!configuration[dataIndex][tempArray[0]]) {
70107                     configuration[dataIndex][tempArray[0]] = {};
70108                 }
70109                 configuration[dataIndex][tempArray[0]][tempArray[1]] = configurationData[j][i];
70110             }
70111         }
70112
70113         return configuration;
70114     };
70115
70116     /**
70117      * get
70118      * @return {String}
70119      */
70120     this.getCurrentConfiguration = function () {
70121         return _CONFIGURATION + _currentConfiguration;
70122     };
70123
70124     /**
70125      * get
70126      * @return {Array}
70127      */
70128     this.getProperties = function () {
70129         return _vehicleMapStack.vehicleProperties;
70130     };
70131
70132     /**
70133      * get supported vehicle properties name.
70134      * @return {Array}
70135      */
70136     this.getSupported = function () {
70137         return _supported;
70138     };
70139
70140     /**
70141      * get property unit.
70142      * @param property
70143      * @param item
70144      * @return {String}
70145      */
70146     this.getPropertyUnit = function (property, item) {
70147         var unitKey = property + "-" + item,
70148             propertyUnitMap = _vehicleMapStack.vehiclePropertyUnitsMap;
70149
70150         return !propertyUnitMap[unitKey] ? "" : "(" + propertyUnitMap[unitKey] + ")";
70151     };
70152
70153     this.getPropertyRange = function (property, item) {
70154         var rangeKey = property + "-" + item,
70155             propertyRangeMap = _vehicleMapStack.vehiclePropertyRangeMap;
70156
70157         return !propertyRangeMap[rangeKey] ? false : propertyRangeMap[rangeKey];
70158     };
70159
70160     /**
70161      * get
70162      * @param property
70163      * @param item
70164      * @return {*}
70165      */
70166     this.getPropertyConstant = function (property, item) {
70167         var propertyConstants = _vehicleMapStack.vehiclePropertyConstantsMap;
70168
70169         return !propertyConstants[property] ? null : propertyConstants[property][item];
70170     };
70171
70172     this.getSettings = function () {
70173         return _formatVehicleDB(_vehicleMapStack.vehicleSettingMap, _settings);
70174     };
70175
70176     this.getAutoRunning = function () {
70177         var autoRunning = {}, i,
70178             autoRunningMap = _vehicleMapStack.vehicleAutoRunningMap,
70179             autoRunningData = _autoRunning;
70180
70181         for (i = 0; i < _autoRunning.length; i++) {
70182             autoRunning[_AUTO + i] = _formatVehicleDB(autoRunningMap, autoRunningData[i]);
70183         }
70184         return autoRunning;
70185     };
70186
70187     _init();
70188 };
70189
70190 //can support all properties.
70191 _vehicleMapStack.vehicleProperties = [
70192     "VehicleSpeed", "EngineSpeed", "VehiclePowerMode", "TripMeter",
70193     "Acceleration", "Transmission", "CruiseControlStatus", "WheelBrake",
70194     "LightStatus", "InteriorLightStatus", "Horn", "Fuel", "EngineOil",
70195     "Location", "ExteriorBrightness", "Temperature", "RainSensor",
70196     "WindshieldWiper", "HVAC", "WindowStatus", "Sunroof", "ConvertibleRoof",
70197     "VehicleId", "Size", "FuelInfo", "VehicleType", "Doors",
70198     "TransmissionGearType", "WheelInformation", "Odometer", "Fluid", "Battery",
70199     "TirePressure", "TireTemperature", "SecurityAlert", "ParkingBrake",
70200     "ParkingLight", "HazardLight", "AntilockBrakingSystem", "TractionControlSystem",
70201     "VehicleTopSpeedLimit", "AirbagStatus", "DoorStatus", "SeatBeltStatus",
70202     "OccupantStatus", "ObstacleDistance", "NightMode", "DrivingMode",
70203     "TurnSignal", "ButtonEvent"
70204 ];
70205
70206 //Vehicle Configuration
70207 _vehicleMapStack.vehicleConfigurationMap = [
70208     "VehicleId-WMI", "VehicleId-VIN",
70209     "Size-width", "Size-height", "Size-length",
70210     "FuelInfo-type", "FuelInfo-refuelPosition",
70211     "VehicleType-type",
70212     "Doors-doorsPerRow",
70213     "TransmissionGearType-transmissionGearType",
70214     "WheelInformation-frontWheelRadius", "WheelInformation-rearWheelRadius", "WheelInformation-wheelTrack", "WheelInformation-ABS"
70215 ];
70216
70217 //all ranged attributes' min. max and step.
70218 _vehicleMapStack.vehiclePropertyRangeMap = {
70219     "VehicleSpeed-vehicleSpeed": [0, 400, 1],
70220     "EngineSpeed-engineSpeed": [0, 10000, 20],
70221     "Acceleration-x": [0, 200, 1],
70222     "Acceleration-y": [0, 200, 1],
70223     "Acceleration-z": [0, 200, 1],
70224     "Fuel-level": [0, 100, 1],
70225     "Fuel-range": [0, 1000, 1],
70226     "Fuel-instantConsumption": [0, 100, 1],
70227     "Fuel-instantEconomy": [0, 100, 1],
70228     "Fuel-averageEconomy": [0, 100, 1],
70229     "EngineOil-remaining": [0, 100, 1],
70230     "EngineOil-temperature": [0, 100, 1],
70231     "EngineOil-pressure": [0, 1000, 1],
70232     "Location-latitude": [-180, 180, 1],
70233     "Location-longitude": [-19, 90, 1],
70234     "Location-altitude": [0, 100, 1],
70235     "Location-direction": [0, 360, 1],
70236     "ExteriorBrightness-exteriorBrightness": [0, 100, 1],
70237     "Temperature-interior": [-5, 35, 1],
70238     "Temperature-exterior": [-40, 60, 1],
70239     "Odometer-odometer": [0, 10000, 10],
70240     "CruiseControlStatus-speed": [1, 100, 1],
70241     "HVAC-targetTemperature": [0, 35, 7],
70242     "Sunroof-openness": [0, 100, 1],
70243     "Sunroof-tilt": [0, 100, 1],
70244     "ConvertibleRoof-openness": [0, 100, 1],
70245     "WindowStatus-openness": [0, 100, 1],
70246     "VehicleTopSpeedLimit-vehicleTopSpeedLimit": [0, 400, 1],
70247     "ObstacleDistance-obstacleDistance": [0, 120, 1],
70248     "Fluid-transmission": [0, 100, 1],
70249     "Fluid-brake": [0, 100, 1],
70250     "Fluid-washer": [0, 100, 1],
70251     "Battery-voltage": [0, 12, 1],
70252     "Battery-current": [0, 200, 1],
70253     "TirePressure-leftFront": [0, 500, 1],
70254     "TirePressure-rightFront": [0, 500, 1],
70255     "TirePressure-leftRear": [0, 500, 1],
70256     "TirePressure-rightRear": [0, 500, 1],
70257     "TireTemperature-leftFront": [0, 60, 1],
70258     "TireTemperature-rightFront": [0, 60, 1],
70259     "TireTemperature-leftRear": [0, 60, 1],
70260     "TireTemperature-rightRear": [0, 60, 1],
70261     "TurnSignal-turnSignal": [0, 100, 1],
70262     "ButtonEvent-buttonEvent": [0, 100, 1]
70263 };
70264
70265 //simulate car running attributes' controller-types.
70266 _vehicleMapStack.vehicleAutoRunningMap = {
70267     "VehicleSpeed-vehicleSpeed": {
70268         "type": "range"
70269     },
70270     "EngineSpeed-engineSpeed": {
70271         "type": "range"
70272     },
70273     "VehiclePowerMode-vehiclePowerMode": {
70274         "type": "select",
70275         "options": [{"OFF": 0},{"ACCESSORY1": 1},{"ACCESSORY2": 2},{"RUN": 3}]
70276     },
70277     "TripMeter-tripMeters": {
70278         "type": "text"
70279     },
70280     "Acceleration-x": {
70281         "type": "range"
70282     },
70283     "Acceleration-y": {
70284         "type": "range"
70285     },
70286     "Acceleration-z": {
70287         "type": "range"
70288     },
70289     "Fuel-level": {
70290         "type": "range"
70291     },
70292     "Fuel-range": {
70293         "type": "range"
70294     },
70295     "Fuel-instantConsumption": {
70296         "type": "range"
70297     },
70298     "Fuel-instantEconomy": {
70299         "type": "range"
70300     },
70301     "Fuel-averageEconomy": {
70302         "type": "range"
70303     },
70304     "EngineOil-remaining": {
70305         "type": "range"
70306     },
70307     "EngineOil-temperature": {
70308         "type": "range"
70309     },
70310     "EngineOil-pressure": {
70311         "type": "range"
70312     },
70313     "Location-latitude": {
70314         "type": "range"
70315     },
70316     "Location-longitude": {
70317         "type": "range"
70318     },
70319     "Location-altitude": {
70320         "type": "range"
70321     },
70322     "Location-direction": {
70323         "type": "range"
70324     },
70325     "ExteriorBrightness-exteriorBrightness": {
70326         "type": "range"
70327     },
70328     "Temperature-interior": {
70329         "type": "range"
70330     },
70331     "Temperature-exterior": {
70332         "type": "range"
70333     },
70334     "RainSensor-rainSensor": {
70335         "type": "select",
70336         "options": [{"No Rain": 0},{"Rain 1": 1},{"Rain 2": 2},{"Rain 3": 3},{"Rain 4": 4},{"Rain 5": 5},
70337             {"Rain 6": 6},{"Rain 7": 7},{"Rain 8": 8},{"Rain 9": 9},{"Heaviest": 10}]
70338     },
70339     "Odometer-odometer": {
70340         "type": "range"
70341     },
70342     "TurnSignal-turnSignal": {
70343         "type": "range"
70344     },
70345     "ButtonEvent-buttonEvent": {
70346         "type": "range"
70347     }
70348 };
70349
70350 //Vehicle Setting attributes' controller-types.
70351 _vehicleMapStack.vehicleSettingMap = {
70352     "Transmission-gearPosition": {
70353         "type": "select",
70354         "options": [{"NEUTRAL": 0},{"FIRST": 1},{"SECOND": 2},{"THIRD": 3}, {"FORTH": 4},{"FIFTH": 5},
70355             {"SIXTH": 6},{"SEVENTH": 7}, {"EIGHTH": 8},{"NINTH": 9},{"TENTH": 10},{"CVT": 64},
70356             {"REVERSE": 128},{"PARK": 255}]
70357     },
70358     "Transmission-mode": {
70359         "type": "select",
70360         "options": [{"NORMAL": 0},{"SPORT": 1},{"ECONOMY": 2}, {"OEMCUSTOM1": 3},{"OEMCUSTOM2": 4}]
70361     },
70362     "CruiseControlStatus-activated": {
70363         "type": "radio",
70364         "options": [{"Active": true}, {"Inactive": false}]
70365     },
70366     "CruiseControlStatus-speed": {
70367         "type": "range"
70368     },
70369     "WheelBrake-engaged": {
70370         "type": "radio",
70371         "options": [{"Engaged": true}, {"Disengaged": false}]
70372     },
70373     "LightStatus-head": {
70374         "type": "radio",
70375         "options": [{"On": true}, {"Off": false}]
70376     },
70377     "LightStatus-rightTurn": {
70378         "type": "radio",
70379         "options": [{"On": true}, {"Off": false}]
70380     },
70381     "LightStatus-leftTurn": {
70382         "type": "radio",
70383         "options": [{"On": true}, {"Off": false}]
70384     },
70385     "LightStatus-brake": {
70386         "type": "radio",
70387         "options": [{"On": true}, {"Off": false}]
70388     },
70389     "LightStatus-fog": {
70390         "type": "radio",
70391         "options": [{"On": true}, {"Off": false}]
70392     },
70393     "LightStatus-hazard": {
70394         "type": "radio",
70395         "options": [{"On": true}, {"Off": false}]
70396     },
70397     "LightStatus-parking": {
70398         "type": "radio",
70399         "options": [{"On": true}, {"Off": false}]
70400     },
70401     "LightStatus-highBeam": {
70402         "type": "radio",
70403         "options": [{"On": true}, {"Off": false}]
70404     },
70405     "InteriorLightStatus-passenger": {
70406         "type": "radio",
70407         "options": [{"On": true}, {"Off": false}]
70408     },
70409     "InteriorLightStatus-driver": {
70410         "type": "radio",
70411         "options": [{"On": true}, {"Off": false}]
70412     },
70413     "InteriorLightStatus-center": {
70414         "type": "radio",
70415         "options": [{"On": true}, {"Off": false}]
70416     },
70417     "Horn-on": {
70418         "type": "radio",
70419         "options": [{"On": true}, {"Off": false}]
70420     },
70421     "WindshieldWiper-windshieldWiper": {
70422         "type": "select",
70423         "options": [{"OFF": 0},{"SLOWEST": 1},{"FASTEST": 5},{"AUTO": 10}]
70424     },
70425     "HVAC-airflowDirection": {
70426         "type": "select",
70427         "options": [{"FRONTPANEL": 0},{"FLOORDUCT": 1},{"FRONT": 0x02}, {"DEFROSTER": 0x04}]
70428     },
70429     "HVAC-fanSpeed": {
70430         "type": "select",
70431         "options": [{"0": 0},{"1": 1},{"2": 2},{"3": 3},{"4": 4},{"5": 5}, {"6": 6},{"7": 7}]
70432     },
70433     "HVAC-targetTemperature": {
70434         "type": "range"
70435     },
70436     "HVAC-airConditioning": {
70437         "type": "radio",
70438         "options": [{"On": true}, {"Off": false}]
70439     },
70440     "HVAC-airRecirculation": {
70441         "type": "radio",
70442         "options": [{"On": true}, {"Off": false}]
70443     },
70444     "HVAC-heater": {
70445         "type": "radio",
70446         "options": [{"On": true}, {"Off": false}]
70447     },
70448     "HVAC-steeringWheelHeater": {
70449         "type": "radio",
70450         "options": [{"On": true}, {"Off": false}]
70451     },
70452     "HVAC-seatHeater": {
70453         "type": "radio",
70454         "options": [{"On": true}, {"Off": false}]
70455     },
70456     "HVAC-seatCooler": {
70457         "type": "radio",
70458         "options": [{"On": true}, {"Off": false}]
70459     },
70460     "Sunroof-openness": {
70461         "type": "range"
70462     },
70463     "Sunroof-tilt": {
70464         "type": "range"
70465     },
70466     "ConvertibleRoof-openness": {
70467         "type": "range"
70468     },
70469     "SecurityAlert-securityAlert": {
70470         "type": "radio",
70471         "options": [{"On": true}, {"Off": false}]
70472     },
70473     "ParkingBrake-parkingBrake": {
70474         "type": "radio",
70475         "options": [{"Engaged": true}, {"Disengaged": false}]
70476     },
70477     "ParkingLight-parkingLight": {
70478         "type": "radio",
70479         "options": [{"Engaged": true}, {"Disengaged": false}]
70480     },
70481     "HazardLight-hazardLight": {
70482         "type": "radio",
70483         "options": [{"Engaged": true}, {"Disengaged": false}]
70484     },
70485     "AntilockBrakingSystem-antilockBrakingSystem": {
70486         "type": "radio",
70487         "options":[{"Engaged": true}, {"Idle": false}]
70488     },
70489     "TractionControlSystem-tractionControlSystem": {
70490         "type": "radio",
70491         "options": [{"On": true}, {"Off": false}]
70492     },
70493     "VehicleTopSpeedLimit-vehicleTopSpeedLimit": {
70494         "type": "range"
70495     },
70496     "WindowStatus-openness": {
70497         "type": "range"
70498     },
70499     "WindowStatus-defrost": {
70500         "type": "radio",
70501         "options": [{"On": true}, {"Off": false}]
70502     },
70503     "AirbagStatus-airbagStatus": {
70504         "type": "select",
70505         "options": [{"INACTIVE": 0},{"ACTIVE": 1},{"DEPLOYED": 2}]
70506     },
70507     "DoorStatus-doorStatus": {
70508         "type": "select",
70509         "options": [{"CLOSED": 0},{"OPEN": 1},{"AJAR": 2}]
70510     },
70511     "DoorStatus-doorLockStatus": {
70512         "type": "radio",
70513         "options": [{"Locked": true}, {"Unlocked": false}]
70514     },
70515     "DoorStatus-childLockStatus": {
70516         "type": "radio",
70517         "options": [{"On": true}, {"Off": false}]
70518     },
70519     "SeatBeltStatus-seatBeltStatus": {
70520         "type": "radio",
70521         "options": [{"Fasten": true}, {"Unfastened": false}]
70522     },
70523     "OccupantStatus-occupantStatus": {
70524         "type": "select",
70525         "options": [{"VACANT": 0},{"CHILD": 1},{"ADULT": 2}]
70526     },
70527     "ObstacleDistance-obstacleDistance": {
70528         "type": "range"
70529     },
70530     "NightMode-nightMode": {
70531         "type": "radio",
70532         "options": [{"Night": true}, {"Day": false}]
70533     },
70534     "DrivingMode-drivingMode": {
70535         "type": "select",
70536         "options": [{"Not Driving": 0},{"Driving": 1}]
70537     },
70538     "Fluid-transmission": {
70539         "type": "range"
70540     },
70541     "Fluid-brake": {
70542         "type": "range"
70543     },
70544     "Fluid-washer": {
70545         "type": "range"
70546     },
70547     "Battery-voltage": {
70548         "type": "range"
70549     },
70550     "Battery-current": {
70551         "type": "range"
70552     },
70553     "TirePressure-leftFront": {
70554         "type": "range"
70555     },
70556     "TirePressure-rightFront": {
70557         "type": "range"
70558     },
70559     "TirePressure-leftRear": {
70560         "type": "range"
70561     },
70562     "TirePressure-rightRear": {
70563         "type": "range"
70564     },
70565     "TireTemperature-leftFront": {
70566         "type": "range"
70567     },
70568     "TireTemperature-rightFront": {
70569         "type": "range"
70570     },
70571     "TireTemperature-leftRear": {
70572         "type": "range"
70573     },
70574     "TireTemperature-rightRear": {
70575         "type": "range"
70576     }
70577 };
70578
70579 //attributes units
70580 _vehicleMapStack.vehiclePropertyUnitsMap = {
70581     "VehicleSpeed-vehicleSpeed": "kph",
70582     "EngineSpeed-engineSpeed": "rpm",
70583     "TripMeter-tripMeters": "[m,...]",
70584     "CruiseControlStatus-speed": "kph",
70585     "Fuel-level": "%",
70586     "Fuel-instantConsumption": "ml/s",
70587     "Fuel-instantEconomy": "km/l",
70588     "Fuel-averageEconomy": "km/l",
70589     "EngineOil-remaining": "%",
70590     "EngineOil-temperature": "C",
70591     "EngineOil-pressure": "kpa",
70592     "ExteriorBrightness-exteriorBrightness": "lux",
70593     "Temperature-interior": "C",
70594     "Temperature-exterior": "C",
70595     "HVAC-targetTemperature": "C",
70596     "Sunroof-openness": "%",
70597     "Sunroof-tilt": "%",
70598     "ConvertibleRoof-openness": "%",
70599     "WindowStatus-openness": "%",
70600     "ObstacleDistance-obstacleDistance": "m",
70601     "Size-width": "mm",
70602     "Size-height": "mm",
70603     "Size-length": "mm",
70604     "WheelInformation-frontWheelRadius": "mm",
70605     "WheelInformation-rearWheelRadius": "mm",
70606     "WheelInformation-wheelTrack": "mm",
70607     "Odometer-odometer": "km",
70608     "Fluid-transmission": "%",
70609     "Fluid-brake": "%",
70610     "Fluid-washer": "%",
70611     "Battery-voltage": "V",
70612     "Battery-current": "A",
70613     "TirePressure-leftFront": "kpa",
70614     "TirePressure-rightFront": "kpa",
70615     "TirePressure-leftRear": "kpa",
70616     "TirePressure-rightRear": "kpa",
70617     "TireTemperature-leftFront": "C",
70618     "TireTemperature-rightFront": "C",
70619     "TireTemperature-leftRear": "C",
70620     "TireTemperature-rightRear": "C",
70621     "VehicleTopSpeedLimit-vehicleTopSpeedLimit": "kph"
70622 };
70623
70624 //key and value of select types in attributes
70625 _vehicleMapStack.vehiclePropertyConstantsMap = {
70626     "FuelInfo": {
70627         "type": {
70628             "val0": "GASOLINE",
70629             "val1": "HIGH_OCTANE",
70630             "val2": "DIESEL",
70631             "val3": "ELECTRIC",
70632             "val4": "HYDROGEN"
70633         },
70634         "refuelPosition": {
70635             "val0": "LEFT",
70636             "val1": "RIGHT",
70637             "val2": "FRONT",
70638             "val3": "REAR"
70639         }
70640     },
70641     "VehicleType": {
70642         "type": {
70643             "val0": "SEDAN",
70644             "val1": "COUPE",
70645             "val2": "CABRIOLE",
70646             "val3": "ROADSTER",
70647             "val4": "SUV",
70648             "val5": "TRUCK"
70649         }
70650     },
70651     "TransmissionGearType": {
70652         "transmissionGearType": {
70653             "val0": "AUTO",
70654             "val1": "MANUAL",
70655             "val2": "CV"
70656         }
70657     },
70658     "VehiclePowerMode": {
70659         "vehiclePowerMode": {
70660             "val0": "OFF",
70661             "val1": "ACCESSORY1",
70662             "val2": "ACCESSORY2",
70663             "val3": "RUN"
70664         }
70665     }
70666 };
70667
70668 exports.VehiclePanelEngine = new VehiclePanelEngine();
70669
70670 });
70671 define('ripple/platform/ivi/3.0/WebAPIError', function (require, exports, module) {
70672 /*
70673  *  Copyright 2013 Intel Corporation.
70674  *
70675  * Licensed under the Apache License, Version 2.0 (the "License");
70676  * you may not use this file except in compliance with the License.
70677  * You may obtain a copy of the License at
70678  *
70679  * http://www.apache.org/licenses/LICENSE-2.0
70680  *
70681  * Unless required by applicable law or agreed to in writing, software
70682  * distributed under the License is distributed on an "AS IS" BASIS,
70683  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70684  * See the License for the specific language governing permissions and
70685  * limitations under the License.
70686  */
70687
70688 var errorcode = require('ripple/platform/ivi/3.0/errorcode');
70689
70690 var msg = {
70691     1: "Permission denied.",
70692     2: "Unsupported property.",
70693     3: "Timeout.",
70694     10: "Unknown."
70695 },
70696     errType = {
70697     1: "PermissionDeniedError",
70698     2: "PropertyUnavailableError",
70699     3: "TimeoutError",
70700     10: "UnknownError"
70701 };
70702
70703 module.exports = function (code, message, name) {
70704     var _code, _message, _name;
70705
70706     if (typeof code !== 'number') {
70707         _code = errorcode.UNKNOWN;
70708         _message = msg[_code];
70709         _name = errType[_code];
70710     } else {
70711         _code = code;
70712         if (typeof message === 'string') {
70713             _message = message;
70714         } else {
70715             _message = msg[_code];
70716         }
70717         if (typeof name === 'string') {
70718             _name = name;
70719         } else {
70720             _name = errType[_code];
70721         }
70722     }
70723
70724     this.__defineGetter__("code", function () {
70725         return _code;
70726     });
70727     this.__defineGetter__("message", function () {
70728         return _message;
70729     });
70730     this.__defineGetter__("name", function () {
70731         return _name;
70732     });
70733 };
70734
70735 });
70736 define('ripple/platform/ivi/3.0/WebAPIException', function (require, exports, module) {
70737 /*
70738  *  Copyright 2013 Intel Corporation.
70739  *
70740  * Licensed under the Apache License, Version 2.0 (the "License");
70741  * you may not use this file except in compliance with the License.
70742  * You may obtain a copy of the License at
70743  *
70744  * http://www.apache.org/licenses/LICENSE-2.0
70745  *
70746  * Unless required by applicable law or agreed to in writing, software
70747  * distributed under the License is distributed on an "AS IS" BASIS,
70748  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70749  * See the License for the specific language governing permissions and
70750  * limitations under the License.
70751  */
70752
70753 var errorcode = require('ripple/platform/ivi/3.0/errorcode');
70754
70755 var msg = {
70756         1: "Permission denied.",
70757         2: "Unsupported property.",
70758         3: "Timeout.",
70759         10: "Unknown."
70760     },
70761     errType = {
70762         1: "PermissionDeniedError",
70763         2: "PropertyUnavailableError",
70764         3: "TimeoutError",
70765         10: "UnknownError"
70766     };
70767
70768 module.exports = function (code, message, name) {
70769     var g, c, _code, _message, _name;
70770
70771     for (c in errorcode) {
70772         g = errorcode.__lookupGetter__(c);
70773         if (g) {
70774             this.__defineGetter__(c, g);
70775         }
70776     }
70777
70778     if (typeof code !== 'number') {
70779         _code = errorcode.UNKNOWN;
70780         _message = msg[_code];
70781         _name = errType[_code];
70782     } else {
70783         _code = code;
70784         if (typeof message === 'string') {
70785             _message = message;
70786         } else {
70787             _message = msg[_code];
70788         }
70789         if (typeof name === 'string') {
70790             _name = name;
70791         } else {
70792             _name = errType[_code];
70793         }
70794     }
70795
70796     this.__defineGetter__("code", function () {
70797         return _code;
70798     });
70799     this.__defineGetter__("message", function () {
70800         return _message;
70801     });
70802     this.__defineGetter__("name", function () {
70803         return _name;
70804     });
70805 };
70806
70807 });
70808 define('ripple/platform/ivi/3.0/dbinit', function (require, exports, module) {
70809 /*
70810  *  Copyright 2013 Intel Corporation.
70811  *
70812  * Licensed under the Apache License, Version 2.0 (the "License");
70813  * you may not use this file except in compliance with the License.
70814  * You may obtain a copy of the License at
70815  *
70816  * http://www.apache.org/licenses/LICENSE-2.0
70817  *
70818  * Unless required by applicable law or agreed to in writing, software
70819  * distributed under the License is distributed on an "AS IS" BASIS,
70820  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70821  * See the License for the specific language governing permissions and
70822  * limitations under the License.
70823  */
70824
70825 var exception = require('ripple/exception'),
70826     DBBuilder,
70827     _data = {
70828         dbBuilder: null
70829     },
70830     _self = {};
70831
70832 function _initialize() {
70833     _data.dbBuilder = new DBBuilder();
70834
70835     _data.dbBuilder.register("Vehicle", "dbvehicle.json");
70836 }
70837
70838 DBBuilder = function () {
70839     var self;
70840
70841     // private
70842     function formatString(str) {
70843         return str.replace(/^\s+|[\t\n\r\v]+|\s+$/g, "").replace(/\s+/g, "");
70844     }
70845
70846     // private
70847     function formatHex(str) {
70848         return str.replace(/,(0x[0-9a-fA-F]+?),/g, ',"$1",');
70849     }
70850
70851     // public
70852     function register(type, dbFile, Extension) {
70853         _data[type] = Extension ? new Extension() : {};
70854
70855         if (!dbFile)
70856             return;
70857
70858         _self.__defineGetter__(type, function () {
70859             var fnInit;
70860
70861             if (!_data[type].db) {
70862                 fnInit = _data[type].initdb || initdb;
70863                 _data[type].db = fnInit(dbFile);
70864             }
70865
70866             return _data[type].db;
70867         });
70868     }
70869
70870     function initdb(dbFile) {
70871         var xmlHttp, res;
70872
70873         try {
70874             xmlHttp = new XMLHttpRequest();
70875             xmlHttp.open("GET", "dbsamples/" + dbFile, false);
70876             xmlHttp.send();
70877         } catch (e) {
70878             exception.handle(e);
70879         }
70880
70881         if (!xmlHttp.responseText) {
70882             return null;
70883         }
70884
70885         res = formatHex(formatString(xmlHttp.responseText));
70886
70887         return JSON.parse(res);
70888     }
70889
70890     self = {
70891         register: register,
70892         initdb:   initdb
70893     };
70894
70895     return self;
70896 };
70897
70898 _initialize();
70899
70900 module.exports = _self;
70901
70902 });
70903 define('ripple/platform/ivi/3.0/errorcode', function (require, exports, module) {
70904 /*
70905  *  Copyright 2013 Intel Corporation.
70906  *
70907  * Licensed under the Apache License, Version 2.0 (the "License"),
70908  * you may not use this file except in compliance with the License.
70909  * You may obtain a copy of the License at
70910  *
70911  * http://www.apache.org/licenses/LICENSE-2.0
70912  *
70913  * Unless required by applicable law or agreed to in writing, software
70914  * distributed under the License is distributed on an "AS IS" BASIS,
70915  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70916  * See the License for the specific language governing permissions and
70917  * limitations under the License.
70918  */
70919
70920 var _self = {};
70921
70922 _self.__defineGetter__("PERMISSION_DENIED", function () {
70923     return 1;
70924 });
70925
70926 _self.__defineGetter__("PROPERTY_UNAVAILABLE", function () {
70927     return 2;
70928 });
70929
70930 _self.__defineGetter__("TIMEOUT", function () {
70931     return 3;
70932 });
70933
70934 _self.__defineGetter__("UNKNOWN", function () {
70935     return 10;
70936 });
70937
70938 module.exports = _self;
70939
70940 });
70941 define('ripple/platform/ivi/3.0/spec/btdevices', function (require, exports, module) {
70942 /*
70943  *  Copyright 2012 Intel Corporation.
70944  *
70945  * Licensed under the Apache License, Version 2.0 (the "License");
70946  * you may not use this file except in compliance with the License.
70947  * You may obtain a copy of the License at
70948  *
70949  * http://www.apache.org/licenses/LICENSE-2.0
70950  *
70951  * Unless required by applicable law or agreed to in writing, software
70952  * distributed under the License is distributed on an "AS IS" BASIS,
70953  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70954  * See the License for the specific language governing permissions and
70955  * limitations under the License.
70956  */
70957
70958 module.exports = {
70959     "22:33:44:12:34:56": {
70960         "name": "Tizen Phone",
70961         "address": "22:33:44:12:34:56",
70962         "deviceClass": {
70963             "major": 0x02,
70964             "majorName": "PHONE",
70965             "minor": 0x03,
70966             "minorName": "PHONE_SMARTPHONE",
70967             "services": [0x0080],
70968             "servicesName": ["OBJECT_TRANSFER"]
70969         },
70970         "isTrusted": false,
70971         "services": {
70972             "5bce9431-6c75-32ab-afe0-2ec108a30860" : {
70973                 "name": "Data Exchange",
70974                 "uuid": "5bce9431-6c75-32ab-afe0-2ec108a30860",
70975                 "protocol": "RFCOMM"
70976             },
70977             "3537d485-0c1e-445a-a066-43fafcfb61d1" : {
70978                 "name": "Data Transfer",
70979                 "uuid": "3537d485-0c1e-445a-a066-43fafcfb61d1",
70980                 "protocol": "RFCOMM"
70981             }
70982         }
70983     },
70984     "22:33:44:12:34:88": {
70985         "name": "Keyboard",
70986         "address": "22:33:44:12:34:88",
70987         "deviceClass": {
70988             "major": 0x05,
70989             "majorName": "PERIPHERAL",
70990             "minor": 0x10,
70991             "minorName": "PERIPHERAL_KEYBOARD",
70992             "services": [0x0080],
70993             "servicesName": ["OBJECT_TRANSFER"]
70994         },
70995         "isTrusted": true,
70996         "services": {
70997             "3537d485-0c1e-445a-a066-43fafcfb61d1" : {
70998                 "name": "Data Exchange",
70999                 "uuid": "3537d485-0c1e-445a-a066-43fafcfb61d1",
71000                 "protocol": "RFCOMM"
71001             }
71002         }
71003     },
71004     "22:33:44:88:34:58": {
71005         "name": "Tizen Laptop",
71006         "address": "22:33:44:88:34:58",
71007         "deviceClass": {
71008             "major": 0x01,
71009             "majorName": "COMPUTER",
71010             "minor": 0x03,
71011             "minorName": "COMPUTER_LAPTOP",
71012             "services": [0x0080],
71013             "servicesName": ["OBJECT_TRANSFER"]
71014         },
71015         "isTrusted": true,
71016         "services": {
71017             "3537d485-0c1e-445a-a066-43fafcfb61d1" : {
71018                 "name": "Data Exchange",
71019                 "uuid": "3537d485-0c1e-445a-a066-43fafcfb61d1",
71020                 "protocol": "RFCOMM"
71021             }
71022         }
71023     }
71024 };
71025
71026 });
71027 define('ripple/platform/ivi/3.0/spec/config', function (require, exports, module) {
71028 /*
71029  *  Copyright 2011 Research In Motion Limited.
71030  *  Copyright 2011 Intel Corporation.
71031  *
71032  * Licensed under the Apache License, Version 2.0 (the "License");
71033  * you may not use this file except in compliance with the License.
71034  * You may obtain a copy of the License at
71035  *
71036  * http://www.apache.org/licenses/LICENSE-2.0
71037  *
71038  * Unless required by applicable law or agreed to in writing, software
71039  * distributed under the License is distributed on an "AS IS" BASIS,
71040  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71041  * See the License for the specific language governing permissions and
71042  * limitations under the License.
71043  */
71044 var utils = require('ripple/utils'),
71045     db = require('ripple/db'),
71046     constants = require('ripple/constants');
71047
71048 module.exports = {
71049     fileName: "config.xml",
71050     validateVersion: function (configValidationObject) {
71051         var valid = true;
71052         // no xmlns:JIL in wac 2.0 spec
71053         valid = !!configValidationObject.widget.validationResult[0].attributes.xmlns.valid;
71054
71055         return valid;
71056     },
71057     extractInfo: function (configValidationObject) {
71058         if (!configValidationObject) {
71059             return null;
71060         }
71061
71062         var widgetInfo = {},
71063             configFeatures,
71064             configPreferences,
71065             preferenceName,
71066             platform, rst, i, j,
71067             settingRst = {
71068                 'screen-orientation': 'portrait',
71069                 'context-menu': 'enable',
71070                 'background-support': 'disable',
71071                 encryption: 'disable',
71072                 'install-location': 'auto',
71073                 'hwkey-event': 'enable'
71074             };
71075
71076         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
71077         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
71078         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
71079         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
71080         if (configValidationObject.widget.children.application.validationResult[0].valid) {
71081             widgetInfo.tizenAppId = configValidationObject.widget.children.application.validationResult[0].attributes.id.value;
71082             widgetInfo.tizenPackageId = configValidationObject.widget.children.application.validationResult[0].attributes.package.value;
71083         }
71084
71085         widgetInfo.features = {};
71086
71087         if (configValidationObject.widget.children.setting.hasOwnProperty('validationResult') === true) {
71088             rst = configValidationObject.widget.children.setting.validationResult;
71089             // the first one has higher priority per platform implementation
71090             for (i = rst.length -1 ; i >= 0; i--) {
71091                 if (rst[i].valid === true) {
71092                     for (j in rst[i].attributes) {
71093                         if (rst[i].attributes[j].value !== undefined) {
71094                             settingRst[j] = rst[i].attributes[j].value;
71095                         }
71096                     }
71097                 }
71098             }
71099             db.save("layout", settingRst["screen-orientation"]);
71100         }
71101
71102         configFeatures = configValidationObject.widget.children.feature.validationResult;
71103         utils.forEach(configFeatures, function (f) {
71104             if (f.valid === true) {
71105                 var feature = {id: f.attributes.name.value,
71106                          required: f.attributes.required.valid};
71107                 widgetInfo.features[feature.id] = feature;
71108             }
71109         });
71110
71111         widgetInfo.preferences = {};
71112
71113         configPreferences = configValidationObject.widget.children.preference.validationResult;
71114
71115         platform = require('ripple/platform');
71116         utils.forEach(configPreferences, function (preference) {
71117             preferenceName = preference.attributes.name.value;
71118             if (preferenceName) {
71119                 widgetInfo.preferences[preferenceName] = {
71120                     "key": preferenceName,
71121                     "value": preference.attributes.value.value || "",
71122                     "readonly": preference.attributes.readonly.value === "true"
71123                 };
71124
71125                 db.save(preferenceName,
71126                         widgetInfo.preferences[preferenceName].value,
71127                         platform.getPersistencePrefix(widgetInfo.id));
71128             }
71129         });
71130
71131         return widgetInfo;
71132     },
71133     schema: {
71134         rootElement: "widget",
71135         widget: {
71136             nodeName: "widget",
71137             required: true,
71138             occurrence: 1,
71139             helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in the configuration document and may have the following child elments: name,description,icon,author,license,content,feature and preference.The \"widget\" element MAY have following attributes: id,version,height,width, defaultlocale, xml:lang and dir",
71140             attributes: {
71141                 xmlns: {
71142                     attributeName: "xmlns",
71143                     required: true,
71144                     type: "list",
71145                     listValues: ["http://www.w3.org/ns/widgets"]
71146                 },
71147                 "xmlns:tizen": {
71148                     attributeName: "xmlns:tizen",
71149                     required: false,
71150                     type: "list",
71151                     listValues: ["http://tizen.org/ns/widgets"]
71152                 },
71153                 "xml:lang": {
71154                     attributeName: "xml:lang",
71155                     required: false,
71156                     type: "iso-language"
71157                 },
71158                 dir: {
71159                     attributeName: "dir",
71160                     required: false,
71161                     type: "list",
71162                     listValues: ["ltr", "rtl", "lro", "rlo"]
71163                 },
71164                 id: {
71165                     attributeName: "id",
71166                     required: false,
71167                     type: "string"
71168                 },
71169                 version: {
71170                     attributeName: "version",
71171                     required: false,
71172                     type: "string"
71173                 },
71174                 height: {
71175                     attributeName: "height",
71176                     required: false,
71177                     type: "integer"
71178                 },
71179                 width: {
71180                     attributeName: "width",
71181                     required: false,
71182                     type: "integer"
71183                 },
71184                 viewmodes: {
71185                     attributeName: "viewmodes",
71186                     required: false,
71187                     type: "list",
71188                     listValues: ["windowed", "floating", "fullscreen", "maximized", "minimized"]
71189                 },
71190                 defaultlocale: {
71191                     attributeName: "defaultlocale",
71192                     required: false,
71193                     type: "iso-language"
71194                 }
71195             },
71196             children: {
71197                 name: {
71198                     nodeName: "name",
71199                     required: false,
71200                     occurrence: 0,
71201                     type: "string",
71202                     attributes: {
71203                         "xml:lang": {
71204                             attributeName: "xml:lang",
71205                             required: false,
71206                             type: "iso-language",
71207                             unique: true
71208                         },
71209                         dir: {
71210                             attributeName: "dir",
71211                             required: false,
71212                             type: "list",
71213                             listValues: ["ltr", "rtl", "lro", "rlo"]
71214                         },
71215                         "short": {
71216                             attributeName: "short",
71217                             required: false,
71218                             type: "string"
71219                         }
71220                     },
71221                     children: {
71222                         span: {
71223                             nodeName: "span",
71224                             required: false,
71225                             type: "string",
71226                             attributes: {
71227                                 "xml:lang": {
71228                                     attributeName: "xml:lang",
71229                                     required: false,
71230                                     type: "iso-language",
71231                                     unique: true
71232                                 },
71233                                 dir: {
71234                                     attributeName: "dir",
71235                                     required: false,
71236                                     type: "list",
71237                                     listValues: ["ltr", "rtl", "lro", "rlo"]
71238                                 }
71239                             }
71240                         }
71241                     }
71242                 },
71243                 description: {
71244                     nodeName: "description",
71245                     required: false,
71246                     occurrence: 0,
71247                     type: "string",
71248                     attributes: {
71249                         "xml:lang": {
71250                             attributeName: "xml:lang",
71251                             required: false,
71252                             type: "iso-language",
71253                             unique: true
71254                         },
71255                         dir: {
71256                             attributeName: "dir",
71257                             required: false,
71258                             type: "list",
71259                             listValues: ["ltr", "rtl", "lro", "rlo"]
71260                         }
71261                     },
71262                     children: {
71263                         span: {
71264                             nodeName: "span",
71265                             required: false,
71266                             type: "string",
71267                             attributes: {
71268                                 "xml:lang": {
71269                                     attributeName: "xml:lang",
71270                                     required: false,
71271                                     type: "iso-language",
71272                                     unique: true
71273                                 },
71274                                 dir: {
71275                                     attributeName: "dir",
71276                                     required: false,
71277                                     type: "list",
71278                                     listValues: ["ltr", "rtl", "lro", "rlo"]
71279                                 }
71280                             }
71281                         }
71282                     }
71283                 },
71284                 author: {
71285                     nodeName: "author",
71286                     required: false,
71287                     occurrence: 0,
71288                     type: "string",
71289                     attributes: {
71290                         "xml:lang": {
71291                             attributeName: "xml:lang",
71292                             required: false,
71293                             type: "iso-language"
71294                         },
71295                         dir: {
71296                             attributeName: "dir",
71297                             required: false,
71298                             type: "list",
71299                             listValues: ["ltr", "rtl", "lro", "rlo"]
71300                         },
71301                         href: {
71302                             attributeName: "href",
71303                             required: false,
71304                             type: "regex",
71305                             regex: constants.REGEX.URL
71306                         },
71307                         email: {
71308                             attributeName: "email",
71309                             required: false,
71310                             type: "regex",
71311                             regex: constants.REGEX.EMAIL
71312                         }
71313                     },
71314                     children: {
71315                         span: {
71316                             nodeName: "span",
71317                             required: false,
71318                             type: "string",
71319                             attributes: {
71320                                 "xml:lang": {
71321                                     attributeName: "xml:lang",
71322                                     required: false,
71323                                     type: "iso-language",
71324                                     unique: true
71325                                 },
71326                                 dir: {
71327                                     attributeName: "dir",
71328                                     required: false,
71329                                     type: "list",
71330                                     listValues: ["ltr", "rtl", "lro", "rlo"]
71331                                 }
71332                             }
71333                         }
71334                     }
71335                 },
71336                 license: {
71337                     nodeName: "license",
71338                     required: false,
71339                     occurrence: 0,
71340                     type: "string",
71341                     attributes: {
71342                         "xml:lang": {
71343                             attributeName: "xml:lang",
71344                             required: false,
71345                             type: "iso-language"
71346                         },
71347                         dir: {
71348                             attributeName: "dir",
71349                             required: false,
71350                             type: "list",
71351                             listValues: ["ltr", "rtl", "lro", "rlo"]
71352                         },
71353                         href: {
71354                             attributeName: "href",
71355                             type: "regex",
71356                             required: false,
71357                             regex: constants.REGEX.URL
71358                         }
71359                     },
71360                     children: {
71361                         span: {
71362                             nodeName: "span",
71363                             required: false,
71364                             type: "string",
71365                             attributes: {
71366                                 "xml:lang": {
71367                                     attributeName: "xml:lang",
71368                                     required: false,
71369                                     type: "iso-language",
71370                                     unique: true
71371                                 },
71372                                 dir: {
71373                                     attributeName: "dir",
71374                                     required: false,
71375                                     type: "list",
71376                                     listValues: ["ltr", "rtl", "lro", "rlo"]
71377                                 }
71378                             }
71379                         }
71380                     }
71381                 },
71382                 icon: {
71383                     nodeName: "icon",
71384                     required: false,
71385                     occurrence: 0,
71386                     attributes: {
71387                         "xml:lang": {
71388                             attributeName: "xml:lang",
71389                             required: false,
71390                             type: "iso-language"
71391                         },
71392                         dir: {
71393                             attributeName: "dir",
71394                             required: false,
71395                             type: "list",
71396                             listValues: ["ltr", "rtl", "lro", "rlo"]
71397                         },
71398                         src: {
71399                             attributeName: "src",
71400                             required: true,
71401                             type: "string"
71402                         },
71403                         width: {
71404                             attributeName: "width",
71405                             required: false,
71406                             type: "integer"
71407                         },
71408                         height: {
71409                             attributeName: "height",
71410                             required: false,
71411                             type: "integer"
71412                         }
71413                     }
71414                 },
71415                 content: {
71416                     nodeName: "content",
71417                     required: false,
71418                     occurrence: 1,
71419                     attributes: {
71420                         "xml:lang": {
71421                             attributeName: "xml:lang",
71422                             required: false,
71423                             type: "iso-language",
71424                             unique: true
71425                         },
71426                         dir: {
71427                             attributeName: "dir",
71428                             required: false,
71429                             type: "list",
71430                             listValues: ["ltr", "rtl", "lro", "rlo"]
71431                         },
71432                         src: {
71433                             attributeName: "src",
71434                             required: true,
71435                             type: "string"
71436                         },
71437                         encoding: {
71438                             attributeName: "encoding",
71439                             required: false,
71440                             type: "string"
71441                         },
71442                         type: {
71443                             attributeName: "type",
71444                             required: false,
71445                             type: "string"
71446                         }
71447                     }
71448                 },
71449                 setting: {
71450                     nodeName: "tizen:setting",
71451                     required: false,
71452                     occurrence: 0,
71453                     attributes: {
71454                         'screen-orientation': {
71455                             attributeName: "screen-orientation",
71456                             required: false,
71457                             type: "list",
71458                             listValues: ['portrait', 'landscape', 'auto']
71459                         },
71460                         'context-menu': {
71461                             attributeName: "context-menu",
71462                             required: false,
71463                             type: "list",
71464                             listValues: ['enable', 'disable']
71465                         },
71466                         'background-support': {
71467                             attributeName: "background-support",
71468                             required: false,
71469                             type: "list",
71470                             listValues: ['enable', 'disable']
71471                         },
71472                         'encryption': {
71473                             attributeName: "encryption",
71474                             required: false,
71475                             type: "list",
71476                             listValues: ['enable', 'disable']
71477                         },
71478                         'install-location': {
71479                             attributeName: "install-location",
71480                             required: false,
71481                             type: "list",
71482                             listValues: ['auto', 'internal-only', 'perfer-external']
71483                         },
71484                         'hwkey-event': {
71485                             attributeName: "hwkey-event",
71486                             required: false,
71487                             type: "list",
71488                             listValues: ['enable', 'disable']
71489                         }
71490                     }
71491                 },
71492                 application: {
71493                     nodeName: "tizen:application",
71494                     required: true,
71495                     occurrence: 1,
71496                     attributes: {
71497                         id: {
71498                             attributeName: "id",
71499                             required: true,
71500                             type: "string"
71501                         },
71502                         required_version: {
71503                             attributeName: "required_version",
71504                             required: true,
71505                             type: "list",
71506                             listValues: ['1.0', '2.0', '2.1', '2.2']
71507                         },
71508                         package: {
71509                             attributeName: "package",
71510                             required: false,
71511                             type: "string"
71512                         }
71513                     }
71514                 },
71515                 "tizen:content": {
71516                     nodeName: "tizen:content",
71517                     required: false,
71518                     occurrence: 1,
71519                     attributes: {
71520                         src: {
71521                             attributeName: "src",
71522                             required: true,
71523                             type: "string"
71524                         }
71525                     }
71526                 },
71527                 control: {
71528                     nodeName: "tizen:app-control",
71529                     required: false,
71530                     occurrence: 0,
71531                     children: {
71532                         src: {
71533                             nodeName: "tizen:src",
71534                             required: true,
71535                             occurence: 0,
71536                             attributes: {
71537                                 name: {
71538                                     attributeName: "name",
71539                                     required: false,
71540                                     type: "string"
71541                                 }
71542                             }
71543                         },
71544                         operation: {
71545                             nodeName: "tizen:operation",
71546                             required: true,
71547                             occurence: 0,
71548                             attributes: {
71549                                 name: {
71550                                     attributeName: "name",
71551                                     required: false,
71552                                     type: "string"
71553                                 }
71554                             }
71555                         },
71556                         uri: {
71557                             nodeName: "tizen:uri",
71558                             required: false,
71559                             occurence: 0,
71560                             attributes: {
71561                                 name: {
71562                                     attributeName: "name",
71563                                     required: false,
71564                                     type: "string"
71565                                 }
71566                             }
71567                         },
71568                         mime: {
71569                             nodeName: "tizen:mime",
71570                             required: false,
71571                             occurence: 0,
71572                             attributes: {
71573                                 name: {
71574                                     attributeName: "name",
71575                                     required: false,
71576                                     type: "string"
71577                                 }
71578                             }
71579                         }
71580                     }
71581                 },
71582                 "app-widget": {
71583                     nodeName: "tizen:app-widget",
71584                     required: false,
71585                     occurrence: 0,
71586                     attributes: {
71587                         id: {
71588                             attributeName: "id",
71589                             required: true,
71590                             type: "string"
71591                         },
71592                         primary: {
71593                             attributeName: "primary",
71594                             required: true,
71595                             type: "list",
71596                             listValues: ['true', 'false']
71597                         },
71598                         "auto-launch": {
71599                             attributeName: "auto-launch",
71600                             required: false,
71601                             type: "list",
71602                             listValues: ['true', 'false']
71603                         },
71604                         "update-period": {
71605                             attributeName: "update-period",
71606                             required: false,
71607                             type: "integer"
71608                         }
71609                     },
71610                     children: {
71611                         "box-label": {
71612                             nodeName: "tizen:box-label",
71613                             required: true,
71614                             occurence: 1
71615                         },
71616                         "box-icon": {
71617                             nodeName: "tizen:box-icon",
71618                             required: true,
71619                             occurence: 1,
71620                             attributes: {
71621                                 src: {
71622                                     attributeName: "src",
71623                                     required: true,
71624                                     type: "string"
71625                                 }
71626                             }
71627                         },
71628                         "box-content": {
71629                             nodeName: "tizen:box-content",
71630                             required: true,
71631                             occurence: 1,
71632                             attributes: {
71633                                 src: {
71634                                     attributeName: "src",
71635                                     required: true,
71636                                     type: "string"
71637                                 },
71638                                 "mouse-event": {
71639                                     attributeName: "mouse-event",
71640                                     required: false,
71641                                     type: "string"
71642                                 },
71643                                 "touch-event": {
71644                                     attributeName: "touch-event",
71645                                     required: false,
71646                                     type: "string"
71647                                 }
71648                             },
71649                             children: {
71650                                 "box-size": {
71651                                     nodeName: "tizen:box-size",
71652                                     required: false,
71653                                     occurence: 1,
71654                                     attributes: {
71655                                         "preview": {
71656                                             attributeName: "preview",
71657                                             required: false,
71658                                             type: "string"
71659                                         }
71660                                     }
71661                                 },
71662                                 pd: {
71663                                     nodeName: "tizen:pd",
71664                                     required: false,
71665                                     occurence: 1,
71666                                     attributes: {
71667                                         "src": {
71668                                             attributeName: "src",
71669                                             required: true,
71670                                             type: "string"
71671                                         },
71672                                         "width": {
71673                                             attributeName: "width",
71674                                             required: true,
71675                                             type: "integer"
71676                                         },
71677                                         "height": {
71678                                             attributeName: "height",
71679                                             required: true,
71680                                             type: "integer"
71681                                         }
71682                                     }
71683                                 }
71684                             }
71685                         }
71686                     }
71687                 },
71688                 account: {
71689                     nodeName: "tizen:account",
71690                     required: false,
71691                     occurrence: 0,
71692                     attributes: {
71693                         "multiple-account-support": {
71694                             attributeName: "multiple-account-support",
71695                             required: true,
71696                             type: "list",
71697                             listValues: ['true', 'false']
71698                         }
71699                     },
71700                     children: {
71701                         icon: {
71702                             nodeName: "tizen:icon",
71703                             required: false,
71704                             occurence: 1,
71705                             attributes: {
71706                                 section: {
71707                                     attributeName: "section",
71708                                     required: true,
71709                                     type: "string"
71710                                 }
71711                             }
71712                         },
71713                         "display-name": {
71714                             nodeName: "tizen:display-name",
71715                             required: false,
71716                             occurence: 1,
71717                             attributes: {
71718                                 "xml:lang": {
71719                                     attributeName: "xml:lang",
71720                                     required: false,
71721                                     type: "string"
71722                                 }
71723                             }
71724                         },
71725                         capability: {
71726                             nodeName: "capability",
71727                             required: false,
71728                             occurence: 1
71729                         }
71730                     }
71731                 },
71732                 feature: {
71733                     nodeName: "tizen:privilege",
71734                     required: false,
71735                     occurrence: 0,
71736                     attributes: {
71737                         "xml:lang": {
71738                             attributeName: "xml:lang",
71739                             required: false,
71740                             type: "iso-language"
71741                         },
71742                         dir: {
71743                             attributeName: "dir",
71744                             required: false,
71745                             type: "list",
71746                             listValues: ["ltr", "rtl", "lro", "rlo"]
71747                         },
71748                         name: {
71749                             attributeName: "name",
71750                             required: true,
71751                             type: "list",
71752                             listValues: ["http://www.w3.org/TR/battery-status/",
71753                                          "http://www.w3.org/TR/geolocation-API/",
71754                                          "http://www.w3.org/TR/touch-events/",
71755                                          "http://www.w3.org/TR/vibration/",
71756                                          "http://tizen.org/privilege/vehicle",
71757                                          "http://tizen.org/privilege/tizen"]
71758                         },
71759                         required: {
71760                             attributeName: "required",
71761                             type: "boolean",
71762                             required: false
71763                         }
71764                     },
71765                     children: {
71766                         param: {
71767                             nodeName: "param",
71768                             required: false,
71769                             occurrence: 0,
71770                             attributes: {
71771                                 "xml:lang": {
71772                                     attributeName: "xml:lang",
71773                                     required: false,
71774                                     type: "iso-language"
71775                                 },
71776                                 dir: {
71777                                     attributeName: "dir",
71778                                     required: false,
71779                                     type: "list",
71780                                     listValues: ["ltr", "rtl", "lro", "rlo"]
71781                                 },
71782                                 name: {
71783                                     attributeName: "name",
71784                                     required: true,
71785                                     type: "string"
71786                                 },
71787                                 value: {
71788                                     attributeName: "value",
71789                                     required: true,
71790                                     type: "string"
71791                                 }
71792                             }
71793                         }
71794                     }
71795                 },
71796                 preference: {
71797                     nodeName: "preference",
71798                     required: false,
71799                     occurrence: 0,
71800                     attributes: {
71801                         "xml:lang": {
71802                             attributeName: "xml:lang",
71803                             required: false,
71804                             type: "iso-language"
71805                         },
71806                         dir: {
71807                             attributeName: "dir",
71808                             required: false,
71809                             type: "list",
71810                             listValues: ["ltr", "rtl", "lro", "rlo"]
71811                         },
71812                         name: {
71813                             attributeName: "name",
71814                             required: true,
71815                             type: "string"
71816                         },
71817                         value: {
71818                             type: "string",
71819                             required: false,
71820                             attributeName: "value"
71821                         },
71822                         readonly: {
71823                             attributeName: "readonly",
71824                             type: "boolean",
71825                             required: false
71826                         }
71827                     }
71828                 }
71829             }
71830         }
71831     }
71832 };
71833
71834 });
71835 define('ripple/platform/ivi/3.0/spec/dbvehicle', function (require, exports, module) {
71836 module.exports = {
71837     "supported": ["VehicleSpeed", "EngineSpeed", "VehiclePowerMode", "TripMeter",
71838         "Acceleration", "Transmission", "CruiseControlStatus", "WheelBrake",
71839         "LightStatus", "InteriorLightStatus", "Horn", "Fuel", "EngineOil",
71840         "Location", "ExteriorBrightness", "Temperature", "RainSensor",
71841         "WindshieldWiper", "HVAC", "WindowStatus", "Sunroof", "ConvertibleRoof",
71842         "VehicleId", "Size", "FuelInfo", "VehicleType", "Doors",
71843         "TransmissionGearType", "WheelInformation", "Odometer", "Fluid", "Battery",
71844         "TirePressure", "TireTemperature", "SecurityAlert", "ParkingBrake",
71845         "ParkingLight", "HazardLight", "AntilockBrakingSystem", "TractionControlSystem",
71846         "VehicleTopSpeedLimit", "AirbagStatus", "DoorStatus", "SeatBeltStatus",
71847         "OccupantStatus", "ObstacleDistance", "NightMode", "DrivingMode"],
71848     "newestHistory": null,
71849     "currentConfiguration": 0,
71850     "configurationData": [
71851         [
71852             "AFA", //VehicleId => WMI
71853             "21D1M2883N342FFG7", //VehicleId => VIN
71854             2096, //Size => width
71855             1860, //Size => height
71856             4779, //Size => length
71857             0, //FuelInfo => type
71858             0, //FuelInfo => refuelPosition
71859             0, //VehicleType => type
71860             [2, 2], //Doors => doorsPerRow
71861             0, //TransmissionGearType => transmissionGearType
71862             1953, //WheelInformation => frontWheelRadius
71863             2000, //WheelInformation => rearWheelRadius
71864             1465, //WheelInformation => wheelTrack
71865             true //WheelInformation => ABS
71866         ],
71867         [
71868             "KMH", "21D1M2888N342FFL7", /**/2125, 1961, 4901, /**/4, 3, /**/4, /**/[2, 2], /**/2,
71869         /**/1964, 2000, 1470, true
71870         ]
71871     ],
71872     "settingData": [
71873         0, //Transmission-gearPosition
71874         0, //Transmission-mode
71875         true, //CruiseControlStatus-activated
71876         0, //CruiseControlStatus-speed
71877         true, //WheelBrake-engaged
71878         true, //LightStatus-head
71879         false, //LightStatus-rightTurn
71880         false, //LightStatus-leftTurn
71881         false, //LightStatus-brake
71882         false, //LightStatus-fog
71883         false, //LightStatus-hazard
71884         false, //LightStatus-parking
71885         false, //LightStatus-highBeam
71886         false, //InteriorLightStatus-passenger
71887         false, //InteriorLightStatus-driver
71888         false, //InteriorLightStatus-center
71889         false, //Horn-horn
71890         0, //WindshieldWiper-windshieldWiper
71891         0x04, //HVAC-airflowDirection
71892         0, //HVAC-airflowDirection
71893         0, //HVAC-targetTemperature
71894         false, //HVAC-airConditioning
71895         false, //HVAC-airRecirculation
71896         false, //HVAC-heater
71897         false, //HVAC-steeringWheelHeater
71898         false, //HVAC-seatHeater
71899         false, //HVAC-seatCooler
71900         0, //Sunroof-openness
71901         0, //Sunroof-tilt
71902         0, //ConvertibleRoof-openness
71903         true, //SecurityAlert-securityAlert
71904         true, //ParkingBrake-parkingBrake
71905         true, //ParkingLight-parkingLight
71906         true, //HazardLight-hazardLight
71907         true, //AntilockBrakingSystem-antilockBrakingSystem
71908         true, //TractionControlSystem-TractionControlSystem
71909         120, //VehicleTopSpeedLimit-VehicleTopSpeedLimit
71910         0, //WindowStatus-openness
71911         true, //WindowStatus-defrost
71912         2, //AirbagStatus-airbagStatus
71913         0, //DoorStatus-doorStatus
71914         true, //DoorStatus-doorLockStatus
71915         true, //DoorStatus-childLockStatus
71916         false, //SeatBeltStatus-seatBeltStatus
71917         0, //OccupantStatus-occupantStatus
71918         10, //ObstacleDistance-obstacleDistance
71919         false, //NightMode-nightMode
71920         0, //DrivingMode-drivingMode
71921         0, //Fluid-transmission
71922         0, //Fluid-brake
71923         0, //Fluid-washer
71924         220, //Battery-voltage
71925         0.5, //Battery-current
71926         0, //TirePressure-leftFront
71927         0, //TirePressure-rightFront
71928         0, //TirePressure-leftRear
71929         0, //TirePressure-rightRear
71930         0, //TireTemperature-leftFront
71931         0, //TireTemperature-rightFront
71932         0, //TireTemperature-leftRear
71933         0 //TireTemperature-rightRear
71934     ],
71935     "autoRunningData": [
71936         [
71937             0, //VehicleSpeed => vehicleSpeed
71938             0, //EngineSpeed => engineSpeed
71939             1, //VehiclePowerMode => vehiclePowerMode
71940             [23, 7876, 124, 4577], //TripMeter => tripMeters
71941             0, //Acceleration => x
71942             0, //Acceleration => y
71943             0, //Acceleration => z
71944             87, //Fuel => level
71945             251, //Fuel => range
71946             250, //Fuel => instantConsumption
71947             85, //Fuel => instantEconomy
71948             15, //Fuel => averageEconomy
71949             0, //EngineOil => remaining
71950             0, //EngineOil => temperature
71951             0, //EngineOil => pressure
71952             0, //Location => latitude
71953             0, //Location => longitude
71954             0, //Location => altitude
71955             0, //Location => direction
71956             0, //ExteriorBrightness => exteriorBrightness
71957             0, //Temperature => interior
71958             0, //Temperature => exterior
71959             2, //RainSensor => rainSensor
71960             15000 //Odometer => odometer
71961         ],
71962         [
71963             60, /**/2500, /**/0, /**/[23, 7876, 124, 4577, 10], /**/10, 10, 10, /**/80, 251, 59, 87, 15,
71964         /**/150, 10, 59, /**/-15, -89, 16, 69, /**/456, /**/45, 45, /**/10, /**/1213
71965         ],
71966         [
71967             120, /**/2800, /**/1, /**/[23, 7876, 124, 4577, 25], /**/120, 120, 120, /**/65, 251, 59, 87, 15,
71968         /**/78, 20, 54, /**/-97, -54, 124, 65, /**/45, /**/67, 45, /**/9, /**/250
71969         ],
71970         [
71971             180, /**/3200, /**/1, /**/[23, 7876, 124, 4577, 25], /**/120, 120, 120, /**/65, 251, 59, 87, 15,
71972         /**/78, 40, 54, /**/-97, -54, 124, 65, /**/45, /**/67, 45, /**/9, /**/250
71973         ],
71974         [
71975             200, /**/3500, /**/1, /**/[23, 7876, 124, 4577, 25], /**/120, 120, 120, /**/65, 251, 59, 87, 15,
71976         /**/78, 60, 54, /**/-97, -54, 124, 65, /**/45, /**/67, 45, /**/9, /**/250
71977         ],
71978         [
71979             300, /**/3900, /**/1, /**/[23, 7876, 124, 4577, 25], /**/120, 120, 120, /**/65, 251, 59, 87, 15,
71980         /**/78, 80, 54, /**/-97, -54, 124, 65, /**/45, /**/67, 45, /**/9, /**/250
71981         ],
71982         [
71983             240, /**/3600, /**/1, /**/[23, 7876, 124, 4577, 25], /**/120, 120, 120, /**/65, 251, 59, 87, 15,
71984         /**/78, 70, 54, /**/-97, -54, 124, 65, /**/45, /**/67, 45, /**/9, /**/250
71985         ],
71986         [
71987             100, /**/2600, /**/1, /**/[23, 7876, 124, 4577, 25], /**/120, 120, 120, /**/65, 251, 59, 87, 15,
71988         /**/78, 30, 54, /**/-97, -54, 124, 65, /**/45, /**/67, 45, /**/9, /**/250
71989         ]
71990     ]
71991 };
71992
71993 });
71994 define('ripple/platform/ivi/3.0/spec/device', function (require, exports, module) {
71995 /*
71996  *  Copyright 2011 Intel Corporation.
71997  *
71998  * Licensed under the Apache License, Version 2.0 (the "License");
71999  * you may not use this file except in compliance with the License.
72000  * You may obtain a copy of the License at
72001  *
72002  * http://www.apache.org/licenses/LICENSE-2.0
72003  *
72004  * Unless required by applicable law or agreed to in writing, software
72005  * distributed under the License is distributed on an "AS IS" BASIS,
72006  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72007  * See the License for the specific language governing permissions and
72008  * limitations under the License.
72009  */
72010 var event = require('ripple/event'),
72011     utils = require('ripple/utils'),
72012     StorageTypeTable = {
72013         "UNKNOWN": "UNKNOWN",
72014         "INTERNAL": "INTERNAL",
72015         "MMC": "MMC",
72016         "USB_HOST": "USB_HOST"
72017     },
72018     NetworkTypeTable = {
72019         "NONE": "NONE",
72020         "2G": "2G",
72021         "2.5G": "2.5G",
72022         "3G": "3G",
72023         "4G": "4G",
72024         "WIFI": "WIFI",
72025         "ETHERNET": "ETHERNET",
72026         "UNKNOWN": "UNKNOWN"
72027     },
72028     LocaleTable = {
72029         "eng_USA": "eng_USA",
72030         "eng_CAN": "eng_CAN",
72031         "deu_DEU": "deu_DEU",
72032         "jpn_JPN": "jpn_JPN",
72033         "zho_CHN": "zho_CHN",
72034         "UNKNOWN": "UNKNOWN"
72035     },
72036     SimStateTable = {
72037         "ABSENT": "ABSENT",
72038         "INITIALIZING": "INITIALIZING",
72039         "READY": "READY",
72040         "PIN_REQUIRED": "PIN_REQUIRED",
72041         "PUK_REQUIRED":"PUK_REQUIRED",
72042         "NETWORK_LOCKED": "NETWORK_LOCKED",
72043         "SIM_LOCKED": "SIM_LOCKED",
72044         "UNKNOWN": "UNKNOWN"
72045     };
72046
72047 function deviceStatusEventTrigger(setting) {
72048     event.trigger("DeviceStatusChanged", [setting]);
72049 }
72050
72051 module.exports = {
72052     "Config": {
72053         "vibratingMode": {
72054             "name": "Vibrator",
72055             "control": {
72056                 "type": "checkbox",
72057                 "value": true
72058             },
72059             "callback": function (setting) {
72060                 event.trigger("VibratingModeChanged", [setting]);
72061             }
72062         },
72063         "lockScreen": {
72064             "name": "Lock Screen",
72065             "control": {
72066                 "type": "checkbox",
72067                 "value": false
72068             },
72069             "callback": function (setting) {
72070                 event.trigger("LockScreenChanged", [setting]);
72071             }
72072         }
72073     },
72074     "DEVICE_ORIENTATION": {
72075         "status": {
72076             "name": "Status",
72077             "control": {
72078                 "type": "label",
72079                 "innertext": "PORTRAIT_PRIMARY",
72080                 "value": "PORTRAIT_PRIMARY"
72081             },
72082             "event": "LayoutChanged"
72083         },
72084         "isAutoRotation": {
72085             "name": "Is Auto Rotation",
72086             "control": {
72087                 "type": "label",
72088                 "value": false
72089             }
72090         }
72091     },
72092     "CPU": {
72093         "load": {
72094             "name": "Load",
72095             "control": {
72096                 "type": "number",
72097                 "value": 0.1
72098             },
72099             "event": "CpuLoadChanged",
72100             "callback": function (setting) {
72101                 if (setting > 1) setting = 1;
72102                 if (setting < 0) setting = 0;
72103                 event.trigger("CpuLoadChanged", [setting]);
72104             }
72105         }
72106     },
72107     "STORAGE": {
72108         "type": {
72109             "name": "Type",
72110             "control": {
72111                 "type": "select",
72112                 "value": StorageTypeTable["INTERNAL"]
72113             },
72114             "options": (function () {
72115                 var optionList = {};
72116                 utils.forEach(StorageTypeTable, function (key, value) {
72117                     optionList[key] = StorageTypeTable[value];
72118                 });
72119
72120                 return optionList;
72121             }())
72122         },
72123         "capacity": {
72124             "name": "Capacity(bytes)",
72125             "control": {
72126                 "type": "label",
72127                 "value": 16000000000
72128             }
72129         },
72130         "availableCapacity": {
72131             "name": "AvailableCapacity(bytes)",
72132             "control": {
72133                 "type": "number",
72134                 "value": 12000000000
72135             },
72136             "callback": function (setting) {
72137                 event.trigger("AvailCapacityChanged", [setting]);
72138             }
72139         },
72140         "isRemovable": {
72141             "name": "IsRemovable",
72142             "control": {
72143                 "type": "checkbox",
72144                 "value": true
72145             }
72146         }
72147     },
72148     "BUILD": {
72149         "model": {
72150             "name": "Model",
72151             "control": {
72152                 "type": "label",
72153                 "innertext": "tizen-2.2 build",
72154                 "value": "tizen-2.2 build"
72155             }
72156         },
72157         "manufacturer": {
72158             "name": "Manufacturer",
72159             "control": {
72160                 "type": "label",
72161                 "innertext": "Tizen",
72162                 "value": "Tizen"
72163             }
72164         },
72165         "buildVersion": {
72166             "name": "Build Version",
72167             "control": {
72168                 "type": "label",
72169                 "innertext": "TIZEN_WEB_SIMULATOR_000001",
72170                 "value": "TIZEN_WEB_SIMULATOR_000001"
72171             }
72172         }
72173     },
72174     "LOCALE": {
72175         "language": {
72176             "name": "Language",
72177             "control": {
72178                 "type": "select",
72179                 "value": LocaleTable["eng_USA"]
72180             },
72181             "options": (function () {
72182                 var optionList = {};
72183                 utils.forEach(LocaleTable, function (key, value) {
72184                     optionList[key] = LocaleTable[value];
72185                 });
72186
72187                 return optionList;
72188             }())
72189         },
72190         "country": {
72191             "name": "Country",
72192             "control": {
72193                 "type": "select",
72194                 "value": LocaleTable["eng_USA"]
72195             },
72196             "options": (function () {
72197                 var optionList = {};
72198                 utils.forEach(LocaleTable, function (key, value) {
72199                     optionList[key] = LocaleTable[value];
72200                 });
72201
72202                 return optionList;
72203             }())
72204         }
72205     },
72206     "DISPLAY": {
72207         "resolutionWidth": {
72208             "name": "Resolution Width(pixels)",
72209             "control": {
72210                 "type": "label",
72211                 "value": 0
72212             }
72213         },
72214         "resolutionHeight": {
72215             "name": "Resolution Height(pixels)",
72216             "control": {
72217                 "type": "label",
72218                 "value": 0
72219             }
72220         },
72221         "dotsPerInchWidth": {
72222             "name": "DPI-X",
72223             "control": {
72224                 "type": "label",
72225                 "value": 0
72226             }
72227         },
72228         "dotsPerInchHeight": {
72229             "name": "DPI-Y",
72230             "control": {
72231                 "type": "label",
72232                 "value": 0
72233             }
72234         },
72235         "physicalWidth": {
72236             "name": "Physical Width(millimeters)",
72237             "control": {
72238                 "type": "label",
72239                 "value": 0
72240             }
72241         },
72242         "physicalHeight": {
72243             "name": "Physical Height(millimeters)",
72244             "control": {
72245                 "type": "label",
72246                 "value": 0
72247             }
72248         },
72249         "brightness": {
72250             "name": "Brightness",
72251             "control": {
72252                 "type": "number",
72253                 "value": 1
72254             },
72255             "event": "DisplayBrightnessChanged",
72256             "callback": function (setting) {
72257                 if (setting > 1) setting = 1;
72258                 if (setting < 0) setting = 0;
72259                 event.trigger("DisplayBrightnessChanged", [setting]);
72260             }
72261         }
72262     },
72263     "NETWORK": {
72264         "networkType": {
72265             "name": "Network Type",
72266             "control" : {
72267                 "type": "select",
72268                 "value": NetworkTypeTable["NONE"]
72269             },
72270             "options": (function () {
72271                 var optionList = {};
72272                 utils.forEach(NetworkTypeTable, function (key, value) {
72273                     optionList[key] = NetworkTypeTable[value];
72274                 });
72275
72276                 return optionList;
72277             }())
72278         }
72279     },
72280     "WIFI_NETWORK": {
72281         "status": {
72282             "name": "Status",
72283             "control": {
72284                 "type": "checkbox",
72285                 "value": false
72286             },
72287             "event": "WiFiNetworkStatusChanged",
72288             "callback": function (setting) {
72289                 event.trigger("WiFiNetworkStatusChanged", [setting]);
72290             }
72291         },
72292         "ssid": {
72293             "name": "SSID",
72294             "control": {
72295                 "type": "text",
72296                 "value": "Tizen WiFi"
72297             }
72298         },
72299         "ipAddress": {
72300             "name": "IP Address",
72301             "control": {
72302                 "type": "text",
72303                 "value": "192.168.0.1"
72304             }
72305         },
72306         "ipv6Address": {
72307             "name": "IPv6 Address",
72308             "control": {
72309                 "type": "text",
72310                 "value": "2001:db8:85a3:0:0:0:70:7334"
72311             }
72312         },
72313         "signalStrength": {
72314             "name": "Signal Strength",
72315             "control": {
72316                 "type": "select",
72317                 "value": 0
72318             },
72319             "options": (function () {
72320                 var i,
72321                     optionList = {};
72322
72323                 for (i = 0; i <= 10; i++) {
72324                     optionList[i] = i;
72325                 }
72326
72327                 return optionList;
72328             }())
72329         }
72330     },
72331     "CELLULAR_NETWORK": {
72332         "status": {
72333             "name": "Status",
72334             "control": {
72335                 "type": "checkbox",
72336                 "value": true
72337             },
72338             "event": "CellularNetworkStatusChanged",
72339             "callback": function (setting) {
72340                 event.trigger("CellularNetworkStatusChanged", [setting]);
72341             }
72342         },
72343         "apn": {
72344             "name": "APN",
72345             "control": {
72346                 "type": "text",
72347                 "value": "Tizen"
72348             }
72349         },
72350         "ipAddress": {
72351             "name": "IP Address",
72352             "control": {
72353                 "type": "text",
72354                 "value": "10.0.2.16"
72355             }
72356         },
72357         "ipv6Address": {
72358             "name": "IPv6 Address",
72359             "control": {
72360                 "type": "text",
72361                 "value": "2001:db8:85a3:0:0:0:70:7334"
72362             }
72363         },
72364         "mcc": {
72365             "name": "MCC",
72366             "control": {
72367                 "type": "number",
72368                 "value": 460
72369             }
72370         },
72371         "mnc": {
72372             "name": "MNC",
72373             "control": {
72374                 "type": "number",
72375                 "value": 0
72376             }
72377         },
72378         "cellId": {
72379             "name": "Cell ID",
72380             "control": {
72381                 "type": "number",
72382                 "value": 0
72383             }
72384         },
72385         "lac": {
72386             "name": "LAC",
72387             "control": {
72388                 "type": "number",
72389                 "value": 0
72390             }
72391         },
72392         "isRoaming": {
72393             "name": "Roaming",
72394             "control": {
72395                 "type": "checkbox",
72396                 "value": true
72397             }
72398         },
72399         "isFlightMode": {
72400             "name": "Flight Mode",
72401             "control": {
72402                 "type": "checkbox",
72403                 "value": false
72404             },
72405             "callback": function (setting) {
72406                 event.trigger("FlightModeChanged", [setting]);
72407             }
72408         },
72409         "imei": {
72410             "name": "IMEI",
72411             "control": {
72412                 "type": "text",
72413                 "value": "012417005203000"
72414             }
72415         }
72416     },
72417     "SIM": {
72418         "state": {
72419             "name": "State",
72420             "control": {
72421                 "type": "select",
72422                 "value": SimStateTable["READY"]
72423             },
72424             "options": (function () {
72425                 var optionList = {};
72426                 utils.forEach(SimStateTable, function (key, value) {
72427                     optionList[key] = SimStateTable[value];
72428                 });
72429
72430                 return optionList;
72431             }())
72432         },
72433         "operatorName": {
72434             "name": "Operator Name",
72435             "control": {
72436                 "type": "text",
72437                 "value": "Tizen"
72438             }
72439         },
72440         "msisdn": {
72441             "name": "MSISDN",
72442             "control": {
72443                 "type": "text",
72444                 "value": "088123456789"
72445             }
72446         },
72447         "iccid": {
72448             "name": "ICCID",
72449             "control": {
72450                 "type": "text",
72451                 "value": "123000MFSSYYGXXXXXXP"
72452             }
72453         },
72454         "mcc": {
72455             "name": "MCC",
72456             "control": {
72457                 "type": "number",
72458                 "value": 460
72459             }
72460         },
72461         "mnc": {
72462             "name": "MNC",
72463             "control": {
72464                 "type": "number",
72465                 "value": 0
72466             }
72467         },
72468         "msin": {
72469             "name": "MSIN",
72470             "control": {
72471                 "type": "text",
72472                 "value": "H1 H2 H3 S 12345"
72473             }
72474         },
72475         "spn": {
72476             "name": "SPN",
72477             "control": {
72478                 "type": "text",
72479                 "value": "TizenSPN"
72480             }
72481         }
72482     },
72483     "PERIPHERAL": {
72484         "isVideoOutputOn": {
72485             "name": "Video Output",
72486             "control": {
72487                 "type": "checkbox",
72488                 "value": false
72489             }
72490         }
72491     }
72492 };
72493
72494 });
72495 define('ripple/platform/ivi/3.0/spec/sensor', function (require, exports, module) {
72496 /*
72497  *  Copyright 2012 Intel Corporation.
72498  *
72499  * Licensed under the Apache License, Version 2.0 (the "License");
72500  * you may not use this file except in compliance with the License.
72501  * You may obtain a copy of the License at
72502  *
72503  * http://www.apache.org/licenses/LICENSE-2.0
72504  *
72505  * Unless required by applicable law or agreed to in writing, software
72506  * distributed under the License is distributed on an "AS IS" BASIS,
72507  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72508  * See the License for the specific language governing permissions and
72509  * limitations under the License.
72510  */
72511 var event = require('ripple/event');
72512
72513 function sensorStatusEventTrigger(setting) {
72514     event.trigger("SensorStatusChanged", [setting]);
72515 }
72516
72517 module.exports = {
72518     "Accelerometer": {
72519         "resolution": 0.039239998906850815,
72520         "minDelay": 20,
72521         "range": 20.051639556884766,
72522         "name": "Accelerometer",
72523         "type": "Accelerometer"
72524     },
72525     "MagneticField": {
72526         "x": {
72527             "name": "X",
72528             "control": {
72529                 "type": "range",
72530                 "value": 100.0000000000000000,
72531                 "min": 0.0000000000000000,
72532                 "max": 200.0000000000000000,
72533                 "step": 0.0000000000000001
72534             },
72535             "callback": function (setting) {
72536                 event.trigger("MagneticField-xChanged", [setting]);
72537             }
72538         },
72539
72540         "y": {
72541             "name": "Y",
72542             "control": {
72543                 "type": "range",
72544                 "value": 100.0000000000000000,
72545                 "min": 0.0000000000000000,
72546                 "max": 200.0000000000000000,
72547                 "step": 0.0000000000000001
72548             },
72549             "callback": function (setting) {
72550                 event.trigger("MagneticField-yChanged", [setting]);
72551             }
72552         },
72553
72554         "z": {
72555             "name": "Z",
72556             "control": {
72557                 "type": "range",
72558                 "value": 100.0000000000000000,
72559                 "min": 0.0000000000000000,
72560                 "max": 200.0000000000000000,
72561                 "step": 0.0000000000000001
72562             },
72563             "callback": function (setting) {
72564                 event.trigger("MagneticField-zChanged", [setting]);
72565             }
72566         },
72567
72568         "resolution": 1,
72569         "minDelay": 20,
72570         "range": 359,
72571         "name": "MagneticField",
72572         "type": "MagneticField"
72573     },
72574     "Rotation": {
72575         "resolution": 1,
72576         "minDelay": 20,
72577         "range": 359,
72578         "name": "Rotation",
72579         "type": "Rotation"
72580     },
72581     "Orientation": {
72582         "resolution": 1,
72583         "minDelay": 20,
72584         "range": 359,
72585         "name": "Orientation",
72586         "type": "Orientation"
72587     }
72588 };
72589
72590 });
72591 define('ripple/platform/ivi/3.0/spec/ui', function (require, exports, module) {
72592 /*
72593  *  Copyright 2011 Intel Corporation.
72594  *
72595  * Licensed under the Apache License, Version 2.0 (the "License");
72596  * you may not use this file except in compliance with the License.
72597  * You may obtain a copy of the License at
72598  *
72599  * http://www.apache.org/licenses/LICENSE-2.0
72600  *
72601  * Unless required by applicable law or agreed to in writing, software
72602  * distributed under the License is distributed on an "AS IS" BASIS,
72603  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72604  * See the License for the specific language governing permissions and
72605  * limitations under the License.
72606  */
72607 module.exports = {
72608     plugins: [
72609         "vehicle"
72610     ]
72611 };
72612
72613 });
72614 define('ripple/platform/ivi/3.0/spec/vehicledb', function (require, exports, module) {
72615 /*
72616  *  Copyright 2013 Intel Corporation.
72617  *
72618  * Licensed under the Apache License, Version 2.0 (the "License");
72619  * you may not use this file except in compliance with the License.
72620  * You may obtain a copy of the License at
72621  *
72622  * http://www.apache.org/licenses/LICENSE-2.0
72623  *
72624  * Unless required by applicable law or agreed to in writing, software
72625  * distributed under the License is distributed on an "AS IS" BASIS,
72626  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72627  * See the License for the specific language governing permissions and
72628  * limitations under the License.
72629  */
72630
72631 module.exports = {
72632     supported: ["VehicleSpeed", "EngineSpeed", "VehiclePowerMode", "TripMeter",
72633         "Acceleration", "Transmission", "CruiseControlStatus", "WheelBrake",
72634         "LightStatus", "InteriorLightStatus", "Horn", "Fuel", "EngineOil",
72635         "Location", "ExteriorBrightness", "Temperature", "RainSensor",
72636         "WindshieldWiper", "HVAC", "WindowStatus", "Sunroof", "ConvertibleRoof",
72637         "VehicleId", "Size", "FuelInfo", "VehicleType", "Doors",
72638         "TransmissionGearType", "WheelInformation", "Odometer", "Fluid", "Battery",
72639         "TirePressure", "TireTemperature", "SecurityAlert", "ParkingBrake",
72640         "ParkingLight", "HazardLight", "AntilockBrakingSystem", "TractionControlSystem",
72641         "VehicleTopSpeedLimit", "AirbagStatus", "DoorStatus", "SeatBeltStatus",
72642         "OccupantStatus", "ObstacleDistance"],
72643     config: {
72644         "current": "Car1",
72645         "Car1": {
72646             "VehicleId": {
72647                 "WMI": "AFA",
72648                 "VIN": "21D1M2883N342FFG7"
72649             },
72650             "Size": {
72651                 "width": 2096,
72652                 "height": 1860,
72653                 "length": 4779
72654             },
72655             "FuelInfo": {
72656                 "type": 0,
72657                 "refuelPosition": 0
72658             },
72659             "VehicleType": {
72660                 "type": 0
72661             },
72662             "Doors": {
72663                 "doorsPerRow": [2,2]
72664             },
72665             "TransmissionGearType": {
72666                 "transmissionGearType": 0
72667             },
72668             "WheelInformation": {
72669                 "frontWheelRadius": 1953,
72670                 "rearWheelRadius": 2000,
72671                 "wheelTrack": 1465,
72672                 "ABS": true
72673             }
72674         },
72675         "Car2": {
72676             "VehicleId": {
72677                 "WMI": "KMH",
72678                 "VIN": "21D1M2888N342FFL7"
72679             },
72680             "Size": {
72681                 "width": 2125,
72682                 "height": 1961,
72683                 "length": 4901
72684             },
72685             "FuelInfo": {
72686                 "type": 4,
72687                 "refuelPosition": 3
72688             },
72689             "VehicleType": {
72690                 "type": 4
72691             },
72692             "Doors": {
72693                 "doorsPerRow": [2,2]
72694             },
72695             "TransmissionGearType": {
72696                 "transmissionGearType": 2
72697             },
72698             "WheelInformation": {
72699                 "frontWheelRadius": 1964,
72700                 "rearWheelRadius": 2000,
72701                 "wheelTrack": 1470,
72702                 "ABS": true
72703             }
72704         }
72705     },
72706     stopSet: {
72707         "Fluid": {
72708             "transmission": {
72709                 "type": "text",
72710                 "title": "unsigned short (0-100 percentage)",
72711                 "default": 100
72712             },
72713             "brake": {
72714                 "type": "text",
72715                 "title": "unsigned short (0-100 percentage)",
72716                 "default": 100
72717             },
72718             "washer": {
72719                 "type": "text",
72720                 "title": "unsigned short (0-100 percentage)",
72721                 "default": 100
72722             }
72723         },
72724         "Battery": {
72725             "voltage": {
72726                 "type": "text",
72727                 "title": "double",
72728                 "default": 11.5
72729             },
72730             "current": {
72731                 "type": "text",
72732                 "title": "double",
72733                 "default": 10.4
72734             }
72735         },
72736         "TirePressure": {
72737             "leftFront": {
72738                 "type": "text",
72739                 "title": "double (kpa)",
72740                 "default": 100.5
72741             },
72742             "rightFront": {
72743                 "type": "text",
72744                 "title": "double (kpa)",
72745                 "default": 120.3
72746             },
72747             "leftRear": {
72748                 "type": "text",
72749                 "title": "double (kpa)",
72750                 "default": 200.6
72751             },
72752             "rightRear": {
72753                 "type": "text",
72754                 "title": "double (kpa)",
72755                 "default": 600.5
72756             }
72757         },
72758         "TireTemperature": {
72759             "leftFront": {
72760                 "type": "text",
72761                 "title": "double (celcius)",
72762                 "default": 88.5
72763             },
72764             "rightFront": {
72765                 "type": "text",
72766                 "title": "double (celcius)",
72767                 "default": 52.1
72768             },
72769             "leftRear": {
72770                 "type": "text",
72771                 "title": "double (celcius)",
72772                 "default": 70.6
72773             },
72774             "rightRear": {
72775                 "type": "text",
72776                 "title": "double (celcius)",
72777                 "default": 96.5
72778             }
72779         }
72780     },
72781     enabledSet: {
72782         "Transmission": {
72783             "gearPosition": {
72784                 "type": "select",
72785                 "options": [{"NEUTRAL":0},{"FIRST":1},{"SECOND":2},{"THIRD":3},
72786                     {"FORTH":4},{"FIFTH":5},{"SIXTH":6},{"SEVENTH":7},
72787                     {"EIGHTH":8},{"NINTH":9},{"TENTH":10},{"CVT":64},
72788                     {"REVERSE":128},{"PARK":255}],
72789                 "default": 255
72790             },
72791             "mode": {
72792                 "type": "select",
72793                 "options": [{"NORMAL":0},{"SPORT":1},{"ECONOMY":2},
72794                     {"OEMCUSTOM1":3},{"OEMCUSTOM2":4}],
72795                 "default": 0
72796             }
72797         },
72798         "CruiseControlStatus": {
72799             "activated": {
72800                 "type": "radio",
72801                 "options": ["active","inactive"],
72802                 "default": true
72803             },
72804             "speed": {
72805                 "type": "text",
72806                 "title": "unsigned short (kph)",
72807                 "default": 100
72808             }
72809         },
72810         "WheelBrake": {
72811             "engaged": {
72812                 "type": "radio",
72813                 "options": ["engaged","disengaged"],
72814                 "default": true
72815             }
72816         },
72817         "LightStatus": {
72818             "head": {
72819                 "type": "radio",
72820                 "options": ["on","off"],
72821                 "default": false
72822             },
72823             "rightTurn": {
72824                 "type": "radio",
72825                 "options": ["on","off"],
72826                 "default": false
72827             },
72828             "leftTurn": {
72829                 "type": "radio",
72830                 "options": ["on","off"],
72831                 "default": false
72832             },
72833             "brake": {
72834                 "type": "radio",
72835                 "options": ["on","off"],
72836                 "default": false
72837             },
72838             "fog": {
72839                 "type": "radio",
72840                 "options": ["on","off"],
72841                 "default": false
72842             },
72843             "hazard": {
72844                 "type": "radio",
72845                 "options": ["on","off"],
72846                 "default": false
72847             },
72848             "parking": {
72849                 "type": "radio",
72850                 "options": ["on","off"],
72851                 "default": false
72852             },
72853             "highBeam": {
72854                 "type": "radio",
72855                 "options": ["on","off"],
72856                 "default": false
72857             }
72858         },
72859         "InteriorLightStatus": {
72860             "passenger": {
72861                 "type": "radio",
72862                 "options": ["on","off"],
72863                 "default": false
72864             },
72865             "driver": {
72866                 "type": "radio",
72867                 "options": ["on","off"],
72868                 "default": false
72869             },
72870             "center": {
72871                 "type": "radio",
72872                 "options": ["on","off"],
72873                 "default": false
72874             }
72875         },
72876         "Horn": {
72877             "horn": {
72878                 "type": "radio",
72879                 "options": ["on","off"],
72880                 "default": false
72881             }
72882         },
72883         "WindshieldWiper": {
72884             "windshieldWiper": {
72885                 "type": "select",
72886                 "options": [{"OFF":0},{"SLOWEST":1},{"FASTEST":5},{"AUTO":10}],
72887                 "default": 0
72888             }
72889         },
72890         "HVAC": {
72891             "airflowDirection": {
72892                 "type": "select",
72893                 "options": [{"FRONTPANEL":0},{"FLOORDUCT":1},{"FRONT":0x02},
72894                     {"DEFROSTER":0x04}],
72895                 "default": 0
72896             },
72897             "fanSpeed": {
72898                 "type": "select",
72899                 "options": [{"0":0},{"1":1},{"2":2},{"3":3},{"4":4},{"5":5},
72900                     {"6":6},{"7":7}],
72901                 "default": 1
72902             },
72903             "targetTemperature": {
72904                 "type": "text",
72905                 "title": "unsigned short (celcius)",
72906                 "default": 21
72907             },
72908             "airConditioning": {
72909                 "type": "radio",
72910                 "options": ["on","off"],
72911                 "default": false
72912             },
72913             "airRecirculation": {
72914                 "type": "radio",
72915                 "options": ["on","off"],
72916                 "default": false
72917             },
72918             "heater": {
72919                 "type": "radio",
72920                 "options": ["on","off"],
72921                 "default": false
72922             },
72923             "defrost-window":  {
72924                 "type": "text",
72925                 "title": "unsigned short",
72926                 "default": 1
72927             },
72928             "defrost-defrost": {
72929                 "type": "radio",
72930                 "options": ["yes","no"],
72931                 "default": true
72932             },
72933             "steeringWheelHeater": {
72934                 "type": "radio",
72935                 "options": ["on","off"],
72936                 "default": false
72937             },
72938             "seatHeater": {
72939                 "type": "radio",
72940                 "options": ["on","off"],
72941                 "default": false
72942             },
72943             "seatCooler": {
72944                 "type": "radio",
72945                 "options": ["on","off"],
72946                 "default": false
72947             }
72948         },
72949         "Sunroof": {
72950             "openness": {
72951                 "type": "text",
72952                 "title": "unsigned short (percentage)",
72953                 "default": 50
72954             },
72955             "tilt": {
72956                 "type": "text",
72957                 "title": "unsigned short (percentage)",
72958                 "default": 50
72959             }
72960         },
72961         "ConvertibleRoof": {
72962             "openness": {
72963                 "type": "text",
72964                 "title": "unsigned short (percentage)",
72965                 "default": 50
72966             }
72967         },
72968         "SecurityAlert": {
72969             "securityAlert": {
72970                 "type": "radio",
72971                 "options": ["on","off"],
72972                 "default": true
72973             }
72974         },
72975         "ParkingBrake": {
72976             "parkingBrake": {
72977                 "type": "radio",
72978                 "options": ["engaged","disengaged"],
72979                 "default": true
72980             }
72981         },
72982         "ParkingLight": {
72983             "parkingLight": {
72984                 "type": "radio",
72985                 "options": ["engaged","disengaged"],
72986                 "default": true
72987             }
72988         },
72989         "HazardLight": {
72990             "hazardLight": {
72991                 "type": "radio",
72992                 "options": ["engaged","disengaged"],
72993                 "default": true
72994             }
72995         },
72996         "AntilockBrakingSystem": {
72997             "securityAlert": {
72998                 "type": "radio",
72999                 "options": ["engaged","idle"],
73000                 "default": true
73001             }
73002         },
73003         "TractionControlSystem": {
73004             "tractionControlSystem": {
73005                 "type": "radio",
73006                 "options": ["on","off"],
73007                 "default": true
73008             }
73009         },
73010         "VehicleTopSpeedLimit": {
73011             "vehicleTopSpeedLimit": {
73012                 "type": "text",
73013                 "title": "unsigned short (km/h)",
73014                 "default": 150
73015             }
73016         },
73017         "WindowStatus": {
73018             "WindowStatus": {
73019                 "type": "text",
73020                 "title": "dictionary",
73021                 "default": null
73022             }
73023         },
73024         "AirbagStatus": {
73025             "airbagStatus": {
73026                 "type": "text",
73027                 "title": "dictionary",
73028                 "default": null
73029             }
73030         },
73031         "DoorStatus": {
73032             "airbagStatus": {
73033                 "type": "text",
73034                 "title": "dictionary",
73035                 "default": null
73036             }
73037         },
73038         "SeatBeltStatus": {
73039             "doorStatus": {
73040                 "type": "text",
73041                 "title": "dictionary",
73042                 "default": null
73043             },
73044             "doorLockStatus": {
73045                 "type": "text",
73046                 "title": "dictionary",
73047                 "default": null
73048             },
73049             "childLockStatus": {
73050                 "type": "radio",
73051                 "options": ["on","off"],
73052                 "default": true
73053             }
73054         },
73055         "OccupantStatus": {
73056             "occupantStatus": {
73057                 "type": "text",
73058                 "title": "dictionary",
73059                 "default": null
73060             }
73061         },
73062         "ObstacleDistance": {
73063             "obstacleDistance": {
73064                 "type": "text",
73065                 "title": "dictionary",
73066                 "default": null
73067             }
73068         }
73069     },
73070     properties: ["VehicleSpeed", "EngineSpeed", "VehiclePowerMode", "TripMeter",
73071         "Acceleration", "Transmission", "CruiseControlStatus", "WheelBrake",
73072         "LightStatus", "InteriorLightStatus", "Horn", "Fuel", "EngineOil",
73073         "Location", "ExteriorBrightness", "Temperature", "RainSensor",
73074         "WindshieldWiper", "HVAC", "WindowStatus", "Sunroof", "ConvertibleRoof",
73075         "VehicleId", "Size", "FuelInfo", "VehicleType", "Doors",
73076         "TransmissionGearType", "WheelInformation", "Odometer", "Fluid", "Battery",
73077         "TirePressure", "TireTemperature", "SecurityAlert", "ParkingBrake",
73078         "ParkingLight", "HazardLight", "AntilockBrakingSystem", "TractionControlSystem",
73079         "VehicleTopSpeedLimit", "AirbagStatus", "DoorStatus", "SeatBeltStatus",
73080         "OccupantStatus", "ObstacleDistance"],
73081     dataCount: 9,
73082     now: "1384408800000",
73083     historyCount: 0,
73084     history: {
73085     },
73086     zone: {
73087         "ZONE_None": 0,
73088         "ZONE_Front": 1,
73089         "ZONE_Middle": 0x10,
73090         "ZONE_Right": 0x100,
73091         "ZONE_Left": 0x1000,
73092         "ZONE_Rear": 0x10000,
73093         "ZONE_Center": 0x10000
73094     },
73095     data: {
73096         "1384408800000": { //2013-11-14 14:00:00
73097             "VehicleSpeed" : {
73098                 "vehicleSpeed": 0
73099             },
73100             "EngineSpeed" : {
73101                 "engineSpeed": 0
73102             },
73103             "VehiclePowerMode": {
73104                 "vehiclePowerMode": 1
73105             },
73106             "TripMeter": {
73107                 "tripMeters": [23, 7876, 124, 4577]
73108             },
73109             "Acceleration": {
73110                 "x": 0,
73111                 "y": 0,
73112                 "z": 0
73113             },
73114             "Fuel": {
73115                 "level": 87,
73116                 "range": 251,
73117                 "instantConsumption": 250,
73118                 "instantEconomy": 85,
73119                 "averageEconomy": 15
73120             },
73121             "EngineOil": {
73122                 "remaining": 0,
73123                 "temperature": 0,
73124                 "pressure": 0
73125             },
73126             "Location": {
73127                 "latitude": 0,
73128                 "longitude": 0,
73129                 "altitude": 0,
73130                 "direction": 0
73131             },
73132             "ExteriorBrightness": {
73133                 "exteriorBrightness": 0
73134             },
73135             "Temperature": {
73136                 "interior": 0,
73137                 "exterior": 0
73138             },
73139             "RainSensor": {
73140                 "rainSensor": 2
73141             },
73142             "Odometer": {
73143                 "odometer": 333
73144             }
73145         },
73146         "1384401600000": { //2013-11-14 12:00:00
73147             "VehicleSpeed" : {
73148                 "vehicleSpeed": 60
73149             },
73150             "EngineSpeed" : {
73151                 "engineSpeed": 2500
73152             },
73153             "VehiclePowerMode": {
73154                 "vehiclePowerMode": 0
73155             },
73156             "TripMeter": {
73157                 "tripMeters": [100, 1000, 1500]
73158             },
73159             "Acceleration": {
73160                 "x": 10,
73161                 "y": 10,
73162                 "z": 10
73163             },
73164             "Fuel": {
73165                 "level": 100,
73166                 "range": 105,
73167                 "instantConsumption": 59,
73168                 "instantEconomy": 87,
73169                 "averageEconomy": 15
73170             },
73171             "EngineOil": {
73172                 "remaining": 150,
73173                 "temperature": 560,
73174                 "pressure": 59
73175             },
73176             "Location": {
73177                 "latitude": -15,
73178                 "longitude": -89,
73179                 "altitude": 16,
73180                 "direction": 69
73181             },
73182             "ExteriorBrightness": {
73183                 "exteriorBrightness": 456
73184             },
73185             "Temperature": {
73186                 "interior": 45,
73187                 "exterior": 45
73188             },
73189             "RainSensor": {
73190                 "rainSensor": 10
73191             },
73192             "Odometer": {
73193                 "odometer": 1213
73194             }
73195         },
73196         "1384402500000": { //2013-11-14 12:15:00
73197             "VehicleSpeed" : {
73198                 "vehicleSpeed": 120
73199             },
73200             "EngineSpeed" : {
73201                 "engineSpeed": 2800
73202             },
73203             "VehiclePowerMode": {
73204                 "vehiclePowerMode": 1
73205             },
73206             "TripMeter": {
73207                 "tripMeters": [100, 1000]
73208             },
73209             "Acceleration": {
73210                 "x": 1002,
73211                 "y": 1045,
73212                 "z": 1036
73213             },
73214             "Fuel": {
73215                 "level": 100,
73216                 "range": 254,
73217                 "instantConsumption": 59,
73218                 "instantEconomy": 87,
73219                 "averageEconomy": 15
73220             },
73221             "EngineOil": {
73222                 "remaining": 78,
73223                 "temperature": 546,
73224                 "pressure": 54
73225             },
73226             "Location": {
73227                 "latitude": -97,
73228                 "longitude": -54,
73229                 "altitude": 124,
73230                 "direction": 65
73231             },
73232             "ExteriorBrightness": {
73233                 "exteriorBrightness": 45
73234             },
73235             "Temperature": {
73236                 "interior": 67,
73237                 "exterior": 45
73238             },
73239             "RainSensor": {
73240                 "rainSensor": 9
73241             },
73242             "Odometer": {
73243                 "odometer": 250
73244             }
73245         },
73246         "1384403400000": { //2013-11-14 12:30:00
73247             "VehicleSpeed" : {
73248                 "vehicleSpeed": 180
73249             },
73250             "EngineSpeed" : {
73251                 "engineSpeed": 3100
73252             },
73253             "VehiclePowerMode": {
73254                 "vehiclePowerMode": 2
73255             },
73256             "TripMeter": {
73257                 "tripMeters": [100, 1000, 1500]
73258             },
73259             "Acceleration": {
73260                 "x": 1234,
73261                 "y": 45,
73262                 "z": 67
73263             },
73264             "Fuel": {
73265                 "level": 34,
73266                 "range": 67,
73267                 "instantConsumption": 97,
73268                 "instantEconomy": 123,
73269                 "averageEconomy": 56
73270             },
73271             "EngineOil": {
73272                 "remaining": 155,
73273                 "temperature": 960,
73274                 "pressure": 78
73275             },
73276             "Location": {
73277                 "latitude": 58,
73278                 "longitude": -89,
73279                 "altitude": 123,
73280                 "direction": 69
73281             },
73282             "ExteriorBrightness": {
73283                 "exteriorBrightness": 768
73284             },
73285             "Temperature": {
73286                 "interior": 45,
73287                 "exterior": 98
73288             },
73289             "RainSensor": {
73290                 "rainSensor": 8
73291             },
73292             "Odometer": {
73293                 "odometer": 360
73294             }
73295         },
73296         "1384404300000": { //2013-11-14 12:45:00
73297             "VehicleSpeed" : {
73298                 "vehicleSpeed": 240
73299             },
73300             "EngineSpeed" : {
73301                 "engineSpeed": 3400
73302             },
73303             "VehiclePowerMode": {
73304                 "vehiclePowerMode": 3
73305             },
73306             "TripMeter": {
73307                 "tripMeters": [100, 15]
73308             },
73309             "Acceleration": {
73310                 "x": 789,
73311                 "y": 234,
73312                 "z": 1200
73313             },
73314             "Fuel": {
73315                 "level": 58,
73316                 "range": 78,
73317                 "instantConsumption": 123,
73318                 "instantEconomy": 56,
73319                 "averageEconomy": 31
73320             },
73321             "EngineOil": {
73322                 "remaining": 54,
73323                 "temperature": 963,
73324                 "pressure": 210
73325             },
73326             "Location": {
73327                 "latitude": -15,
73328                 "longitude": 32,
73329                 "altitude": 16,
73330                 "direction": 23
73331             },
73332             "ExteriorBrightness": {
73333                 "exteriorBrightness": 234
73334             },
73335             "Temperature": {
73336                 "interior": 76,
73337                 "exterior": 45
73338             },
73339             "RainSensor": {
73340                 "rainSensor": 7
73341             },
73342             "Odometer": {
73343                 "odometer": 38
73344             }
73345         },
73346         "1384405200000": { //2013-11-14 13:00:00
73347             "VehicleSpeed" : {
73348                 "vehicleSpeed": 280
73349             },
73350             "EngineSpeed" : {
73351                 "engineSpeed": 3700
73352             },
73353             "VehiclePowerMode": {
73354                 "vehiclePowerMode": 0
73355             },
73356             "TripMeter": {
73357                 "tripMeters": [1245, 1000]
73358             },
73359             "Acceleration": {
73360                 "x": 400,
73361                 "y": 10,
73362                 "z": 600
73363             },
73364             "Fuel": {
73365                 "level": 120,
73366                 "range": 130,
73367                 "instantConsumption": 140,
73368                 "instantEconomy": 145,
73369                 "averageEconomy": 47
73370             },
73371             "EngineOil": {
73372                 "remaining": 56,
73373                 "temperature": 78,
73374                 "pressure": 54
73375             },
73376             "Location": {
73377                 "latitude": -15,
73378                 "longitude": 12,
73379                 "altitude": 16,
73380                 "direction": 69
73381             },
73382             "ExteriorBrightness": {
73383                 "exteriorBrightness": 45
73384             },
73385             "Temperature": {
73386                 "interior": 45,
73387                 "exterior": 58
73388             },
73389             "RainSensor": {
73390                 "rainSensor": 6
73391             },
73392             "Odometer": {
73393                 "odometer": 1314
73394             }
73395         },
73396         "1384406100000": { //2013-11-14 13:15:00
73397             "VehicleSpeed" : {
73398                 "vehicleSpeed": 320
73399             },
73400             "EngineSpeed" : {
73401                 "engineSpeed": 4000
73402             },
73403             "VehiclePowerMode": {
73404                 "vehiclePowerMode": 1
73405             },
73406             "TripMeter": {
73407                 "tripMeters": [90, 100, 1000]
73408             },
73409             "Acceleration": {
73410                 "x": 850,
73411                 "y": 853,
73412                 "z": 956
73413             },
73414             "Fuel": {
73415                 "level": 78,
73416                 "range": 99,
73417                 "instantConsumption": 98,
73418                 "instantEconomy": 125,
73419                 "averageEconomy": 157
73420             },
73421             "EngineOil": {
73422                 "remaining": 89,
73423                 "temperature": 1001,
73424                 "pressure": 12
73425             },
73426             "Location": {
73427                 "latitude": 46,
73428                 "longitude": -89,
73429                 "altitude": 16,
73430                 "direction": 69
73431             },
73432             "ExteriorBrightness": {
73433                 "exteriorBrightness": 432
73434             },
73435             "Temperature": {
73436                 "interior": 45,
73437                 "exterior": 21
73438             },
73439             "RainSensor": {
73440                 "rainSensor": 5
73441             },
73442             "Odometer": {
73443                 "odometer": 521
73444             }
73445         },
73446         "1384407000000": { //2013-11-14 13:30:00
73447             "VehicleSpeed" : {
73448                 "vehicleSpeed": 220
73449             },
73450             "EngineSpeed" : {
73451                 "engineSpeed": 3200
73452             },
73453             "VehiclePowerMode": {
73454                 "vehiclePowerMode": 3
73455             },
73456             "TripMeter": {
73457                 "tripMeters": [55]
73458             },
73459             "Acceleration": {
73460                 "x": 777,
73461                 "y": 7878,
73462                 "z": 521
73463             },
73464             "Fuel": {
73465                 "level": 58,
73466                 "range": 96,
73467                 "instantConsumption": 230,
73468                 "instantEconomy": 237,
73469                 "averageEconomy": 245
73470             },
73471             "EngineOil": {
73472                 "remaining": 12,
73473                 "temperature": 521,
73474                 "pressure": 16
73475             },
73476             "Location": {
73477                 "latitude": -15,
73478                 "longitude": -89,
73479                 "altitude": 16,
73480                 "direction": 86
73481             },
73482             "ExteriorBrightness": {
73483                 "exteriorBrightness": 123
73484             },
73485             "Temperature": {
73486                 "interior": 45,
73487                 "exterior": 12
73488             },
73489             "RainSensor": {
73490                 "rainSensor": 4
73491             },
73492             "Odometer": {
73493                 "odometer": 2
73494             }
73495         },
73496         "1384407900000": { //2013-11-14 13:45:00
73497             "VehicleSpeed" : {
73498                 "vehicleSpeed": 100
73499             },
73500             "EngineSpeed" : {
73501                 "engineSpeed": 2600
73502             },
73503             "VehiclePowerMode": {
73504                 "vehiclePowerMode": 2
73505             },
73506             "TripMeter": {
73507                 "tripMeters": [1030, 1012]
73508             },
73509             "Acceleration": {
73510                 "x": 888,
73511                 "y": 666,
73512                 "z": 444
73513             },
73514             "Fuel": {
73515                 "level": 132,
73516                 "range": 145,
73517                 "instantConsumption": 87,
73518                 "instantEconomy": 169,
73519                 "averageEconomy": 91
73520             },
73521             "EngineOil": {
73522                 "remaining": 66,
73523                 "temperature": 1314,
73524                 "pressure": 88
73525             },
73526             "Location": {
73527                 "latitude": -15,
73528                 "longitude": -89,
73529                 "altitude": 789,
73530                 "direction": 69
73531             },
73532             "ExteriorBrightness": {
73533                 "exteriorBrightness": 768
73534             },
73535             "Temperature": {
73536                 "interior": 0,
73537                 "exterior": 45
73538             },
73539             "RainSensor": {
73540                 "rainSensor": 3
73541             },
73542             "Odometer": {
73543                 "odometer": 66
73544             }
73545         }
73546     }
73547 };
73548
73549 });
73550 define('ripple/platform/ivi/3.0/spec', function (require, exports, module) {
73551 /*
73552  *  Copyright 2012 Intel Corporation.
73553  *
73554  * Licensed under the Apache License, Version 2.0 (the "License");
73555  * you may not use this file except in compliance with the License.
73556  * You may obtain a copy of the License at
73557  *
73558  * http://www.apache.org/licenses/LICENSE-2.0
73559  *
73560  * Unless required by applicable law or agreed to in writing, software
73561  * distributed under the License is distributed on an "AS IS" BASIS,
73562  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
73563  * See the License for the specific language governing permissions and
73564  * limitations under the License.
73565  */
73566
73567 module.exports = {
73568
73569     id: "ivi",
73570     version: "3.0",
73571     name: "IVI",
73572
73573     persistencePrefix: "ivi3-",
73574
73575     config: require('ripple/platform/ivi/3.0/spec/config'),
73576     ui: require('ripple/platform/ivi/3.0/spec/ui'),
73577     device: require('ripple/platform/ivi/3.0/spec/device'),
73578     sensor: require('ripple/platform/ivi/3.0/spec/sensor'),
73579     DeviceMotionEvent: require('ripple/platform/tizen/2.0/DeviceMotionEvent'),
73580     DeviceOrientationEvent: require('ripple/platform/tizen/2.0/DeviceOrientationEvent'),
73581
73582     objects: {
73583         Coordinates: {
73584             path: "w3c/1.0/Coordinates"
73585         },
73586         Position: {
73587             path: "w3c/1.0/Position"
73588         },
73589         PositionError: {
73590             path: "w3c/1.0/PositionError"
73591         },
73592         SensorConnection: {
73593             path: "w3c/1.0/SensorConnection"
73594         },
73595         navigator: {
73596             path: "tizen/2.0/navigator",
73597             children: {
73598                 geolocation: {
73599                     path: "wac/2.0/geolocation"
73600                 }
73601             }
73602         },
73603         tizen: {
73604             children: {
73605                 vehicle: {
73606                     path: "ivi/3.0/vehicle",
73607                     feature: "http://tizen.org/privilege/vehicle",
73608                     handleSubfeatures: true
73609                 }
73610             }
73611         }
73612     }
73613 };
73614
73615 });
73616 define('ripple/platform/ivi/3.0/typecast', function (require, exports, module) {
73617 /*
73618  *  Copyright 2013 Intel Corporation.
73619  *
73620  * Licensed under the Apache License, Version 2.0 (the "License");
73621  * you may not use this file except in compliance with the License.
73622  * You may obtain a copy of the License at
73623  *
73624  * http://www.apache.org/licenses/LICENSE-2.0
73625  *
73626  * Unless required by applicable law or agreed to in writing, software
73627  * distributed under the License is distributed on an "AS IS" BASIS,
73628  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
73629  * See the License for the specific language governing permissions and
73630  * limitations under the License.
73631  */
73632
73633 var typedef = require('ripple/platform/ivi/3.0/typedef'),
73634     errorcode = require('ripple/platform/ivi/3.0/errorcode'),
73635     WebAPIException = require('ripple/platform/ivi/3.0/WebAPIException'),
73636     TypeCoerce = require('ripple/platform/ivi/3.0/typecoerce'),
73637     _self = {};
73638
73639 function _cast(pattern, obj, isDuplicate) {
73640     var tc, tcFunc;
73641
73642     if (pattern === null)
73643         return;
73644
73645     tc = new TypeCoerce(pattern);
73646     tcFunc = isDuplicate ? tc.copy : tc.cast;
73647
73648     if ((obj = tcFunc(obj)) === null) {
73649         throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
73650     }
73651
73652     return obj;
73653 }
73654
73655 function _castType(pattern) {
73656     /*
73657      * Type cast for each known type. The function name is the exact name of the
73658      * corresponding type.
73659      *
73660      * obj
73661      *    Variable to be casted
73662      *
73663      * aux
73664      *    Auxiliary descriptor of obj. It can be any one or combination of below
73665      *    strings, or ignored in most cases.
73666      *
73667      *    "?"     Nullable types
73668      *    "[]"    Array
73669      *    "+"     Deep copy
73670      *
73671      * Return
73672      *    Casted or duplicated object.
73673      */
73674
73675     return function (obj, aux) {
73676         var type, isNullable, isDuplicate;
73677
73678         aux = aux ? String(aux) : "";
73679         type = (aux.indexOf("[]") !== -1) ? [pattern] : pattern;
73680         isNullable = (aux.indexOf("?") !== -1);
73681         isDuplicate = (aux.indexOf("+") !== -1);
73682
73683         if (isNullable && ((obj === null) || (obj === undefined))) {
73684             return obj;
73685         }
73686
73687         return _cast(type, obj, isDuplicate);
73688     };
73689 }
73690
73691 function _castConstructor(name) {
73692     var constructors, hook, vtc, isOverloaded, castConstructor;
73693
73694     /*
73695      * Type cast for constructor. The function name is the exact name of the
73696      * object type.
73697      *
73698      * argv
73699      *    arguments. The keyword 'arguments' will always be passed in.
73700      */
73701
73702     function castUnique(argv) {
73703         _cast(constructors, argv, false);
73704     }
73705
73706     /*
73707      * Type cast for overloaded constructors. The function name is the exact
73708      * name of the object type.
73709      *
73710      * argv
73711      *    arguments. The keyword 'arguments' will always be passed in.
73712      *
73713      * scope
73714      *    'this' of the original constructor.
73715      *
73716      * voc
73717      *    Array of overloaded constructors callback
73718      */
73719
73720     function castOverload(argv, scope, voc) {
73721         var iOverload;
73722
73723         if (!vtc) {
73724             vtc = [];
73725             constructors.forEach(function (c) {
73726                 vtc.push((c === null) ? null : new TypeCoerce(c));
73727             });
73728         }
73729
73730         vtc.some(function (tc, index) {
73731             if (tc && (tc.cast(argv) === null))
73732                 return false;
73733
73734             iOverload = index;
73735             return true;
73736         });
73737
73738         if (iOverload === undefined) {
73739             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
73740         }
73741
73742         return (voc && voc[iOverload].apply(scope, argv));
73743     }
73744
73745     constructors = typedef.constructor[name];
73746
73747     if (name in _self) {
73748         hook = _self[name];
73749     }
73750
73751     isOverloaded = (Object.prototype.toString.call(constructors) ===
73752             "[object Array]");
73753     castConstructor = isOverloaded ? castOverload : castUnique;
73754
73755     return function (argv, scope) {
73756         if (Object.prototype.toString.call(argv) !== "[object Arguments]") {
73757             return (hook && hook.apply(this, arguments));
73758         }
73759
73760         if (!(scope instanceof argv.callee)) {
73761             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR, null, "TypeError");
73762         }
73763
73764         castConstructor.apply(this, arguments);
73765     };
73766 }
73767
73768 function _castInterface(name) {
73769     var interface, hook;
73770
73771     interface = typedef.interface[name];
73772
73773     if (name in _self) {
73774         hook = _self[name];
73775     }
73776
73777     /*
73778      * Type cast for each known method of interface. The function name is the
73779      * exact name of the corresponding interface.
73780      *
73781      * method
73782      *    String of method name
73783      *
73784      * argv
73785      *    arguments. The keyword 'arguments' will always be passed in.
73786      *
73787      * isDuplicate
73788      *    A boolean value to indicate whether arguments will be copied or not.
73789      */
73790
73791     return function (method, argv, isDuplicate) {
73792         if ((typeof method !== "string") || (typeof argv !== "object")) {
73793             return (hook && hook.apply(this, arguments));
73794         }
73795
73796         _cast(interface[method], argv, isDuplicate);
73797     };
73798 }
73799
73800 (function () {
73801     var i;
73802
73803     for (i in typedef) {
73804         _self[i] = _castType(typedef[i]);
73805     }
73806
73807     for (i in typedef.constructor) {
73808         _self[i] = _castConstructor(i);
73809         typedef[i]._constructor = i;
73810     }
73811
73812     for (i in typedef.interface) {
73813         _self[i] = _castInterface(i);
73814     }
73815 }());
73816
73817 module.exports = _self;
73818
73819 });
73820 define('ripple/platform/ivi/3.0/typecoerce', function (require, exports, module) {
73821 /*
73822  *  Copyright 2013 Intel Corporation.
73823  *
73824  * Licensed under the Apache License, Version 2.0 (the "License");
73825  * you may not use this file except in compliance with the License.
73826  * You may obtain a copy of the License at
73827  *
73828  * http://www.apache.org/licenses/LICENSE-2.0
73829  *
73830  * Unless required by applicable law or agreed to in writing, software
73831  * distributed under the License is distributed on an "AS IS" BASIS,
73832  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
73833  * See the License for the specific language governing permissions and
73834  * limitations under the License.
73835  */
73836
73837 var t = require('ripple/platform/ivi/3.0/typedef'),
73838     _self;
73839
73840 _self = function (pattern) {
73841     var typeCoerce, typeOfPattern;
73842
73843     // private
73844     function getExtendedType(val) {
73845         var type = Object.prototype.toString.call(val), attr;
73846
73847         switch (type) {
73848         case "[object Array]":
73849             if ((typeof val[0] === "string") && (val[0].length > 0)) {
73850                 type = "enum";
73851             } else {
73852                 type = "Union";
73853             }
73854             return type;
73855
73856         case "[object Object]":
73857             if ("_dictionary" in val) {
73858                 return "dictionary";
73859             }
73860
73861             type = "Object";
73862
73863             for (attr in val) {
73864                 if (attr === "0") {
73865                     type = "Arguments";
73866                 } else if (val[attr] === "Callback") {
73867                     type = "Callback";
73868                 }
73869                 break;
73870             }
73871
73872             return type;
73873         }
73874
73875         switch (val) {
73876         case "Callback":
73877             type = "Function";
73878             break;
73879
73880         case "TZDate":
73881         case "any":
73882         case "byte":
73883         case "float":
73884         case "long":
73885         case "long long":
73886         case "octet":
73887         case "short":
73888         case "unsigned long":
73889         case "unsigned long long":
73890         case "unsigned short":
73891             type = val;
73892             break;
73893
73894         case "double":
73895             type = "float";
73896             break;
73897
73898         default:    // Derivative type name: e.g., "AbstractFilter"
73899             type = "";
73900             break;
73901         }
73902
73903         return type;
73904     }
73905
73906     function getType(val, isPattern) {
73907         var type = Object.prototype.toString.call(val);
73908
73909         switch (type) {
73910         case "[object Array]":
73911             type = (isPattern && (val.length > 1)) ? getExtendedType(val) :
73912                     "Array";
73913             break;
73914
73915         case "[object Arguments]":
73916             type = "Arguments";
73917             break;
73918
73919         case "[object Boolean]":
73920             type = "boolean";
73921             break;
73922
73923         case "[object Date]":
73924             type = "Date";
73925             break;
73926
73927         case "[object Function]":
73928             type = "Function";
73929             break;
73930
73931         case "[object Number]":
73932             type = "Number";
73933             break;
73934
73935         case "[object Object]":
73936             type = isPattern ? getExtendedType(val) : "Object";
73937             break;
73938
73939         case "[object String]":
73940             type = (isPattern && !!val) ? getExtendedType(val) : "DOMString";
73941             break;
73942         }
73943
73944         return type;
73945     }
73946
73947     function isConstructed(obj) {
73948         if (!("_constructor" in pattern))
73949             return true;
73950
73951         if (obj instanceof window.tizen[pattern._constructor])
73952             return true;
73953
73954         return false;
73955     }
73956
73957     function toInteger(x) {
73958         return (x < 0) ? Math.ceil(x) : Math.floor(x);
73959     }
73960
73961     function modulo(a, b) {
73962         return (a - Math.floor(a / b) * b);
73963     }
73964
73965     function toInt(x, bits) {
73966         var p;
73967
73968         x = Number(x);
73969
73970         if (isNaN(x) || !isFinite(x))
73971             return null;
73972
73973         p = Math.pow(2, bits);
73974         x = modulo(toInteger(x), p);
73975
73976         return (x >= Math.pow(2, bits - 1)) ? (x - p) : x;
73977     }
73978
73979     function toUInt(x, bits) {
73980         x = Number(x);
73981
73982         if (isNaN(x) || !isFinite(x))
73983             return null;
73984
73985         return modulo(toInteger(x), Math.pow(2, bits));
73986     }
73987
73988     function toInt8(x) {
73989         return toInt(x, 8);
73990     }
73991
73992     function toInt16(x) {
73993         return toInt(x, 16);
73994     }
73995
73996     function toInt32(x) {
73997         return toInt(x, 32);
73998     }
73999
74000     function toInt64(x) {
74001         return toInt(x, 64);
74002     }
74003
74004     function toUInt8(x) {
74005         return toUInt(x, 8);
74006     }
74007
74008     function toUInt16(x) {
74009         return toUInt(x, 16);
74010     }
74011
74012     function toUInt32(x) {
74013         return toUInt(x, 32);
74014     }
74015
74016     function toUInt64(x) {
74017         return toUInt(x, 64);
74018     }
74019
74020     // public
74021     function cast(obj) {
74022         var typeMap,
74023             typeOfObj = getType(obj, false);
74024
74025         typeMap = {
74026             "Arguments": function () {
74027                 var i, isNullable, ret;
74028
74029                 for (i in pattern) {
74030                     if (i === "_optional")
74031                         continue;
74032
74033                     isNullable = !!(pattern._optional && pattern._optional[i]);
74034
74035                     if (i > obj.length - 1) {
74036                         if (!isNullable) {
74037                             return null;
74038                         }
74039                         break;
74040                     }
74041
74042                     if (!isNullable || (obj[i] !== null)) {
74043                         ret = _self(pattern[i]).cast(obj[i]);
74044                         if (ret === null) {
74045                             return null;
74046                         }
74047                         obj[i] = ret;
74048                     }
74049                 }
74050
74051                 return obj;
74052             },
74053
74054             "Array": function () {
74055                 var elementType, i, ret;
74056
74057                 if (typeOfObj !== typeOfPattern) {
74058                     return null;
74059                 }
74060
74061                 elementType = _self(pattern[0]);
74062                 for (i in obj) {
74063                     ret = elementType.cast(obj[i]);
74064                     if (ret === null) {
74065                         return null;
74066                     }
74067                     obj[i] = ret;
74068                 }
74069
74070                 return obj;
74071             },
74072
74073             "Callback": function () {
74074                 var attr;
74075
74076                 if (typeOfObj !== "Object") {
74077                     return null;
74078                 }
74079
74080                 for (attr in pattern) {
74081                     if (attr in obj) {
74082                         obj[attr] = _self(pattern[attr]).cast(obj[attr]);
74083                         if (obj[attr] === null) {
74084                             return null;
74085                         }
74086                     }
74087                 }
74088
74089                 return obj;
74090             },
74091
74092             "DOMString": function () {
74093                 switch (typeOfObj) {
74094                 case "DOMString":
74095                 case "Date":
74096                 case "Number":
74097                 case "boolean":
74098                     obj = String(obj);
74099                     break;
74100
74101                 default:
74102                     if ((obj === null) || (obj === undefined)) {
74103                         obj = String(obj);
74104                     } else {
74105                         obj = null;
74106                     }
74107                     break;
74108                 }
74109
74110                 return obj;
74111             },
74112
74113             "Date": function () {
74114                 return (typeOfObj === typeOfPattern) ? obj : null;
74115             },
74116
74117             "Function": function () {
74118                 return (typeOfObj === typeOfPattern) ? obj : null;
74119             },
74120
74121             "Object": function () {
74122                 var ret, attr, i;
74123
74124                 if (typeOfObj !== typeOfPattern) {
74125                     if ((obj === null) || (obj === undefined)) {
74126                         return null;
74127                     }
74128                     if (!("_derived" in pattern)) {
74129                         return null;
74130                     }
74131                 }
74132
74133                 if (!isConstructed(obj)) {
74134                     return null;
74135                 }
74136
74137                 for (attr in pattern) {
74138                     switch (attr) {
74139                     case "_optional":
74140                     case "_constructor":
74141                         break;
74142
74143                     case "_derived":
74144                         for (i in pattern._derived) {
74145                             ret = _self(pattern._derived[i]).cast(obj);
74146                             if (ret !== null)
74147                                 break;
74148                         }
74149                         if (ret === null) {
74150                             return null;
74151                         }
74152                         break;
74153
74154                     default:
74155                         if (!pattern._optional || !pattern._optional[attr] ||
74156                                 (obj[attr] !== undefined) &&
74157                                 (obj[attr] !== null)) {
74158                             ret = _self(pattern[attr]).cast(obj[attr]);
74159                             if (ret === null) {
74160                                 return null;
74161                             }
74162                             obj[attr] = ret;
74163                         }
74164                         break;
74165                     }
74166                 }
74167
74168                 return obj;
74169             },
74170
74171             "TZDate": function () {
74172                 if (typeOfObj !== "Object") {
74173                     return null;
74174                 }
74175                 return (obj instanceof window.tizen.TZDate) ? obj : null;
74176             },
74177
74178             "Union": function () {
74179                 var ret, i;
74180
74181                 for (i in pattern) {
74182                     ret = _self(pattern[i]).cast(obj);
74183                     if (ret !== null)
74184                         break;
74185                 }
74186
74187                 return ret;
74188             },
74189
74190             "any": function () {
74191                 return obj;
74192             },
74193
74194             "boolean": function () {
74195                 return (typeOfObj === typeOfPattern) ? obj : null;
74196             },
74197
74198             "byte": function () {
74199                 return toInt8(obj);
74200             },
74201
74202             "dictionary": function () {
74203                 var attr, ret;
74204
74205                 if (typeOfObj !== "Object") {
74206                     return null;
74207                 }
74208
74209                 for (attr in pattern) {
74210                     switch (attr) {
74211                     case "_dictionary":
74212                         if (pattern._dictionary !== null) {
74213                             ret = _self(pattern._dictionary).cast(obj);
74214                             if (ret === null) {
74215                                 return null;
74216                             }
74217                         }
74218                         break;
74219
74220                     default:
74221                         if ((attr in obj) && (obj[attr] !== null) &&
74222                                 (obj[attr] !== undefined)) {
74223                             ret = _self(pattern[attr]).cast(obj[attr]);
74224                             if (ret === null) {
74225                                 return null;
74226                             }
74227                             obj[attr] = ret;
74228                         }
74229                         break;
74230                     }
74231                 }
74232
74233                 return obj;
74234             },
74235
74236             "enum": function () {
74237                 var i;
74238
74239                 obj = String(obj).trim();
74240                 for (i in pattern) {
74241                     if (obj === pattern[i]) {
74242                         return obj;
74243                     }
74244                 }
74245
74246                 return null;
74247             },
74248
74249             "float": function () {
74250                 var f = parseFloat(obj, 10);
74251
74252                 return (isNaN(f) ? null : f);
74253             },
74254
74255             "long": function () {
74256                 return toInt32(obj);
74257             },
74258
74259             "long long": function () {
74260                 return toInt64(obj);
74261             },
74262
74263             "octet": function () {
74264                 return toUInt8(obj);
74265             },
74266
74267             "short": function () {
74268                 return toInt16(obj);
74269             },
74270
74271             "unsigned long": function () {
74272                 return toUInt32(obj);
74273             },
74274
74275             "unsigned long long": function () {
74276                 return toUInt64(obj);
74277             },
74278
74279             "unsigned short": function () {
74280                 return toUInt16(obj);
74281             },
74282
74283             "": function () {
74284                 return _self(t[pattern]).cast(obj);
74285             }
74286         };
74287
74288         return typeMap[typeOfPattern]();
74289     }
74290
74291     function copy(obj) {
74292         var typeMap,
74293             typeOfObj = getType(obj, false);
74294
74295         typeMap = {
74296             "Arguments": function () {
74297                 var i, isNullable, ret = [];
74298
74299                 for (i in pattern) {
74300                     if (i === "_optional")
74301                         continue;
74302
74303                     isNullable = !!(pattern._optional && pattern._optional[i]);
74304
74305                     if (i > obj.length - 1) {
74306                         if (!isNullable) {
74307                             return null;
74308                         }
74309                         break;
74310                     }
74311
74312                     if (!isNullable || (obj[i] !== null)) {
74313                         ret[i] = _self(pattern[i]).copy(obj[i]);
74314                         if (ret[i] === null) {
74315                             return null;
74316                         }
74317                     }
74318                 }
74319
74320                 for (i in ret) {
74321                     obj[i] = ret[i];
74322                 }
74323
74324                 return obj;
74325             },
74326
74327             "Array": function () {
74328                 var arr = [], elementType, i;
74329
74330                 if (typeOfObj !== typeOfPattern) {
74331                     return null;
74332                 }
74333
74334                 elementType = _self(pattern[0]);
74335                 for (i in obj) {
74336                     if (obj[i]) {
74337                         arr[i] = elementType.copy(obj[i]);
74338                         if (arr[i] === null)
74339                             return null;
74340                     }
74341                 }
74342
74343                 return arr;
74344             },
74345
74346             "Callback": function () {
74347                 var ret = {}, attr;
74348
74349                 if (typeOfObj !== "Object") {
74350                     return null;
74351                 }
74352
74353                 for (attr in pattern) {
74354                     if (attr in obj) {
74355                         ret[attr] = _self(pattern[attr]).copy(obj[attr]);
74356                         if (ret[attr] === null) {
74357                             return null;
74358                         }
74359                     }
74360                 }
74361
74362                 return ret;
74363             },
74364
74365             "Object": function () {
74366                 var ret = {}, attr, i, derived;
74367
74368                 if (typeOfObj !== typeOfPattern) {
74369                     if ((obj === null) || (obj === undefined)) {
74370                         return null;
74371                     }
74372                     if (!("_derived" in pattern)) {
74373                         return null;
74374                     }
74375                 }
74376
74377                 if (!isConstructed(obj)) {
74378                     return null;
74379                 }
74380                 if ("_constructor" in pattern) {
74381                     ret.__proto__ = window.tizen[pattern._constructor].prototype;
74382                 }
74383
74384                 for (attr in pattern) {
74385                     switch (attr) {
74386                     case "_optional":
74387                     case "_constructor":
74388                         break;
74389
74390                     case "_derived":
74391                         for (i in pattern._derived) {
74392                             derived = _self(pattern._derived[i]).copy(obj);
74393                             if (derived !== null)
74394                                 break;
74395                         }
74396                         if (derived === null) {
74397                             return null;
74398                         }
74399                         for (attr in derived) {
74400                             ret[attr] = derived[attr];
74401                         }
74402                         break;
74403
74404                     default:
74405                         if (!pattern._optional || !pattern._optional[attr] ||
74406                                 (obj[attr] !== undefined) &&
74407                                 (obj[attr] !== null)) {
74408                             ret[attr] = _self(pattern[attr]).copy(obj[attr]);
74409                             if (ret[attr] === null) {
74410                                 return null;
74411                             }
74412                         }
74413                         break;
74414                     }
74415                 }
74416
74417                 return ret;
74418             },
74419
74420             "Union": function () {
74421                 var ret, i;
74422
74423                 for (i in pattern) {
74424                     ret = _self(pattern[i]).copy(obj);
74425                     if (ret !== null)
74426                         break;
74427                 }
74428
74429                 return ret;
74430             },
74431
74432             "dictionary": function () {
74433                 var ret = {}, attr, base, i;
74434
74435                 if (typeOfObj !== "Object") {
74436                     return null;
74437                 }
74438
74439                 for (attr in pattern) {
74440                     switch (attr) {
74441                     case "_dictionary":
74442                         if (pattern._dictionary !== null) {
74443                             base = _self(pattern._dictionary).copy(obj);
74444                             if (base === null) {
74445                                 return null;
74446                             }
74447                             for (i in base) {
74448                                 ret[i] = base[i];
74449                             }
74450                         }
74451                         break;
74452
74453                     default:
74454                         if ((attr in obj) && (obj[attr] !== null) &&
74455                                 (obj[attr] !== undefined)) {
74456                             ret[attr] = _self(pattern[attr]).copy(obj[attr]);
74457                             if (ret[attr] === null) {
74458                                 return null;
74459                             }
74460                         }
74461                         break;
74462                     }
74463                 }
74464
74465                 return ret;
74466             },
74467
74468             "": function () {
74469                 return _self(t[pattern]).copy(obj);
74470             }
74471         };
74472
74473         return (typeOfPattern in typeMap) ? typeMap[typeOfPattern]() :
74474                 cast(obj);
74475     }
74476
74477     function match(obj) {
74478         var typeMap,
74479             typeOfObj = getType(obj, false);
74480
74481         typeMap = {
74482             "Array": function () {
74483                 var elementType, i;
74484
74485                 if (typeOfObj !== typeOfPattern)
74486                     return false;
74487
74488                 elementType = _self(pattern[0]);
74489                 for (i in obj) {
74490                     if (!elementType.match(obj[i])) {
74491                         return false;
74492                     }
74493                 }
74494
74495                 return true;
74496             },
74497
74498             "Callback": function () {
74499                 var attr, isMatched = true;
74500
74501                 if (typeOfObj !== "Object") {
74502                     return false;
74503                 }
74504
74505                 for (attr in pattern) {
74506                     if (attr in obj) {
74507                         isMatched = _self(pattern[attr]).match(obj[attr]);
74508                         if (!isMatched) {
74509                             break;
74510                         }
74511                     }
74512                 }
74513
74514                 return isMatched;
74515             },
74516
74517             "DOMString": function () {
74518                 return (typeOfObj === typeOfPattern);
74519             },
74520
74521             "Date": function () {
74522                 return (typeOfObj === typeOfPattern);
74523             },
74524
74525             "Function": function () {
74526                 return (typeOfObj === typeOfPattern);
74527             },
74528
74529             "Object": function () {
74530                 var attr, isMatched = false, i;
74531
74532                 if (typeOfObj !== typeOfPattern) {
74533                     if ((obj === null) || (obj === undefined)) {
74534                         return false;
74535                     }
74536                     if (!("_derived" in pattern)) {
74537                         return false;
74538                     }
74539                     return false;
74540                 }
74541
74542                 if (!isConstructed(obj)) {
74543                     return false;
74544                 }
74545
74546                 for (attr in pattern) {
74547                     switch (attr) {
74548                     case "_optional":
74549                     case "_constructor":
74550                         break;
74551
74552                     case "_derived":
74553                         for (i in pattern._derived) {
74554                             isMatched = _self(pattern._derived[i]).match(obj);
74555                             if (isMatched)
74556                                 break;
74557                         }
74558                         break;
74559
74560                     default:
74561                         if (pattern._optional && pattern._optional[attr]) {
74562                             isMatched = ((obj[attr] === null) ||
74563                                     (obj[attr] === undefined) ||
74564                                     _self(pattern[attr]).match(obj[attr]));
74565                         } else {
74566                             isMatched = (obj[attr] !== undefined) &&
74567                                     _self(pattern[attr]).match(obj[attr]);
74568                         }
74569                         break;
74570                     }
74571
74572                     if (!isMatched)
74573                         break;
74574                 }
74575
74576                 /*// Check if verbose attributes are present
74577                 if (isMatched) {
74578                     for (attr in obj) {
74579                         if (pattern[attr] === undefined) {
74580                             isMatched = false;
74581                             break;
74582                         }
74583                     }
74584                 }*/
74585
74586                 return isMatched;
74587             },
74588
74589             "Union": function () {
74590                 var isMatched, i;
74591
74592                 for (i in pattern) {
74593                     isMatched = _self(pattern[i]).match(obj);
74594                     if (isMatched)
74595                         break;
74596                 }
74597
74598                 return isMatched;
74599             },
74600
74601             "any": function () {
74602                 return true;
74603             },
74604
74605             "boolean": function () {
74606                 return (typeOfObj === typeOfPattern);
74607             },
74608
74609             "byte": function () {
74610                 return (obj === toInt8(obj));
74611             },
74612
74613             "dictionary": function () {
74614                 var attr, isMatched = true;
74615
74616                 if (typeOfObj !== "Object") {
74617                     return false;
74618                 }
74619
74620                 for (attr in pattern) {
74621                     switch (attr) {
74622                     case "_dictionary":
74623                         if (pattern._dictionary !== null) {
74624                             isMatched = _self(pattern._dictionary).match(obj);
74625                             if (!isMatched)
74626                                 break;
74627                         }
74628                         break;
74629
74630                     default:
74631                         if ((attr in obj) && (obj[attr] !== null) &&
74632                                 (obj[attr] !== undefined)) {
74633                             isMatched = _self(pattern[attr]).match(obj[attr]);
74634                             if (!isMatched)
74635                                 break;
74636                         }
74637                         break;
74638                     }
74639                 }
74640
74641                 return isMatched;
74642             },
74643
74644             "enum": function () {
74645                 for (var i in pattern) {
74646                     if (obj === pattern[i]) {
74647                         return true;
74648                     }
74649                 }
74650
74651                 return false;
74652             },
74653
74654             "float": function () {
74655                 return (typeOfObj === "Number");
74656             },
74657
74658             "long": function () {
74659                 return (obj === toInt32(obj));
74660             },
74661
74662             "long long": function () {
74663                 return (obj === toInt64(obj));
74664             },
74665
74666             "octet": function () {
74667                 return (obj === toUInt8(obj));
74668             },
74669
74670             "short": function () {
74671                 return (obj === toInt16(obj));
74672             },
74673
74674             "unsigned long": function () {
74675                 return (obj === toUInt32(obj));
74676             },
74677
74678             "unsigned long long": function () {
74679                 return (obj === toUInt64(obj));
74680             },
74681
74682             "unsigned short": function () {
74683                 return (obj === toUInt16(obj));
74684             },
74685
74686             "Arguments": function () {
74687                 return true;
74688             },
74689
74690             "": function () {
74691                 return _self(t[pattern]).match(obj);
74692             }
74693         };
74694
74695         return typeMap[typeOfPattern]();
74696     }
74697
74698     typeOfPattern = getType(pattern, true);
74699
74700     typeCoerce = {
74701         cast:  cast,
74702         copy:  copy,
74703         match: match
74704     };
74705
74706     return typeCoerce;
74707 };
74708
74709 module.exports = _self;
74710
74711 });
74712 define('ripple/platform/ivi/3.0/typedef', function (require, exports, module) {
74713 /*
74714  *  Copyright 2013 Intel Corporation.
74715  *
74716  * Licensed under the Apache License, Version 2.0 (the "License");
74717  * you may not use this file except in compliance with the License.
74718  * You may obtain a copy of the License at
74719  *
74720  * http://www.apache.org/licenses/LICENSE-2.0
74721  *
74722  * Unless required by applicable law or agreed to in writing, software
74723  * distributed under the License is distributed on an "AS IS" BASIS,
74724  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
74725  * See the License for the specific language governing permissions and
74726  * limitations under the License.
74727  */
74728
74729 var _t, _c, _i;
74730
74731 /*
74732  * Primitive type definition
74733  */
74734
74735 _t = {
74736     // Basic
74737     Callback:                           "Callback",
74738     DOMString:                          "",
74739     Date:                               new Date(),
74740     Function:                           function () {},
74741     TZDate:                             "TZDate",
74742     any:                                "any",
74743     boolean:                            false,
74744     byte:                               "byte",
74745     double:                             "double",
74746     float:                              "float",
74747     long:                               "long",
74748     octet:                              "octet",
74749     short:                              "short",
74750     long_long:                          "long long",
74751     unsigned_long:                      "unsigned long",
74752     unsigned_long_long:                 "unsigned long long",
74753     unsigned_short:                     "unsigned short"
74754 };
74755
74756 /*
74757  * Derivative type definition
74758  */
74759
74760 /*
74761  * Object attributes
74762  *     Contruct a prototype of an object. Specify a primitive type for each attribute.
74763  *
74764  * _optional
74765  *     Optional attributes table, which consists of two types of attributes,
74766  *
74767  *     nullable
74768  *         Nullable attributes, marked as '?' in IDL.
74769  *
74770  *     undefined
74771  *         Array type attributes, that not definitely specified to be
74772  *         initialized as an empty array, i.e., undefined-initialized array.
74773  *
74774  * _derived
74775  *     Derived types, which used in two cases of definition,
74776  *
74777  *     Subtype list
74778  *         An array consists of derived subtypes. It exists in the definition of
74779  *         a base type.
74780  *
74781  *     Union types
74782  *         An array consists of member types. It exists in the definition of
74783  *         a union type.
74784  *
74785  * _dictionary
74786  *     Dictionary type, which indicates that the object is a dictionary type.
74787  */
74788
74789 /*
74790  * Vehicle
74791  */
74792 _t.SupportedPropertiesSuccessCallback = _t.Function;
74793
74794 _t.VehiclePropertyErrorCallback = _t.Function;
74795
74796 _t.VehiclePropertyCallback = _t.Function;
74797
74798 _t.VehiclePropertyListCallback = _t.Function;
74799
74800 /*
74801  * VehicleSpeed
74802  */
74803 _t.VehicleSpeed = {
74804     vehicleSpeed: _t.unsigned_long
74805 };
74806
74807 /*
74808  * EngineSpeed
74809  */
74810 _t.EngineSpeed = {
74811     engineSpeed: _t.unsigned_long
74812 };
74813
74814 /*
74815  * VehiclePowerMode
74816  */
74817 _t.VehiclePowerMode = {
74818     vehiclePowerMode: _t.octet
74819 };
74820
74821 /*
74822  * TripMeters
74823  */
74824 _t.TripMeter = {
74825     tripMeters: [_t.unsigned_long]
74826 };
74827
74828 /*
74829  * Acceleration
74830  */
74831 _t.Acceleration = {
74832     x: _t.unsigned_long,
74833     y: _t.unsigned_long,
74834     z: _t.unsigned_long
74835 };
74836
74837 /*
74838  * Transmission
74839  */
74840 _t.Transmission = {
74841     gearPosition: _t.octet,
74842     mode: _t.octet
74843 };
74844
74845 /*
74846  * CruiseControlStatus
74847  */
74848 _t.CruiseControlStatus = {
74849     activated: _t.boolean,
74850     speed: _t.unsigned_short
74851 };
74852 /*
74853  * WheelBrake
74854  */
74855 _t.WheelBrake = {
74856     engaged: _t.boolean
74857 };
74858
74859 /*
74860  * LightStatus
74861  */
74862 _t.LightStatus = {
74863     head: _t.boolean,
74864     rightTurn: _t.boolean,
74865     leftTurn: _t.boolean,
74866     brake: _t.boolean,
74867     fog: _t.boolean,
74868     hazard: _t.boolean,
74869     parking: _t.boolean,
74870     highBeam: _t.boolean
74871 };
74872
74873 /*
74874  * InteriorLightStatus
74875  */
74876 _t.InteriorLightStatus = {
74877     passenger: _t.boolean,
74878     driver: _t.boolean,
74879     center: _t.boolean
74880 };
74881
74882 /*
74883  * Horn
74884  */
74885 _t.Horn = {
74886     on: _t.boolean
74887 };
74888
74889 /*
74890  * Fuel
74891  */
74892 _t.Fuel = {
74893     level: _t.unsigned_short,
74894     range: _t.unsigned_short,
74895     instantConsumption: _t.unsigned_short,
74896     instantEconomy: _t.unsigned_short,
74897     averageEconomy: _t.unsigned_short
74898 };
74899
74900 /*
74901  * EngineOil
74902  */
74903 _t.EngineOil = {
74904     remaining: _t.unsigned_short,
74905     temperature: _t.long,
74906     pressure: _t.unsigned_short
74907 };
74908
74909 /*
74910  * Location
74911  */
74912 _t.Location = {
74913     latitude: _t.double,
74914     longitude: _t.double,
74915     altitude: _t.double,
74916     direction: _t.unsigned_short
74917 };
74918
74919 /*
74920  * ExteriorBrightness
74921  */
74922 _t.ExteriorBrightness = {
74923     exteriorBrightness: _t.unsigned_long
74924 };
74925
74926 /*
74927  * Temperature
74928  */
74929 _t.Temperature = {
74930     interior: _t.short,
74931     exterior: _t.short
74932 };
74933
74934 /*
74935  * RainSensor
74936  */
74937 _t.RainSensor = {
74938     rainSensor: _t.unsigned_short
74939 };
74940
74941 /*
74942  * WindshieldWiper
74943  */
74944 _t.WindshieldWiper = {
74945     windshieldWiper: _t.unsigned_short
74946 };
74947
74948 /*
74949  * DefrostDictionary
74950  */
74951 _t.DefrostDictionary = {
74952     window: _t.unsigned_short,
74953     defrost: _t.boolean,
74954
74955     _dictionary: true
74956 };
74957
74958 /*
74959  * HVAC
74960  */
74961 _t.HVAC = {
74962     airflowDirection: _t.unsigned_short,
74963     fanSpeed: _t.unsigned_short,
74964     targetTemperature: _t.unsigned_short,
74965     airConditioning: _t.boolean,
74966     airRecirculation: _t.boolean,
74967     heater: _t.boolean,
74968     steeringWheelHeater: _t.boolean,
74969     seatHeater: _t.boolean,
74970     seatCooler: _t.boolean
74971 };
74972
74973 /*
74974  * WindowStatus
74975  */
74976 _t.WindowStatus = {
74977     openness: _t.unsigned_short,
74978     defrost: _t.boolean
74979 };
74980
74981 /*
74982  * Sunroof
74983  */
74984 _t.Sunroof = {
74985     openness: _t.unsigned_short,
74986     tilt: _t.unsigned_short
74987 };
74988
74989 /*
74990  * ConvertibleRoof
74991  */
74992 _t.ConvertibleRoof = {
74993     openness: _t.unsigned_short
74994 };
74995
74996 /*
74997  * VehicleId
74998  */
74999 _t.VehicleId = {
75000     WMI: _t.DOMString,
75001     VIN: _t.DOMString
75002 };
75003
75004 /*
75005  * Size
75006  */
75007 _t.Size = {
75008     width: _t.unsigned_long,
75009     height: _t.unsigned_long,
75010     length: _t.unsigned_long
75011 };
75012
75013 /*
75014  * FuelInfo
75015  */
75016 _t.FuelInfo = {
75017     type: _t.unsigned_short,
75018     refuelPosition: _t.unsigned_short
75019 };
75020
75021 /*
75022  * VehicleType
75023  */
75024 _t.VehicleType = {
75025     type: _t.unsigned_short
75026 };
75027
75028 /*
75029  * Doors
75030  */
75031 _t.Doors = {
75032     doorsPerRow: [_t.unsigned_short]
75033 };
75034
75035 /*
75036  * TransmissionGearType
75037  */
75038 _t.TransmissionGearType = {
75039     transmissionGearType: _t.unsigned_short
75040 };
75041
75042 /*
75043  * WheelInformation
75044  */
75045 _t.WheelInformation = {
75046     frontWheelRadius: _t.unsigned_short,
75047     rearWheelRadius: _t.unsigned_short,
75048     wheelTrack: _t.unsigned_long,
75049     ABS: _t.boolean
75050 };
75051
75052 /*
75053  * Odometer
75054  */
75055 _t.Odometer = {
75056     odometer: _t.unsigned_long
75057 };
75058
75059 /*
75060  * Fluid
75061  */
75062 _t.Fluid = {
75063     transmission: _t.unsigned_short,
75064     brake: _t.unsigned_short,
75065     washer: _t.unsigned_short
75066 };
75067
75068 /*
75069  * Battery
75070  */
75071 _t.Battery = {
75072     voltage: _t.double,
75073     current: _t.double
75074 };
75075
75076 /*
75077  * TirePressure
75078  */
75079 _t.TirePressure = {
75080     leftFront: _t.double,
75081     rightFront: _t.double,
75082     leftRear: _t.double,
75083     rightRear: _t.double
75084 };
75085
75086 /*
75087  * TireTemperature
75088  */
75089 _t.TireTemperature = {
75090     leftFront: _t.double,
75091     rightFront: _t.double,
75092     leftRear: _t.double,
75093     rightRear: _t.double
75094 };
75095
75096 /*
75097  * SecurityAlert
75098  */
75099 _t.SecurityAlert = {
75100     securityAlert: _t.boolean
75101 };
75102
75103 /*
75104  * ParkingBrake
75105  */
75106 _t.ParkingBrake = {
75107     parkingBrake: _t.boolean
75108 };
75109
75110 /*
75111  * ParkingLight
75112  */
75113 _t.ParkingLight = {
75114     parkingLight: _t.boolean
75115 };
75116
75117 /*
75118  * HazardLight
75119  */
75120 _t.HazardLight = {
75121     hazardLight: _t.boolean
75122 };
75123
75124 /*
75125  * AntilockBrakingSystem
75126  */
75127 _t.AntilockBrakingSystem = {
75128     antilockBrakingSystem: _t.boolean
75129 };
75130
75131 /*
75132  * TractionControlSystem
75133  */
75134 _t.TractionControlSystem = {
75135     tractionControlSystem: _t.boolean
75136 };
75137
75138 /*
75139  * VehicleTopSpeedLimit
75140  */
75141 _t.VehicleTopSpeedLimit = {
75142     vehicleTopSpeedLimit: _t.unsigned_short
75143 };
75144
75145 /*
75146  * AirbagStatus
75147  */
75148 _t.AirbagStatus = {
75149     airbagStatus: _t.unsigned_short
75150 };
75151
75152 /*
75153  * DoorStatus
75154  */
75155 _t.DoorStatus = {
75156     doorStatus: _t.unsigned_short,
75157     doorLockStatus: _t.boolean,
75158     childLockStatus: _t.boolean
75159 };
75160
75161 /*
75162  * SeatBeltStatus
75163  */
75164 _t.SeatBeltStatus = {
75165     seatBeltStatus: _t.boolean
75166 };
75167
75168 /*
75169  * OccupantStatus
75170  */
75171 _t.OccupantStatus = {
75172     occupantStatus: _t.unsigned_short
75173 };
75174
75175 /*
75176  * ObstacleDistance
75177  */
75178 _t.ObstacleDistance = {
75179     obstacleDistance: _t.double
75180 };
75181
75182 /*
75183  * NightMode
75184  */
75185 _t.NightMode = {
75186     nightMode: _t.boolean
75187 };
75188
75189 /*
75190  * DrivingMode
75191  */
75192 _t.DrivingMode = {
75193     drivingMode: _t.unsigned_short
75194 };
75195
75196 /*
75197  * TurnSignal
75198  */
75199 _t.TurnSignal = {
75200     turnSignal: _t.unsigned_short
75201 };
75202
75203 /*
75204  * ButtonEvent
75205  */
75206 _t.ButtonEvent = {
75207     buttonEvent: _t.unsigned_short
75208 };
75209
75210 /*
75211  * VehiclePropertyType
75212  */
75213 _t.VehiclePropertyType = {
75214     time: _t.unsigned_long_long,
75215     zone: _t.short,
75216     source: _t.DOMString,
75217
75218     _derived: [_t.VehicleSpeed, _t.EngineSpeed, _t.VehiclePowerMode,
75219         _t.TripMeter, _t.Acceleration, _t.Transmission,
75220         _t.CruiseControlStatus, _t.WheelBrake, _t.LightStatus,
75221         _t.InteriorLightStatus, _t.Horn, _t.Fuel, _t.EngineOil, _t.Location,
75222         _t.ExteriorBrightness, _t.Temperature, _t.RainSensor,
75223         _t.WindshieldWiper, _t.HVAC, _t.WindowStatus, _t.Sunroof,
75224         _t.ConvertibleRoof, _t.VehicleId, _t.Size, _t.FuelInfo, _t.VehicleType,
75225         _t.Doors, _t.TransmissionGearType, _t.WheelInformation, _t.Odometer,
75226         _t.Fluid, _t.Battery, _t.TirePressure, _t.TireTemperature,
75227         _t.SecurityAlert, _t.ParkingBrake, _t.ParkingLight, _t.HazardLight,
75228         _t.AntilockBrakingSystem, _t.TractionControlSystem,
75229         _t.VehicleTopSpeedLimit, _t.AirbagStatus, _t.DoorStatus,
75230         _t.SeatBeltStatus, _t.OccupantStatus, _t.ObstacleDistance,
75231         _t.NightMode, _t.TurnSignal, _t.ButtonEvent]
75232 };
75233
75234 /*
75235  * Constructor list definition
75236  */
75237
75238 /*
75239  * Generic constructor
75240  *     Construct a prototype of constructor. A fake array of arguments type is
75241  *     specified for constructor.
75242  *
75243  * Overloaded constructors
75244  *     Construct an array of prototype of constructor. Each array element is
75245  *     specified for one of constructors. The constructor with extra arguments
75246  *     are recommended to be defined ahead of the one with fewer same arguments
75247  *     for exact match.
75248  */
75249
75250 _c = {};
75251
75252 /*
75253  * Interface prototype definition
75254  */
75255
75256 _i = {
75257     // Vehicle
75258     Vehicle: {}
75259 };
75260
75261 _i.Vehicle.get = {
75262     0: _t.DOMString,
75263     1: _t.short,
75264
75265     _optional: {
75266         // nullable
75267         1: true
75268     }
75269 };
75270
75271 _i.Vehicle.subscribe = {
75272     0: _t.DOMString,
75273     1: _t.VehiclePropertyCallback,
75274     2: _t.short,
75275     3: _t.VehiclePropertyErrorCallback,
75276
75277     _optional: {
75278         // nullable
75279         2: true,
75280         3: true
75281     }
75282 };
75283
75284 _i.Vehicle.set = {
75285     0: _t.DOMString,
75286     1: _t.VehiclePropertyType,
75287     2: _t.VehiclePropertyErrorCallback,
75288
75289     _optional: {
75290         // nullable
75291         2: true
75292     }
75293 };
75294
75295 _i.Vehicle.getHistory = {
75296     0: _t.DOMString,
75297     1: _t.short,
75298     2: _t.Date,
75299     3: _t.Date,
75300     4: _t.VehiclePropertyListCallback,
75301     5: _t.VehiclePropertyErrorCallback,
75302
75303     _optional: {
75304         // nullable
75305         5: true
75306     }
75307 };
75308
75309 _i.Vehicle.listZones = {
75310     0: _t.DOMString
75311 };
75312
75313 // Exports
75314 _t.constructor = _c;
75315 _t.interface   = _i;
75316
75317 module.exports = _t;
75318
75319 });
75320 define('ripple/platform/ivi/3.0/vehicle', function (require, exports, module) {
75321 /*
75322  *  Copyright 2013 Intel Corporation.
75323  *
75324  * Licensed under the Apache License, Version 2.0 (the "License");
75325  * you may not use this file except in compliance with the License.
75326  * You may obtain a copy of the License at
75327  *
75328  * http://www.apache.org/licenses/LICENSE-2.0
75329  *
75330  * Unless required by applicable law or agreed to in writing, software
75331  * distributed under the License is distributed on an "AS IS" BASIS,
75332  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
75333  * See the License for the specific language governing permissions and
75334  * limitations under the License.
75335  */
75336
75337 var utils = require('ripple/utils'),
75338     event = require('ripple/event'),
75339     t = require('ripple/platform/ivi/3.0/typecast'),
75340     errorcode = require('ripple/platform/ivi/3.0/errorcode'),
75341     WebAPIError = require('ripple/platform/ivi/3.0/WebAPIError'),
75342     WebAPIException = require('ripple/platform/ivi/3.0/WebAPIException'),
75343     _self,
75344     _security = {
75345         "http://tizen.org/privilege/vehicle": ["supported", "get", "set",
75346             "getHistory", "subscribe", "listZones"]
75347     },
75348     _vehicleCacheData = {
75349         "supported": null,
75350         "data": null
75351     },
75352     _vehicleEvent = {subscribe: {}},
75353     VehiclePropertyType,
75354     VehicleSpeed,
75355     EngineSpeed,
75356     VehiclePowerMode,
75357     TripMeter,
75358     Acceleration,
75359     Transmission,
75360     CruiseControlStatus,
75361     WheelBrake,
75362     LightStatus,
75363     InteriorLightStatus,
75364     Horn,
75365     Fuel,
75366     EngineOil,
75367     Location,
75368     ExteriorBrightness,
75369     Temperature,
75370     RainSensor,
75371     WindshieldWiper,
75372     HVAC,
75373     WindowStatus,
75374     Sunroof,
75375     ConvertibleRoof,
75376     VehicleId,
75377     Size,
75378     FuelInfo,
75379     VehicleType,
75380     Doors,
75381     TransmissionGearType,
75382     WheelInformation,
75383     Odometer,
75384     Fluid,
75385     Battery,
75386     TirePressure,
75387     TireTemperature,
75388     SecurityAlert,
75389     ParkingBrake,
75390     ParkingLight,
75391     HazardLight,
75392     AntilockBrakingSystem,
75393     TractionControlSystem,
75394     VehicleTopSpeedLimit,
75395     AirbagStatus,
75396     DoorStatus,
75397     SeatBeltStatus,
75398     OccupantStatus,
75399     ObstacleDistance,
75400     NightMode,
75401     DrivingMode,
75402     TurnSignal,
75403     ButtonEvent,
75404     VehicleFactory;
75405
75406 function _initialize () {
75407     event.on("vehicle-cache-refresh", function (supported, data) {
75408         _vehicleCacheData.supported = supported;
75409         _vehicleCacheData.data = data;
75410     });
75411
75412     event.trigger("vehicle-cache-request", [_vehicleCacheData]);
75413 }
75414
75415 /*function _reloadVehicle (data) {
75416     var property, name, format = {};
75417
75418     for (name in data) {
75419         property = data[name];
75420
75421         format[name] = new VehicleFactory(name, _vehicleCacheData.data[name]);
75422     }
75423
75424     return format;
75425 }*/
75426
75427 _self = function () {
75428     var vehicle;
75429
75430     function supported () {
75431         if (!_security.supported) {
75432             throw new WebAPIException(errorcode.PERMISSION_DENIED);
75433         }
75434
75435         return _vehicleCacheData.supported;
75436     }
75437
75438     function get (property, zone) {
75439         if (!_security.get) {
75440             throw new WebAPIException(errorcode.PERMISSION_DENIED);
75441         }
75442
75443         t.Vehicle("get", arguments);
75444
75445         if (_vehicleCacheData.supported.indexOf(property) === -1) {
75446             throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
75447         }
75448
75449         return new VehicleFactory(property, _vehicleCacheData.data[property]);
75450     }
75451
75452     function subscribe (property, successCallback, zone, errorCallback) {
75453         if (!_security.subscribe) {
75454             throw new WebAPIException(errorcode.PERMISSION_DENIED);
75455         }
75456
75457         t.Vehicle("subscribe", arguments);
75458
75459         if (_vehicleCacheData.supported.indexOf(property) === -1) {
75460             throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
75461         }
75462
75463         _vehicleEvent.subscribe[property] = {
75464             successCallback: successCallback,
75465             errorCallback: errorCallback
75466         };
75467
75468         window.setTimeout(function () {
75469             if (! _vehicleEvent["vehicle-subscribe-response"]) {
75470                 event.on("vehicle-subscribe-response", function (propertyObj) {
75471                     var propertySub = _vehicleEvent.subscribe[propertyObj.type],
75472                         success = propertySub.successCallback,
75473                         error = propertySub.errorCallback;
75474
75475                     if (propertyObj.supported) {
75476                         success(new VehicleFactory(propertyObj.type, propertyObj.val));
75477                     }
75478                     else {
75479                         if (error) {
75480                             error(new WebAPIError(errorcode.PROPERTY_UNAVAILABLE));
75481                         }
75482                         else {
75483                             throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
75484                         }
75485                     }
75486                 });
75487                 _vehicleEvent["vehicle-subscribe-response"] = true;
75488             }
75489             event.trigger("vehicle-subscribe-request", [property, true, zone]);
75490         }, 1);
75491     }
75492
75493     function set (property, value, errorCallback) {
75494         var val = utils.copy(value);
75495
75496         if (!_security.set) {
75497             throw new WebAPIException(errorcode.PERMISSION_DENIED);
75498         }
75499
75500         t.Vehicle("set", arguments);
75501
75502         if (_vehicleCacheData.supported.indexOf(property) === -1) {
75503             throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
75504         }
75505
75506         window.setTimeout(function () {
75507             event.once("vehicle-set-response", function (status) {
75508                 if (!status) {
75509                     if (errorCallback) {
75510                         errorCallback(new WebAPIError(errorcode.PROPERTY_UNAVAILABLE));
75511                     }
75512                     else {
75513                         throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
75514                     }
75515                 }
75516             });
75517             event.trigger("vehicle-set-request", [property, val]);
75518         }, 1);
75519     }
75520
75521     function getHistory (property, zone, startTime, endTime, successCallback, errorCallback) {
75522         var properties = [], i;
75523
75524         if (!_security.getHistory) {
75525             throw new WebAPIException(errorcode.PERMISSION_DENIED);
75526         }
75527
75528         t.Vehicle("getHistory", arguments);
75529
75530         if (_vehicleCacheData.supported.indexOf(property) === -1) {
75531             throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
75532         }
75533
75534         startTime = startTime.getTime();
75535         endTime = endTime.getTime();
75536
75537         window.setTimeout(function () {
75538             event.once("vehicle-history-response", function (values, status) {
75539                 if (status) {
75540                     for (i = 0; i < values.length; i++) {
75541                         properties.push(new VehicleFactory(property, values[i]));
75542                     }
75543                     successCallback(properties);
75544                 }
75545                 else {
75546                     if (errorCallback) {
75547                         errorCallback(new WebAPIError(errorcode.PROPERTY_UNAVAILABLE));
75548                     }
75549                     else {
75550                         throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
75551                     }
75552                 }
75553             });
75554             event.trigger("vehicle-history-request", [property, zone, startTime, endTime]);
75555         }, 1);
75556     }
75557
75558     function listZones (property) {
75559         if (!_security.listZones) {
75560             throw new WebAPIException(errorcode.PERMISSION_DENIED);
75561         }
75562
75563         t.Vehicle("listZones", arguments);
75564
75565         return [0];
75566     }
75567
75568     function handleSubFeatures (subFeatures) {
75569         var i, subFeature;
75570
75571         for (subFeature in subFeatures) {
75572             for (i in _security[subFeature]) {
75573                 _security[_security[subFeature][i]] = true;
75574             }
75575         }
75576     }
75577
75578     vehicle = {
75579         supported: supported,
75580         get: get,
75581         subscribe: subscribe,
75582         set: set,
75583         getHistory: getHistory,
75584         listZones: listZones,
75585         handleSubFeatures: handleSubFeatures
75586     };
75587
75588     vehicle.__defineGetter__("ZONE_None", function () {
75589         return 0;
75590     });
75591
75592     vehicle.__defineGetter__("ZONE_Front", function () {
75593         return 0x01;
75594     });
75595
75596     vehicle.__defineGetter__("ZONE_Middle", function () {
75597         return 0x02;
75598     });
75599
75600     vehicle.__defineGetter__("ZONE_Right", function () {
75601         return 0x04;
75602     });
75603
75604     vehicle.__defineGetter__("ZONE_Left", function () {
75605         return 0x08;
75606     });
75607
75608     vehicle.__defineGetter__("ZONE_Rear", function () {
75609         return 0x10;
75610     });
75611
75612     vehicle.__defineGetter__("ZONE_Center", function () {
75613         return 0x20;
75614     });
75615
75616     return vehicle;
75617 };
75618
75619 VehicleFactory = function (vehicleType, value) {
75620     var instanceType;
75621
75622     switch (vehicleType) {
75623     case "VehicleSpeed":
75624         instanceType = new VehicleSpeed(value);
75625         break;
75626     case "EngineSpeed":
75627         instanceType = new EngineSpeed(value);
75628         break;
75629     case "VehiclePowerMode":
75630         instanceType = new VehiclePowerMode(value);
75631         break;
75632     case "TripMeter":
75633         instanceType = new TripMeter(value);
75634         break;
75635     case "Acceleration":
75636         instanceType = new Acceleration(value);
75637         break;
75638     case "Transmission":
75639         instanceType = new Transmission(value);
75640         break;
75641     case "CruiseControlStatus":
75642         instanceType = new CruiseControlStatus(value);
75643         break;
75644     case "WheelBrake":
75645         instanceType = new WheelBrake(value);
75646         break;
75647     case "LightStatus":
75648         instanceType = new LightStatus(value);
75649         break;
75650     case "InteriorLightStatus":
75651         instanceType = new InteriorLightStatus(value);
75652         break;
75653     case "Horn":
75654         instanceType = new Horn(value);
75655         break;
75656     case "Fuel":
75657         instanceType = new Fuel(value);
75658         break;
75659     case "EngineOil":
75660         instanceType = new EngineOil(value);
75661         break;
75662     case "Location":
75663         instanceType = new Location(value);
75664         break;
75665     case "ExteriorBrightness":
75666         instanceType = new ExteriorBrightness(value);
75667         break;
75668     case "Temperature":
75669         instanceType = new Temperature(value);
75670         break;
75671     case "RainSensor":
75672         instanceType = new RainSensor(value);
75673         break;
75674     case "WindshieldWiper":
75675         instanceType = new WindshieldWiper(value);
75676         break;
75677     case "HVAC":
75678         instanceType = new HVAC(value);
75679         break;
75680     case "WindowStatus":
75681         instanceType = new WindowStatus(value);
75682         break;
75683     case "Sunroof":
75684         instanceType = new Sunroof(value);
75685         break;
75686     case "ConvertibleRoof":
75687         instanceType = new ConvertibleRoof(value);
75688         break;
75689     case "VehicleId":
75690         instanceType = new VehicleId(value);
75691         break;
75692     case "Size":
75693         instanceType = new Size(value);
75694         break;
75695     case "FuelInfo":
75696         instanceType = new FuelInfo(value);
75697         break;
75698     case "VehicleType":
75699         instanceType = new VehicleType(value);
75700         break;
75701     case "Doors":
75702         instanceType = new Doors(value);
75703         break;
75704     case "TransmissionGearType":
75705         instanceType = new TransmissionGearType(value);
75706         break;
75707     case "WheelInformation":
75708         instanceType = new WheelInformation(value);
75709         break;
75710     case "Odometer":
75711         instanceType = new Odometer(value);
75712         break;
75713     case "Fluid":
75714         instanceType = new Fluid(value);
75715         break;
75716     case "Battery":
75717         instanceType = new Battery(value);
75718         break;
75719     case "TirePressure":
75720         instanceType = new TirePressure(value);
75721         break;
75722     case "TireTemperature":
75723         instanceType = new TireTemperature(value);
75724         break;
75725     case "SecurityAlert":
75726         instanceType = new SecurityAlert(value);
75727         break;
75728     case "ParkingBrake":
75729         instanceType = new ParkingBrake(value);
75730         break;
75731     case "ParkingLight":
75732         instanceType = new ParkingLight(value);
75733         break;
75734     case "HazardLight":
75735         instanceType = new HazardLight(value);
75736         break;
75737     case "AntilockBrakingSystem":
75738         instanceType = new AntilockBrakingSystem(value);
75739         break;
75740     case "TractionControlSystem":
75741         instanceType = new TractionControlSystem(value);
75742         break;
75743     case "VehicleTopSpeedLimit":
75744         instanceType = new VehicleTopSpeedLimit(value);
75745         break;
75746     case "AirbagStatus":
75747         instanceType = new AirbagStatus(value);
75748         break;
75749     case "DoorStatus":
75750         instanceType = new DoorStatus(value);
75751         break;
75752     case "SeatBeltStatus":
75753         instanceType = new SeatBeltStatus(value);
75754         break;
75755     case "OccupantStatus":
75756         instanceType = new OccupantStatus(value);
75757         break;
75758     case "ObstacleDistance":
75759         instanceType = new ObstacleDistance(value);
75760         break;
75761     case "NightMode":
75762         instanceType = new NightMode(value);
75763         break;
75764     case "DrivingMode":
75765         instanceType = new DrivingMode(value);
75766         break;
75767     case "TurnSignal":
75768         instanceType = new TurnSignal(value);
75769         break;
75770     case "ButtonEvent":
75771         instanceType = new ButtonEvent(value);
75772         break;
75773     }
75774
75775     function _construct () {
75776         var val;
75777
75778         for (val in value) {
75779             instanceType[val] = value[val];
75780         }
75781         return instanceType;
75782     }
75783
75784     return _construct();
75785 };
75786
75787 VehiclePropertyType = function (propertyTypes) {
75788     var vehiclePropertyType = {};
75789
75790     vehiclePropertyType.time = propertyTypes.time || undefined;
75791     vehiclePropertyType.zone = propertyTypes.zone || 0;
75792     vehiclePropertyType.source = propertyTypes.source || "";
75793
75794     this.__defineGetter__("time", function () {
75795         return vehiclePropertyType.time;
75796     });
75797
75798     this.__defineSetter__("time", function (val) {
75799         try {
75800             vehiclePropertyType.time = t.unsigned_long_long(val);
75801         }
75802         catch (err) {
75803         }
75804     });
75805
75806     this.__defineGetter__("zone", function () {
75807         return vehiclePropertyType.zone;
75808     });
75809
75810     this.__defineSetter__("zone", function (val) {
75811         try {
75812             vehiclePropertyType.zone = t.short(val);
75813         }
75814         catch (err) {
75815         }
75816     });
75817
75818     this.__defineGetter__("source", function () {
75819         return vehiclePropertyType.source;
75820     });
75821
75822     this.__defineSetter__("source", function (val) {
75823         try {
75824             vehiclePropertyType.source = t.DOMString(val);
75825         }
75826         catch (err) {
75827         }
75828     });
75829 };
75830
75831 VehicleSpeed = function (propertyTypes) {
75832     var vehicleSpeed = {};
75833
75834     VehiclePropertyType.call(this, propertyTypes);
75835
75836     vehicleSpeed.vehicleSpeed = propertyTypes.vehicleSpeed || 0;
75837
75838     this.__defineGetter__("vehicleSpeed", function () {
75839         return vehicleSpeed.vehicleSpeed;
75840     });
75841
75842     this.__defineSetter__("vehicleSpeed", function (val) {
75843         try {
75844             vehicleSpeed.vehicleSpeed = t.unsigned_long(val);
75845         }
75846         catch (err) {
75847         }
75848     });
75849 };
75850
75851 EngineSpeed = function (propertyTypes) {
75852     var engineSpeed = {};
75853
75854     VehiclePropertyType.call(this, propertyTypes);
75855
75856     engineSpeed.engineSpeed = propertyTypes.engineSpeed || 0;
75857
75858     this.__defineGetter__("engineSpeed", function () {
75859         return engineSpeed.engineSpeed;
75860     });
75861
75862     this.__defineSetter__("engineSpeed", function (val) {
75863         try {
75864             engineSpeed.engineSpeed = t.unsigned_long(val);
75865         }
75866         catch (err) {
75867         }
75868     });
75869 };
75870
75871 VehiclePowerMode = function (propertyTypes) {
75872     var vehiclePowerMode = {};
75873
75874     VehiclePropertyType.call(this, propertyTypes);
75875
75876     vehiclePowerMode.vehiclePowerMode = propertyTypes.vehiclePowerMode || 0;
75877
75878     this.__defineGetter__("VEHICLEPOWERMODE_OFF", function () {
75879         return 0;
75880     });
75881
75882     this.__defineGetter__("VEHICLEPOWERMODE_ACCESSORY1", function () {
75883         return 1;
75884     });
75885
75886     this.__defineGetter__("VEHICLEPOWERMODE_ACCESSORY2", function () {
75887         return 2;
75888     });
75889
75890     this.__defineGetter__("VEHICLEPOWERMODE_RUN", function () {
75891         return 3;
75892     });
75893
75894     this.__defineGetter__("vehiclePowerMode", function () {
75895         return vehiclePowerMode.vehiclePowerMode;
75896     });
75897
75898     this.__defineSetter__("vehiclePowerMode", function (val) {
75899         try {
75900             val = t.octet(val);
75901             if (val < 0 || val > 3) {
75902                 return;
75903             }
75904             vehiclePowerMode.vehiclePowerMode = val;
75905         }
75906         catch (err) {
75907         }
75908     });
75909 };
75910
75911 TripMeter = function (propertyTypes) {
75912     var tripMeter = {};
75913
75914     VehiclePropertyType.call(this, propertyTypes);
75915
75916     tripMeter.tripMeters = propertyTypes.tripMeters || [];
75917
75918     this.__defineGetter__("tripMeters", function () {
75919         return tripMeter.tripMeters;
75920     });
75921
75922     this.__defineSetter__("tripMeters", function (val) {
75923         try {
75924         //Changing any items in the array will reset the item's value to '0';
75925             tripMeter.tripMeters = t.unsigned_long(val, "[]");
75926         }
75927         catch (err) {
75928         }
75929     });
75930 };
75931
75932 Acceleration = function (propertyTypes) {
75933     var acceleration = {};
75934
75935     VehiclePropertyType.call(this, propertyTypes);
75936
75937     acceleration.x = propertyTypes.x || 0;
75938     acceleration.y = propertyTypes.y || 0;
75939     acceleration.z = propertyTypes.z || 0;
75940
75941     this.__defineGetter__("x", function () {
75942         return acceleration.x;
75943     });
75944
75945     this.__defineSetter__("x", function (val) {
75946         try {
75947             acceleration.x = t.unsigned_long(val);
75948         }
75949         catch (err) {
75950         }
75951     });
75952
75953     this.__defineGetter__("y", function () {
75954         return acceleration.y;
75955     });
75956
75957     this.__defineSetter__("y", function (val) {
75958         try {
75959             acceleration.y = t.unsigned_long(val);
75960         }
75961         catch (err) {
75962         }
75963     });
75964
75965     this.__defineGetter__("z", function () {
75966         return acceleration.z;
75967     });
75968
75969     this.__defineSetter__("z", function (val) {
75970         try {
75971             acceleration.z = t.unsigned_long(val);
75972         }
75973         catch (err) {
75974         }
75975     });
75976 };
75977
75978 Transmission = function (propertyTypes) {
75979     var transmission = {};
75980
75981     VehiclePropertyType.call(this, propertyTypes);
75982
75983     transmission.gearPosition = propertyTypes.gearPosition || 0;
75984     transmission.mode = propertyTypes.mode || 0;
75985
75986     this.__defineGetter__("TRANSMISSIONPOSITION_NEUTRAL", function () {
75987         return 0;
75988     });
75989
75990     this.__defineGetter__("TRANSMISSIONPOSITION_FIRST", function () {
75991         return 1;
75992     });
75993
75994     this.__defineGetter__("TRANSMISSIONPOSITION_SECOND", function () {
75995         return 2;
75996     });
75997
75998     this.__defineGetter__("TRANSMISSIONPOSITION_THIRD", function () {
75999         return 3;
76000     });
76001
76002     this.__defineGetter__("TRANSMISSIONPOSITION_FORTH", function () {
76003         return 4;
76004     });
76005
76006     this.__defineGetter__("TRANSMISSIONPOSITION_FIFTH", function () {
76007         return 5;
76008     });
76009
76010     this.__defineGetter__("TRANSMISSIONPOSITION_SIXTH", function () {
76011         return 6;
76012     });
76013
76014     this.__defineGetter__("TRANSMISSIONPOSITION_SEVENTH", function () {
76015         return 7;
76016     });
76017
76018     this.__defineGetter__("TRANSMISSIONPOSITION_EIGHTH", function () {
76019         return 8;
76020     });
76021
76022     this.__defineGetter__("TRANSMISSIONPOSITION_NINTH", function () {
76023         return 9;
76024     });
76025
76026     this.__defineGetter__("TRANSMISSIONPOSITION_TENTH", function () {
76027         return 10;
76028     });
76029
76030     this.__defineGetter__("TRANSMISSIONPOSITION_CVT", function () {
76031         return 64;
76032     });
76033
76034     this.__defineGetter__("TRANSMISSIONPOSITION_REVERSE", function () {
76035         return 128;
76036     });
76037
76038     this.__defineGetter__("TRANSMISSIONPOSITION_PARK", function () {
76039         return 255;
76040     });
76041
76042     this.__defineGetter__("TRANSMISSIONMODE_NORMAL", function () {
76043         return 0;
76044     });
76045
76046     this.__defineGetter__("TRANSMISSIONMODE_SPORT", function () {
76047         return 1;
76048     });
76049
76050     this.__defineGetter__("TRANSMISSIONMODE_ECONOMY", function () {
76051         return 2;
76052     });
76053
76054     this.__defineGetter__("TRANSMISSIONMODE_OEMCUSTOM1", function () {
76055         return 3;
76056     });
76057
76058     this.__defineGetter__("TRANSMISSIONMODE_OEMCUSTOM2", function () {
76059         return 4;
76060     });
76061
76062     this.__defineGetter__("gearPosition", function () {
76063         return transmission.gearPosition;
76064     });
76065
76066     this.__defineSetter__("gearPosition", function (val) {
76067         try {
76068             val = t.octet(val);
76069             if ((val >= 0 && val <= 10) || val === 64 || val === 128 ||
76070                 val === 255) {
76071                 transmission.gearPosition = val;
76072             }
76073         }
76074         catch (err) {
76075         }
76076     });
76077
76078     this.__defineGetter__("mode", function () {
76079         return transmission.mode;
76080     });
76081
76082     this.__defineSetter__("mode", function (val) {
76083         try {
76084             val = t.octet(val);
76085             if (val < 0 || val > 4) {
76086                 return;
76087             }
76088             transmission.mode = val;
76089         }
76090         catch (err) {
76091         }
76092     });
76093 };
76094
76095 CruiseControlStatus = function (propertyTypes) {
76096     var cruiseControlStatus = {};
76097
76098     VehiclePropertyType.call(this, propertyTypes);
76099
76100     cruiseControlStatus.activated = propertyTypes.activated || false;
76101     cruiseControlStatus.speed = propertyTypes.speed || 0;
76102
76103     this.__defineGetter__("activated", function () {
76104         return cruiseControlStatus.activated;
76105     });
76106
76107     this.__defineSetter__("activated", function (val) {
76108         try {
76109             cruiseControlStatus.activated = t.boolean(val);
76110         }
76111         catch (err) {
76112         }
76113     });
76114
76115     this.__defineGetter__("speed", function () {
76116         return cruiseControlStatus.speed;
76117     });
76118
76119     this.__defineSetter__("speed", function (val) {
76120         try {
76121             cruiseControlStatus.speed = t.unsigned_short(val);
76122         }
76123         catch (err) {
76124         }
76125     });
76126 };
76127
76128 WheelBrake = function (propertyTypes) {
76129     var wheelBrake = {};
76130
76131     VehiclePropertyType.call(this, propertyTypes);
76132
76133     wheelBrake.engaged = propertyTypes.engaged || false;
76134
76135     this.__defineGetter__("engaged", function () {
76136         return wheelBrake.engaged;
76137     });
76138
76139     this.__defineSetter__("engaged", function (val) {
76140         try {
76141             wheelBrake.engaged = t.boolean(val);
76142         }
76143         catch (err) {
76144         }
76145     });
76146 };
76147
76148 LightStatus = function (propertyTypes) {
76149     var lightStatus = {};
76150
76151     VehiclePropertyType.call(this, propertyTypes);
76152
76153     lightStatus.head = propertyTypes.head || false;
76154     lightStatus.rightTurn = propertyTypes.rightTurn || false;
76155     lightStatus.leftTurn = propertyTypes.leftTurn || false;
76156     lightStatus.brake = propertyTypes.brake || false;
76157     lightStatus.fog = propertyTypes.fog || false;
76158     lightStatus.hazard = propertyTypes.hazard || false;
76159     lightStatus.parking = propertyTypes.parking || false;
76160     lightStatus.highBeam = propertyTypes.highBeam || false;
76161
76162     this.__defineGetter__("head", function () {
76163         return lightStatus.head;
76164     });
76165
76166     this.__defineSetter__("head", function (val) {
76167         try {
76168             lightStatus.head = t.boolean(val);
76169         }
76170         catch (err) {
76171         }
76172     });
76173
76174     this.__defineGetter__("rightTurn", function () {
76175         return lightStatus.rightTurn;
76176     });
76177
76178     this.__defineSetter__("rightTurn", function (val) {
76179         try {
76180             lightStatus.rightTurn = t.boolean(val);
76181         }
76182         catch (err) {
76183         }
76184     });
76185
76186     this.__defineGetter__("leftTurn", function () {
76187         return lightStatus.leftTurn;
76188     });
76189
76190     this.__defineSetter__("leftTurn", function (val) {
76191         try {
76192             lightStatus.leftTurn = t.boolean(val);
76193         }
76194         catch (err) {
76195         }
76196     });
76197
76198     this.__defineGetter__("brake", function () {
76199         return lightStatus.brake;
76200     });
76201
76202     this.__defineSetter__("brake", function (val) {
76203         try {
76204             lightStatus.brake = t.boolean(val);
76205         }
76206         catch (err) {
76207         }
76208     });
76209
76210     this.__defineGetter__("fog", function () {
76211         return lightStatus.fog;
76212     });
76213
76214     this.__defineSetter__("fog", function (val) {
76215         try {
76216             lightStatus.fog = t.boolean(val);
76217         }
76218         catch (err) {
76219         }
76220     });
76221
76222     this.__defineGetter__("hazard", function () {
76223         return lightStatus.hazard;
76224     });
76225
76226     this.__defineSetter__("hazard", function (val) {
76227         try {
76228             lightStatus.hazard = t.boolean(val);
76229         }
76230         catch (err) {
76231         }
76232     });
76233
76234     this.__defineGetter__("parking", function () {
76235         return lightStatus.parking;
76236     });
76237
76238     this.__defineSetter__("parking", function (val) {
76239         try {
76240             lightStatus.parking = t.boolean(val);
76241         }
76242         catch (err) {
76243         }
76244     });
76245
76246     this.__defineGetter__("highBeam", function () {
76247         return lightStatus.highBeam;
76248     });
76249
76250     this.__defineSetter__("highBeam", function (val) {
76251         try {
76252             lightStatus.highBeam = t.boolean(val);
76253         }
76254         catch (err) {
76255         }
76256     });
76257 };
76258
76259 InteriorLightStatus = function (propertyTypes) {
76260     var interiorLightStatus = {};
76261
76262     VehiclePropertyType.call(this, propertyTypes);
76263
76264     interiorLightStatus.passenger = propertyTypes.passenger || false;
76265     interiorLightStatus.driver = propertyTypes.driver || false;
76266     interiorLightStatus.center = propertyTypes.center || false;
76267
76268     this.__defineGetter__("passenger", function () {
76269         return interiorLightStatus.passenger;
76270     });
76271
76272     this.__defineSetter__("passenger", function (val) {
76273         try {
76274             interiorLightStatus.passenger = t.boolean(val);
76275         }
76276         catch (err) {
76277         }
76278     });
76279
76280     this.__defineGetter__("driver", function () {
76281         return interiorLightStatus.driver;
76282     });
76283
76284     this.__defineSetter__("driver", function (val) {
76285         try {
76286             interiorLightStatus.driver = t.boolean(val);
76287         }
76288         catch (err) {
76289         }
76290     });
76291
76292     this.__defineGetter__("center", function () {
76293         return interiorLightStatus.center;
76294     });
76295
76296     this.__defineSetter__("center", function (val) {
76297         try {
76298             interiorLightStatus.center = t.boolean(val);
76299         }
76300         catch (err) {
76301         }
76302     });
76303 };
76304
76305 Horn = function (propertyTypes) {
76306     var horn = {};
76307
76308     VehiclePropertyType.call(this, propertyTypes);
76309
76310     horn.on = propertyTypes.on || false;
76311
76312     this.__defineGetter__("on", function () {
76313         return horn.on;
76314     });
76315
76316     this.__defineSetter__("on", function (val) {
76317         try {
76318             horn.on = t.boolean(val);
76319         }
76320         catch (err) {
76321         }
76322     });
76323 };
76324
76325 Fuel = function (propertyTypes) {
76326     var fuel = {};
76327
76328     VehiclePropertyType.call(this, propertyTypes);
76329
76330     fuel.level = propertyTypes.level || 0;
76331     fuel.range = propertyTypes.range || 0;
76332     fuel.instantConsumption = propertyTypes.instantConsumption || 0;
76333     fuel.instantEconomy = propertyTypes.instantEconomy || 0;
76334     fuel.averageEconomy = propertyTypes.averageEconomy || 0;
76335
76336     this.__defineGetter__("level", function () {
76337         return fuel.level;
76338     });
76339
76340     this.__defineSetter__("level", function (val) {
76341         try {
76342             fuel.level = t.unsigned_short(val);
76343         }
76344         catch (err) {
76345         }
76346     });
76347
76348     this.__defineGetter__("range", function () {
76349         return fuel.range;
76350     });
76351
76352     this.__defineSetter__("range", function (val) {
76353         try {
76354             fuel.range = t.unsigned_short(val);
76355         }
76356         catch (err) {
76357         }
76358     });
76359
76360     this.__defineGetter__("instantConsumption", function () {
76361         return fuel.instantConsumption;
76362     });
76363
76364     this.__defineSetter__("instantConsumption", function (val) {
76365         try {
76366             fuel.instantConsumption = t.unsigned_short(val);
76367         }
76368         catch (err) {
76369         }
76370     });
76371
76372     this.__defineGetter__("instantEconomy", function () {
76373         return fuel.instantEconomy;
76374     });
76375
76376     this.__defineSetter__("instantEconomy", function (val) {
76377         try {
76378             fuel.instantEconomy = t.unsigned_short(val);
76379         }
76380         catch (err) {
76381         }
76382     });
76383
76384     this.__defineGetter__("averageEconomy", function () {
76385         return fuel.averageEconomy;
76386     });
76387
76388     this.__defineSetter__("averageEconomy", function (val) {
76389         try {
76390             //Setting this to any value should reset the counter to '0'
76391             fuel.averageEconomy = t.unsigned_short(val);
76392         }
76393         catch (err) {
76394         }
76395     });
76396 };
76397
76398 EngineOil = function (propertyTypes) {
76399     var engineOil = {};
76400
76401     VehiclePropertyType.call(this, propertyTypes);
76402
76403     engineOil.remaining = propertyTypes.remaining || 0;
76404     engineOil.temperature = propertyTypes.temperature || 0;
76405     engineOil.pressure = propertyTypes.Pressure || 0;
76406
76407     this.__defineGetter__("remaining", function () {
76408         return engineOil.remaining;
76409     });
76410
76411     this.__defineSetter__("remaining", function (val) {
76412         try {
76413             engineOil.remaining = t.unsigned_short(val);
76414         }
76415         catch (err) {
76416         }
76417     });
76418
76419     this.__defineGetter__("temperature", function () {
76420         return engineOil.temperature;
76421     });
76422
76423     this.__defineSetter__("temperature", function (val) {
76424         try {
76425             engineOil.temperature = t.long(val);
76426         }
76427         catch (err) {
76428         }
76429     });
76430
76431     this.__defineGetter__("pressure", function () {
76432         return engineOil.pressure;
76433     });
76434
76435     this.__defineSetter__("pressure", function (val) {
76436         try {
76437             engineOil.pressure = t.unsigned_short(val);
76438         }
76439         catch (err) {
76440         }
76441     });
76442 };
76443
76444 Location = function (propertyTypes) {
76445     var location = {};
76446
76447     VehiclePropertyType.call(this, propertyTypes);
76448
76449     location.latitude = propertyTypes.latitude || 0;
76450     location.longitude = propertyTypes.longitude || 0;
76451     location.altitude = propertyTypes.altitude || 0;
76452     location.direction = propertyTypes.direction || 0;
76453
76454     this.__defineGetter__("latitude", function () {
76455         return location.latitude;
76456     });
76457
76458     this.__defineSetter__("latitude", function (val) {
76459         try {
76460             val = t.double(val);
76461             if (val >= -180 && val <= 180) {
76462                 location.latitude = val;
76463             }
76464         }
76465         catch (err) {
76466         }
76467     });
76468
76469     this.__defineGetter__("longitude", function () {
76470         return location.longitude;
76471     });
76472
76473     this.__defineSetter__("longitude", function (val) {
76474         try {
76475             val = t.double(val);
76476             if (val >= -90 && val <= 90) {
76477                 location.longitude = val;
76478             }
76479         }
76480         catch (err) {
76481         }
76482     });
76483
76484     this.__defineGetter__("altitude", function () {
76485         return location.altitude;
76486     });
76487
76488     this.__defineSetter__("altitude", function (val) {
76489         try {
76490             val = t.double(val);
76491             if (val >= 0) {
76492                 location.altitude = val;
76493             }
76494         }
76495         catch (err) {
76496         }
76497     });
76498
76499     this.__defineGetter__("direction", function () {
76500         return location.direction;
76501     });
76502
76503     this.__defineSetter__("direction", function (val) {
76504         try {
76505             val = t.unsigned_short(val);
76506             if (val >= 0 && val < 360) {
76507                 location.direction = val;
76508             }
76509         }
76510         catch (err) {
76511         }
76512     });
76513 };
76514
76515 ExteriorBrightness = function (propertyTypes) {
76516     var eb = {};
76517
76518     VehiclePropertyType.call(this, propertyTypes);
76519
76520     eb.exteriorBrightness = propertyTypes.exteriorBrightness || 0;
76521
76522     this.__defineGetter__("exteriorBrightness", function () {
76523         return eb.exteriorBrightness;
76524     });
76525
76526     this.__defineSetter__("exteriorBrightness", function (val) {
76527         try {
76528             eb.exteriorBrightness = t.unsigned_long(val);
76529         }
76530         catch (err) {
76531         }
76532     });
76533 };
76534
76535 Temperature = function (propertyTypes) {
76536     var temperature = {};
76537
76538     VehiclePropertyType.call(this, propertyTypes);
76539
76540     temperature.interior = propertyTypes.interior || 0;
76541     temperature.exterior = propertyTypes.exterior || 0;
76542
76543     this.__defineGetter__("interior", function () {
76544         return temperature.interior;
76545     });
76546
76547     this.__defineSetter__("interior", function (val) {
76548         try {
76549             temperature.interior = t.short(val);
76550         }
76551         catch (err) {
76552         }
76553     });
76554
76555     this.__defineGetter__("exterior", function () {
76556         return temperature.exterior;
76557     });
76558
76559     this.__defineSetter__("exterior", function (val) {
76560         try {
76561             temperature.exterior = t.short(val);
76562         }
76563         catch (err) {
76564         }
76565     });
76566 };
76567
76568 RainSensor = function (propertyTypes) {
76569     var rainSensor = {};
76570
76571     VehiclePropertyType.call(this, propertyTypes);
76572
76573     rainSensor.rainSensor = propertyTypes.rainSensor || 0;
76574
76575     this.__defineGetter__("rainSensor", function () {
76576         return rainSensor.rainSensor;
76577     });
76578
76579     this.__defineSetter__("rainSensor", function (val) {
76580         try {
76581             val = t.unsigned_short(val);
76582             if (val >= 0 && val <= 10) {
76583                 rainSensor.rainSensor = val;
76584             }
76585         }
76586         catch (err) {
76587         }
76588     });
76589 };
76590
76591 WindshieldWiper = function (propertyTypes) {
76592     var windshieldWiper = {};
76593
76594     VehiclePropertyType.call(this, propertyTypes);
76595
76596     windshieldWiper.windshieldWiper = propertyTypes.windshieldWiper || 0;
76597
76598     this.__defineGetter__("WIPERSPEED_OFF", function () {
76599         return 0;
76600     });
76601
76602     this.__defineGetter__("WIPERSPEED_SLOWEST", function () {
76603         return 1;
76604     });
76605
76606     this.__defineGetter__("WIPERSPEED_FASTEST", function () {
76607         return 5;
76608     });
76609
76610     this.__defineGetter__("WIPERSPEED_AUTO", function () {
76611         return 10;
76612     });
76613
76614     this.__defineGetter__("windshieldWiper", function () {
76615         return windshieldWiper.windshieldWiper;
76616     });
76617
76618     this.__defineSetter__("windshieldWiper", function (val) {
76619         try {
76620             val = t.unsigned_short(val);
76621             if (val === 0 || val === 1 || val === 5 || val === 10) {
76622                 windshieldWiper.windshieldWiper = val;
76623             }
76624         }
76625         catch (err) {
76626         }
76627     });
76628 };
76629
76630 HVAC = function (propertyTypes) {
76631     var hvac = {};
76632
76633     VehiclePropertyType.call(this, propertyTypes);
76634
76635     hvac.airflowDirection = propertyTypes.airflowDirection || 0;
76636     hvac.fanSpeed = propertyTypes.fanSpeed || 0;
76637     hvac.targetTemperature = propertyTypes.targetTemperature || 0;
76638     hvac.airConditioning = propertyTypes.airConditioning || false;
76639     hvac.airRecirculation = propertyTypes.airRecirculation || false;
76640     hvac.heater = propertyTypes.heater || false;
76641     hvac.steeringWheelHeater = propertyTypes.steeringWheelHeater || false;
76642     hvac.seatHeater = propertyTypes.seatHeater || false;
76643     hvac.seatCooler = propertyTypes.seatCooler || false;
76644
76645     this.__defineGetter__("AIRFLOWDIRECTION_FRONTPANEL", function () {
76646         return 0;
76647     });
76648
76649     this.__defineGetter__("AIRFLOWDIRECTION_FLOORDUCT", function () {
76650         return 1;
76651     });
76652
76653     this.__defineGetter__("AIRFLOWDIRECTION_FRONT", function () {
76654         return 0x02;
76655     });
76656
76657     this.__defineGetter__("AIRFLOWDIRECTION_DEFROSTER", function () {
76658         return 0x04;
76659     });
76660
76661     this.__defineGetter__("airflowDirection", function () {
76662         return hvac.airflowDirection;
76663     });
76664
76665     this.__defineSetter__("airflowDirection", function (val) {
76666         try {
76667             val = t.unsigned_short(val);
76668             if (val === 0 || val === 1 || val === 0x02 || val === 0x04) {
76669                 hvac.airflowDirection = val;
76670             }
76671         }
76672         catch (err) {
76673         }
76674     });
76675
76676     this.__defineGetter__("fanSpeed", function () {
76677         return hvac.fanSpeed;
76678     });
76679
76680     this.__defineSetter__("fanSpeed", function (val) {
76681         try {
76682             val = t.unsigned_short(val);
76683             if (val >= 0 && val <= 7) {
76684                 hvac.fanSpeed = val;
76685             }
76686         }
76687         catch (err) {
76688         }
76689     });
76690
76691     this.__defineGetter__("targetTemperature", function () {
76692         return hvac.targetTemperature;
76693     });
76694
76695     this.__defineSetter__("targetTemperature", function (val) {
76696         try {
76697             hvac.targetTemperature = t.unsigned_short(val);
76698         }
76699         catch (err) {
76700         }
76701     });
76702
76703     this.__defineGetter__("airConditioning", function () {
76704         return hvac.airConditioning;
76705     });
76706
76707     this.__defineSetter__("airConditioning", function (val) {
76708         try {
76709             hvac.airConditioning = t.boolean(val);
76710         }
76711         catch (err) {
76712         }
76713     });
76714
76715     this.__defineGetter__("airRecirculation", function () {
76716         return hvac.airRecirculation;
76717     });
76718
76719     this.__defineSetter__("airRecirculation", function (val) {
76720         try {
76721             hvac.airRecirculation = t.boolean(val);
76722         }
76723         catch (err) {
76724         }
76725     });
76726
76727     this.__defineGetter__("heater", function () {
76728         return hvac.heater;
76729     });
76730
76731     this.__defineSetter__("heater", function (val) {
76732         try {
76733             hvac.heater = t.boolean(val);
76734         }
76735         catch (err) {
76736         }
76737     });
76738
76739     this.__defineGetter__("steeringWheelHeater", function () {
76740         return hvac.steeringWheelHeater;
76741     });
76742
76743     this.__defineSetter__("steeringWheelHeater", function (val) {
76744         try {
76745             hvac.steeringWheelHeater = t.boolean(val);
76746         }
76747         catch (err) {
76748         }
76749     });
76750
76751     this.__defineGetter__("seatHeater", function () {
76752         return hvac.seatHeater;
76753     });
76754
76755     this.__defineSetter__("seatHeater", function (val) {
76756         try {
76757             hvac.seatHeater = t.boolean(val);
76758         }
76759         catch (err) {
76760         }
76761     });
76762
76763     this.__defineGetter__("seatCooler", function () {
76764         return hvac.seatCooler;
76765     });
76766
76767     this.__defineSetter__("seatCooler", function (val) {
76768         try {
76769             hvac.seatCooler = t.boolean(val);
76770         }
76771         catch (err) {
76772         }
76773     });
76774 };
76775
76776 WindowStatus = function (propertyTypes) {
76777     var windowStatus = {};
76778
76779     VehiclePropertyType.call(this, propertyTypes);
76780
76781     windowStatus.openness = propertyTypes.openness || 0;
76782     windowStatus.defrost = propertyTypes.defrost || false;
76783
76784     this.__defineGetter__("WINDOWLOCATION_DRIVER", function () {
76785         return 0;
76786     });
76787
76788     this.__defineGetter__("WINDOWLOCATION_PASSENGER", function () {
76789         return 1;
76790     });
76791
76792     this.__defineGetter__("WINDOWLOCATION_LEFTREAR", function () {
76793         return 2;
76794     });
76795
76796     this.__defineGetter__("WINDOWLOCATION_RIGHTREAR", function () {
76797         return 3;
76798     });
76799
76800     this.__defineGetter__("WINDOWLOCATION_REAR", function () {
76801         return 4;
76802     });
76803
76804     this.__defineGetter__("openness", function () {
76805         return windowStatus.openness;
76806     });
76807
76808     this.__defineSetter__("openness", function (val) {
76809         try {
76810             val = t.unsigned_short(val);
76811             if (val >= 0 && val <= 100) {
76812                 windowStatus.openness = val;
76813             }
76814         }
76815         catch (err) {
76816         }
76817     });
76818
76819     this.__defineGetter__("defrost", function () {
76820         return windowStatus.defrost;
76821     });
76822
76823     this.__defineSetter__("defrost", function (val) {
76824         try {
76825             windowStatus.defrost = t.boolean(val);
76826         }
76827         catch (err) {
76828         }
76829     });
76830 };
76831
76832 Sunroof = function (propertyTypes) {
76833     var sunroof = {};
76834
76835     VehiclePropertyType.call(this, propertyTypes);
76836
76837     sunroof.openness = propertyTypes.openness || 0;
76838     sunroof.tilt = propertyTypes.tilt || 0;
76839
76840     this.__defineGetter__("openness", function () {
76841         return sunroof.openness;
76842     });
76843
76844     this.__defineSetter__("openness", function (val) {
76845         try {
76846             sunroof.openness = t.unsigned_short(val);
76847         }
76848         catch (err) {
76849         }
76850     });
76851
76852     this.__defineGetter__("tilt", function () {
76853         return sunroof.tilt;
76854     });
76855
76856     this.__defineSetter__("tilt", function (val) {
76857         try {
76858             sunroof.tilt = t.unsigned_short(val);
76859         }
76860         catch (err) {
76861         }
76862     });
76863 };
76864
76865 ConvertibleRoof = function (propertyTypes) {
76866     var convertibleRoof = {};
76867
76868     VehiclePropertyType.call(this, propertyTypes);
76869
76870     convertibleRoof.openness = propertyTypes.openness || 0;
76871
76872     this.__defineGetter__("openness", function () {
76873         return convertibleRoof.openness;
76874     });
76875
76876     this.__defineSetter__("openness", function (val) {
76877         try {
76878             convertibleRoof.openness = t.unsigned_short(val);
76879         }
76880         catch (err) {
76881         }
76882     });
76883 };
76884
76885 VehicleId = function (propertyTypes) {
76886     var vehicleId = {};
76887
76888     VehiclePropertyType.call(this, propertyTypes);
76889
76890     vehicleId.WMI = propertyTypes.WMI || "";
76891     vehicleId.VIN = propertyTypes.VIN || "";
76892
76893     this.__defineGetter__("WMI", function () {
76894         return vehicleId.WMI;
76895     });
76896
76897     this.__defineSetter__("WMI", function (val) {
76898         try {
76899             //?
76900             vehicleId.WMI = t.DOMString(val);
76901         }
76902         catch (err) {
76903         }
76904     });
76905
76906     this.__defineGetter__("VIN", function () {
76907         return vehicleId.VIN;
76908     });
76909
76910     this.__defineSetter__("VIN", function (val) {
76911         try {
76912             //?
76913             vehicleId.VIN = t.DOMString(val);
76914         }
76915         catch (err) {
76916         }
76917     });
76918 };
76919
76920 Size = function (propertyTypes) {
76921     var size = {};
76922
76923     VehiclePropertyType.call(this, propertyTypes);
76924
76925     size.width = propertyTypes.width || 0;
76926     size.height = propertyTypes.height || 0;
76927     size.length = propertyTypes.length || 0;
76928
76929     this.__defineGetter__("width", function () {
76930         return size.width;
76931     });
76932
76933     this.__defineSetter__("width", function (val) {
76934         try {
76935             size.width = t.unsigned_long(val);
76936         }
76937         catch (err) {
76938         }
76939     });
76940
76941     this.__defineGetter__("height", function () {
76942         return size.height;
76943     });
76944
76945     this.__defineSetter__("height", function (val) {
76946         try {
76947             size.height = t.unsigned_long(val);
76948         }
76949         catch (err) {
76950         }
76951     });
76952
76953     this.__defineGetter__("length", function () {
76954         return size.length;
76955     });
76956
76957     this.__defineSetter__("length", function (val) {
76958         try {
76959             size.length = t.unsigned_long(val);
76960         }
76961         catch (err) {
76962         }
76963     });
76964 };
76965
76966 FuelInfo = function (propertyTypes) {
76967     var fuelInfo = {};
76968
76969     VehiclePropertyType.call(this, propertyTypes);
76970
76971     fuelInfo.type = propertyTypes.type || 0;
76972     fuelInfo.refuelPosition = propertyTypes.refuelPosition || 0;
76973
76974     this.__defineGetter__("FUELTYPE_GASOLINE", function () {
76975         return 0;
76976     });
76977
76978     this.__defineGetter__("FUELTYPE_HIGH_OCTANE", function () {
76979         return 1;
76980     });
76981
76982     this.__defineGetter__("FUELTYPE_DIESEL", function () {
76983         return 2;
76984     });
76985
76986     this.__defineGetter__("FUELTYPE_ELECTRIC", function () {
76987         return 3;
76988     });
76989
76990     this.__defineGetter__("FUELTYPE_HYDROGEN", function () {
76991         return 4;
76992     });
76993
76994     this.__defineGetter__("REFUELPOSITION_LEFT", function () {
76995         return 0;
76996     });
76997
76998     this.__defineGetter__("REFUELPOSITION_RIGHT", function () {
76999         return 1;
77000     });
77001
77002     this.__defineGetter__("REFUELPOSITION_FRONT", function () {
77003         return 2;
77004     });
77005
77006     this.__defineGetter__("REFUELPOSITION_REAR", function () {
77007         return 3;
77008     });
77009
77010     this.__defineGetter__("type", function () {
77011         return fuelInfo.type;
77012     });
77013
77014     this.__defineSetter__("type", function (val) {
77015         try {
77016             val = t.unsigned_short(val);
77017             if (val >= 0 && val <= 4) {
77018                 fuelInfo.type = val;
77019             }
77020         }
77021         catch (err) {
77022         }
77023     });
77024
77025     this.__defineGetter__("refuelPosition", function () {
77026         return fuelInfo.refuelPosition;
77027     });
77028
77029     this.__defineSetter__("refuelPosition", function (val) {
77030         try {
77031             val = t.unsigned_short(val);
77032             if (val >= 0 && val <= 3) {
77033                 fuelInfo.refuelPosition = val;
77034             }
77035         }
77036         catch (err) {
77037         }
77038     });
77039 };
77040
77041 VehicleType = function (propertyTypes) {
77042     var vehicleType = {};
77043
77044     VehiclePropertyType.call(this, propertyTypes);
77045
77046     vehicleType.type = propertyTypes.type || 0;
77047
77048     this.__defineGetter__("VEHICLETYPE_SEDAN", function () {
77049         return 0;
77050     });
77051
77052     this.__defineGetter__("VEHICLETYPE_COUPE", function () {
77053         return 1;
77054     });
77055
77056     this.__defineGetter__("VEHICLETYPE_CABRIOLE", function () {
77057         return 2;
77058     });
77059
77060     this.__defineGetter__("VEHICLETYPE_ROADSTER", function () {
77061         return 3;
77062     });
77063
77064     this.__defineGetter__("VEHICLETYPE_SUV", function () {
77065         return 4;
77066     });
77067
77068     this.__defineGetter__("VEHICLETYPE_TRUCK", function () {
77069         return 5;
77070     });
77071
77072     this.__defineGetter__("type", function () {
77073         return vehicleType.type;
77074     });
77075
77076     this.__defineSetter__("type", function (val) {
77077         try {
77078             val = t.unsigned_short(val);
77079             if (val >= 0 && val <= 5) {
77080                 vehicleType.type = val;
77081             }
77082         }
77083         catch (err) {
77084         }
77085     });
77086 };
77087
77088 Doors = function (propertyTypes) {
77089     var doors = {};
77090
77091     VehiclePropertyType.call(this, propertyTypes);
77092
77093     doors.doorsPerRow = propertyTypes.doorsPerRow || [];
77094
77095     this.__defineGetter__("doorsPerRow", function () {
77096         return doors.doorsPerRow;
77097     });
77098
77099     this.__defineSetter__("doorsPerRow", function (val) {
77100         try {
77101             doors.doorsPerRow = t.unsigned_short(val, "[]");
77102         }
77103         catch (err) {
77104         }
77105     });
77106 };
77107
77108 TransmissionGearType = function (propertyTypes) {
77109     var trans = {};
77110
77111     VehiclePropertyType.call(this, propertyTypes);
77112
77113     trans.transmissionGearType = propertyTypes.transmissionGearType || 0;
77114
77115     this.__defineGetter__("TRANSMISSIONGEARTYPE_AUTO", function () {
77116         return 0;
77117     });
77118
77119     this.__defineGetter__("TRANSMISSIONGEARTYPE_MANUAL", function () {
77120         return 1;
77121     });
77122
77123     this.__defineGetter__("TRANSMISSIONGEARTYPE_CV", function () {
77124         return 2;
77125     });
77126
77127     this.__defineGetter__("transmissionGearType", function () {
77128         return trans.transmissionGearType;
77129     });
77130
77131     this.__defineSetter__("transmissionGearType", function (val) {
77132         try {
77133             val = t.unsigned_short(val);
77134             if (val >= 0 && val <= 2) {
77135                 trans.transmissionGearType = val;
77136             }
77137         }
77138         catch (err) {
77139         }
77140     });
77141 };
77142
77143 WheelInformation = function (propertyTypes) {
77144     var wheelInfo = {};
77145
77146     VehiclePropertyType.call(this, propertyTypes);
77147
77148     wheelInfo.frontWheelRadius = propertyTypes.frontWheelRadius || 0;
77149     wheelInfo.rearWheelRadius = propertyTypes.rearWheelRadius || 0;
77150     wheelInfo.wheelTrack = propertyTypes.wheelTrack || 0;
77151     wheelInfo.ABS = propertyTypes.ABS || false;
77152
77153     this.__defineGetter__("frontWheelRadius", function () {
77154         return wheelInfo.frontWheelRadius;
77155     });
77156
77157     this.__defineSetter__("frontWheelRadius", function (val) {
77158         try {
77159             wheelInfo.frontWheelRadius =t.unsigned_short(val);
77160         }
77161         catch (err) {
77162         }
77163     });
77164
77165     this.__defineGetter__("rearWheelRadius", function () {
77166         return wheelInfo.rearWheelRadius;
77167     });
77168
77169     this.__defineSetter__("rearWheelRadius", function (val) {
77170         try {
77171             wheelInfo.rearWheelRadius =t.unsigned_short(val);
77172         }
77173         catch (err) {
77174         }
77175     });
77176
77177     this.__defineGetter__("wheelTrack", function () {
77178         return wheelInfo.wheelTrack;
77179     });
77180
77181     this.__defineSetter__("wheelTrack", function (val) {
77182         try {
77183             wheelInfo.wheelTrack =t.unsigned_long(val);
77184         }
77185         catch (err) {
77186         }
77187     });
77188
77189     this.__defineGetter__("ABS", function () {
77190         return wheelInfo.ABS;
77191     });
77192
77193     this.__defineSetter__("ABS", function (val) {
77194         try {
77195             wheelInfo.ABS =t.boolean(val);
77196         }
77197         catch (err) {
77198         }
77199     });
77200 };
77201
77202 Odometer = function (propertyTypes) {
77203     var odm = {};
77204
77205     VehiclePropertyType.call(this, propertyTypes);
77206
77207     odm.odometer = propertyTypes.odometer || 0;
77208
77209     this.__defineGetter__("odometer", function () {
77210         return odm.odometer;
77211     });
77212
77213     this.__defineSetter__("odometer", function (val) {
77214         try {
77215             odm.odometer = t.unsigned_long(val);
77216         }
77217         catch (err) {
77218         }
77219     });
77220 };
77221
77222 Fluid = function (propertyTypes) {
77223     var fluid = {};
77224
77225     VehiclePropertyType.call(this, propertyTypes);
77226
77227     fluid.transmission = propertyTypes.transmission || 0;
77228     fluid.brake = propertyTypes.brake || 0;
77229     fluid.washer = propertyTypes.washer || 0;
77230
77231     this.__defineGetter__("transmission", function () {
77232         return fluid.transmission;
77233     });
77234
77235     this.__defineSetter__("transmission", function (val) {
77236         try {
77237             val = t.unsigned_short(val);
77238             if (val >= 0 && val <= 100) {
77239                 fluid.transmission = val;
77240             }
77241         }
77242         catch (err) {
77243         }
77244     });
77245
77246     this.__defineGetter__("brake", function () {
77247         return fluid.brake;
77248     });
77249
77250     this.__defineSetter__("brake", function (val) {
77251         try {
77252             val = t.unsigned_short(val);
77253             if (val >= 0 && val <= 100) {
77254                 fluid.brake = val;
77255             }
77256         }
77257         catch (err) {
77258         }
77259     });
77260
77261     this.__defineGetter__("washer", function () {
77262         return fluid.washer;
77263     });
77264
77265     this.__defineSetter__("washer", function (val) {
77266         try {
77267             val = t.unsigned_short(val);
77268             if (val >= 0 && val <= 100) {
77269                 fluid.washer = val;
77270             }
77271         }
77272         catch (err) {
77273         }
77274     });
77275 };
77276
77277 Battery = function (propertyTypes) {
77278     var battery = {};
77279
77280     VehiclePropertyType.call(this, propertyTypes);
77281
77282     battery.voltage = propertyTypes.voltage || 0;
77283     battery.current = propertyTypes.current || 0;
77284
77285     this.__defineGetter__("voltage", function () {
77286         return battery.voltage;
77287     });
77288
77289     this.__defineSetter__("voltage", function (val) {
77290         try {
77291             battery.voltage = t.double(val);
77292         }
77293         catch (err) {
77294         }
77295     });
77296
77297     this.__defineGetter__("current", function () {
77298         return battery.current;
77299     });
77300
77301     this.__defineSetter__("current", function (val) {
77302         try {
77303             battery.current = t.double(val);
77304         }
77305         catch (err) {
77306         }
77307     });
77308 };
77309
77310 TirePressure = function (propertyTypes) {
77311     var tirePressure = {};
77312
77313     VehiclePropertyType.call(this, propertyTypes);
77314
77315     tirePressure.leftFront = propertyTypes.leftFront || 0;
77316     tirePressure.rightFront = propertyTypes.rightFront || 0;
77317     tirePressure.leftRear = propertyTypes.leftRear || 0;
77318     tirePressure.rightRear = propertyTypes.rightRear || 0;
77319
77320     this.__defineGetter__("leftFront", function () {
77321         return tirePressure.leftFront;
77322     });
77323
77324     this.__defineSetter__("leftFront", function (val) {
77325         try {
77326             tirePressure.leftFront = t.double(val);
77327         }
77328         catch (err) {
77329         }
77330     });
77331
77332     this.__defineGetter__("rightFront", function () {
77333         return tirePressure.rightFront;
77334     });
77335
77336     this.__defineSetter__("rightFront", function (val) {
77337         try {
77338             tirePressure.rightFront = t.double(val);
77339         }
77340         catch (err) {
77341         }
77342     });
77343
77344     this.__defineGetter__("leftRear", function () {
77345         return tirePressure.leftRear;
77346     });
77347
77348     this.__defineSetter__("leftRear", function (val) {
77349         try {
77350             tirePressure.leftRear = t.double(val);
77351         }
77352         catch (err) {
77353         }
77354     });
77355
77356     this.__defineGetter__("rightRear", function () {
77357         return tirePressure.rightRear;
77358     });
77359
77360     this.__defineSetter__("rightRear", function (val) {
77361         try {
77362             tirePressure.rightRear = t.double(val);
77363         }
77364         catch (err) {
77365         }
77366     });
77367 };
77368
77369 TireTemperature = function (propertyTypes) {
77370     var tireTemperature = {};
77371
77372     VehiclePropertyType.call(this, propertyTypes);
77373
77374     tireTemperature.leftFront = propertyTypes.leftFront || 0;
77375     tireTemperature.rightFront = propertyTypes.rightFront || 0;
77376     tireTemperature.leftRear = propertyTypes.leftRear || 0;
77377     tireTemperature.rightRear = propertyTypes.rightRear || 0;
77378
77379     this.__defineGetter__("leftFront", function () {
77380         return tireTemperature.leftFront;
77381     });
77382
77383     this.__defineSetter__("leftFront", function (val) {
77384         try {
77385             tireTemperature.leftFront = t.double(val);
77386         }
77387         catch (err) {
77388         }
77389     });
77390
77391     this.__defineGetter__("rightFront", function () {
77392         return tireTemperature.rightFront;
77393     });
77394
77395     this.__defineSetter__("rightFront", function (val) {
77396         try {
77397             tireTemperature.rightFront = t.double(val);
77398         }
77399         catch (err) {
77400         }
77401     });
77402
77403     this.__defineGetter__("leftRear", function () {
77404         return tireTemperature.leftRear;
77405     });
77406
77407     this.__defineSetter__("leftRear", function (val) {
77408         try {
77409             tireTemperature.leftRear = t.double(val);
77410         }
77411         catch (err) {
77412         }
77413     });
77414
77415     this.__defineGetter__("rightRear", function () {
77416         return tireTemperature.rightRear;
77417     });
77418
77419     this.__defineSetter__("rightRear", function (val) {
77420         try {
77421             tireTemperature.rightRear = t.double(val);
77422         }
77423         catch (err) {
77424         }
77425     });
77426 };
77427
77428 SecurityAlert = function (propertyTypes) {
77429     var securityAlert = {};
77430
77431     VehiclePropertyType.call(this, propertyTypes);
77432
77433     securityAlert.securityAlert = propertyTypes.securityAlert || false;
77434
77435     this.__defineGetter__("securityAlert", function () {
77436         return securityAlert.securityAlert;
77437     });
77438
77439     this.__defineSetter__("securityAlert", function (val) {
77440         try {
77441             securityAlert.securityAlert = t.boolean(val);
77442         }
77443         catch (err) {
77444         }
77445     });
77446 };
77447
77448 ParkingBrake = function (propertyTypes) {
77449     var parkingBrake = {};
77450
77451     VehiclePropertyType.call(this, propertyTypes);
77452
77453     parkingBrake.parkingBrake = propertyTypes.parkingBrake || false;
77454
77455     this.__defineGetter__("parkingBrake", function () {
77456         return parkingBrake.parkingBrake;
77457     });
77458
77459     this.__defineSetter__("parkingBrake", function (val) {
77460         try {
77461             parkingBrake.parkingBrake = t.boolean(val);
77462         }
77463         catch (err) {
77464         }
77465     });
77466 };
77467
77468 ParkingLight = function (propertyTypes) {
77469     var parkingLight = {};
77470
77471     VehiclePropertyType.call(this, propertyTypes);
77472
77473     parkingLight.parkingLight = propertyTypes.parkingLight || false;
77474
77475     this.__defineGetter__("parkingLight", function () {
77476         return parkingLight.parkingLight;
77477     });
77478
77479     this.__defineSetter__("parkingLight", function (val) {
77480         try {
77481             parkingLight.parkingLight = t.boolean(val);
77482         }
77483         catch (err) {
77484         }
77485     });
77486 };
77487
77488 HazardLight = function (propertyTypes) {
77489     var hazardLight = {};
77490
77491     VehiclePropertyType.call(this, propertyTypes);
77492
77493     hazardLight.hazardLight = propertyTypes.hazardLight || false;
77494
77495     this.__defineGetter__("hazardLight", function () {
77496         return hazardLight.hazardLight;
77497     });
77498
77499     this.__defineSetter__("hazardLight", function (val) {
77500         try {
77501             hazardLight.hazardLight = t.boolean(val);
77502         }
77503         catch (err) {
77504         }
77505     });
77506 };
77507
77508 AntilockBrakingSystem = function (propertyTypes) {
77509     var abs = {};
77510
77511     VehiclePropertyType.call(this, propertyTypes);
77512
77513     abs.antilockBrakingSystem = propertyTypes.antilockBrakingSystem || false;
77514
77515     this.__defineGetter__("antilockBrakingSystem", function () {
77516         return abs.antilockBrakingSystem;
77517     });
77518
77519     this.__defineSetter__("antilockBrakingSystem", function (val) {
77520         try {
77521             abs.antilockBrakingSystem = t.boolean(val);
77522         }
77523         catch (err) {
77524         }
77525     });
77526 };
77527
77528 TractionControlSystem = function (propertyTypes) {
77529     var tcs = {};
77530
77531     VehiclePropertyType.call(this, propertyTypes);
77532
77533     tcs.tractionControlSystem = propertyTypes.tractionControlSystem || false;
77534
77535     this.__defineGetter__("tractionControlSystem", function () {
77536         return tcs.tractionControlSystem;
77537     });
77538
77539     this.__defineSetter__("tractionControlSystem", function (val) {
77540         try {
77541             tcs.tractionControlSystem = t.boolean(val);
77542         }
77543         catch (err) {
77544         }
77545     });
77546 };
77547
77548 VehicleTopSpeedLimit = function (propertyTypes) {
77549     var vtl = {};
77550
77551     VehiclePropertyType.call(this, propertyTypes);
77552
77553     vtl.vehicleTopSpeedLimit = propertyTypes.vehicleTopSpeedLimit || false;
77554
77555     this.__defineGetter__("vehicleTopSpeedLimit", function () {
77556         return vtl.vehicleTopSpeedLimit;
77557     });
77558
77559     this.__defineSetter__("vehicleTopSpeedLimit", function (val) {
77560         try {
77561             vtl.vehicleTopSpeedLimit = t.unsigned_short(val);
77562         }
77563         catch (err) {
77564         }
77565     });
77566 };
77567
77568 AirbagStatus = function (propertyTypes) {
77569     var airbagStatus = {};
77570
77571     VehiclePropertyType.call(this, propertyTypes);
77572
77573     airbagStatus.airbagStatus = propertyTypes.airbagStatus || 0;
77574
77575     this.__defineGetter__("AIRBAGSTATUS_INACTIVE", function () {
77576         return 0;
77577     });
77578
77579     this.__defineGetter__("AIRBAGSTATUS_ACTIVE", function () {
77580         return 1;
77581     });
77582
77583     this.__defineGetter__("AIRBAGSTATUS_DEPLOYED", function () {
77584         return 2;
77585     });
77586
77587     this.__defineGetter__("airbagStatus", function () {
77588         return airbagStatus.airbagStatus;
77589     });
77590
77591     this.__defineSetter__("airbagStatus", function (val) {
77592         try {
77593             val = t.unsigned_short(val);
77594             if (val === 0 || val === 1 || val === 2) {
77595                 airbagStatus.airbagStatus = val;
77596             }
77597         }
77598         catch (err) {
77599         }
77600     });
77601 };
77602
77603 DoorStatus = function (propertyTypes) {
77604     var doorStatus = {};
77605
77606     VehiclePropertyType.call(this, propertyTypes);
77607
77608     doorStatus.doorStatus = propertyTypes.doorStatus || 0;
77609     doorStatus.doorLockStatus = propertyTypes.doorLockStatus || false;
77610     doorStatus.childLockStatus = propertyTypes.childLockStatus || false;
77611
77612     this.__defineGetter__("DOORSTATUS_CLOSED", function () {
77613         return 0;
77614     });
77615
77616     this.__defineGetter__("DOORSTATUS_OPEN", function () {
77617         return 1;
77618     });
77619
77620     this.__defineGetter__("DOORSTATUS_AJAR", function () {
77621         return 2;
77622     });
77623
77624     this.__defineGetter__("doorStatus", function () {
77625         return doorStatus.doorStatus;
77626     });
77627
77628     this.__defineSetter__("doorStatus", function (val) {
77629         try {
77630             val = t.unsigned_short(val);
77631             if (val === 0 || val === 1 || val === 2) {
77632                 doorStatus.doorStatus = val;
77633             }
77634         }
77635         catch (err) {
77636         }
77637     });
77638
77639     this.__defineGetter__("doorLockStatus", function () {
77640         return doorStatus.doorLockStatus;
77641     });
77642
77643     this.__defineSetter__("doorLockStatus", function (val) {
77644         try {
77645             doorStatus.doorLockStatus = t.boolean(val);
77646         }
77647         catch (err) {
77648         }
77649     });
77650
77651     this.__defineGetter__("childLockStatus", function () {
77652         return doorStatus.childLockStatus;
77653     });
77654
77655     this.__defineSetter__("childLockStatus", function (val) {
77656         try {
77657             doorStatus.childLockStatus = t.boolean(val);
77658         }
77659         catch (err) {
77660         }
77661     });
77662 };
77663
77664 SeatBeltStatus = function (propertyTypes) {
77665     var seatBeltStatus = {};
77666
77667     VehiclePropertyType.call(this, propertyTypes);
77668
77669     seatBeltStatus.seatBeltStatus = propertyTypes.seatBeltStatus || false;
77670
77671     this.__defineGetter__("seatBeltStatus", function () {
77672         return seatBeltStatus.seatBeltStatus;
77673     });
77674
77675     this.__defineSetter__("seatBeltStatus", function (val) {
77676         try {
77677             seatBeltStatus.seatBeltStatus = t.boolean(val);
77678         }
77679         catch (err) {
77680         }
77681     });
77682 };
77683
77684 OccupantStatus = function (propertyTypes) {
77685     var occupantStatus = {};
77686
77687     VehiclePropertyType.call(this, propertyTypes);
77688
77689     occupantStatus.occupantStatus = propertyTypes.occupantStatus || 0;
77690
77691     this.__defineGetter__("OCCUPANTSTATUS_VACANT", function () {
77692         return 0;
77693     });
77694
77695     this.__defineGetter__("OCCUPANTSTATUS_CHILD", function () {
77696         return 1;
77697     });
77698
77699     this.__defineGetter__("OCCUPANTSTATUS_ADULT", function () {
77700         return 2;
77701     });
77702
77703     this.__defineGetter__("occupantStatus", function () {
77704         return occupantStatus.occupantStatus;
77705     });
77706
77707     this.__defineSetter__("occupantStatus", function (val) {
77708         try {
77709             val = t.unsigned_short(val);
77710             if (val === 0 || val === 1 || val === 2) {
77711                 occupantStatus.occupantStatus = val;
77712             }
77713         }
77714         catch (err) {
77715         }
77716     });
77717 };
77718
77719 ObstacleDistance = function (propertyTypes) {
77720     var obstacleDistance = {};
77721
77722     VehiclePropertyType.call(this, propertyTypes);
77723
77724     obstacleDistance.obstacleDistance = propertyTypes.obstacleDistance || 0;
77725
77726     this.__defineGetter__("DISTANCESENSORLOCATION_LEFTFRONT", function () {
77727         return 0;
77728     });
77729
77730     this.__defineGetter__("DISTANCESENSORLOCATION_RIGHTFRONT", function () {
77731         return 1;
77732     });
77733
77734     this.__defineGetter__("DISTANCESENSORLOCATION_LEFTREAR", function () {
77735         return 2;
77736     });
77737
77738     this.__defineGetter__("DISTANCESENSORLOCATION_RIGHTREAR", function () {
77739         return 3;
77740     });
77741
77742     this.__defineGetter__("DISTANCESENSORLOCATION_LEFTBLINDSPOT", function () {
77743         return 4;
77744     });
77745
77746     this.__defineGetter__("DISTANCESENSORLOCATION_RIGHTBLINDSPOT", function () {
77747         return 5;
77748     });
77749
77750     this.__defineGetter__("obstacleDistance", function () {
77751         return obstacleDistance.obstacleDistance;
77752     });
77753
77754     this.__defineSetter__("obstacleDistance", function (val) {
77755         try {
77756             obstacleDistance.obstacleDistance = t.double(val);
77757         }
77758         catch (err) {
77759         }
77760     });
77761 };
77762
77763 NightMode = function (propertyTypes) {
77764     var nightMode = {};
77765
77766     VehiclePropertyType.call(this, propertyTypes);
77767
77768     nightMode.nightMode = propertyTypes.nightMode || false;
77769
77770     this.__defineGetter__("nightMode", function () {
77771         return nightMode.nightMode;
77772     });
77773
77774     this.__defineSetter__("nightMode", function (val) {
77775         try {
77776             nightMode.nightMode = t.boolean(val);
77777         }
77778         catch (err) {
77779         }
77780     });
77781 };
77782
77783 DrivingMode = function (propertyTypes) {
77784     var drivingMode = {};
77785
77786     VehiclePropertyType.call(this, propertyTypes);
77787
77788     drivingMode.drivingMode = propertyTypes.drivingMode || 0;
77789
77790     this.__defineGetter__("drivingMode", function () {
77791         return drivingMode.drivingMode;
77792     });
77793
77794     this.__defineSetter__("drivingMode", function (val) {
77795         try {
77796             val = t.unsigned_short(val);
77797             if (val === 0 || val === 1) {
77798                 drivingMode.drivingMode = val;
77799             }
77800         }
77801         catch (err) {
77802         }
77803     });
77804 };
77805
77806 TurnSignal = function (propertyTypes) {
77807     var turnSignal = {};
77808
77809     VehiclePropertyType.call(this, propertyTypes);
77810
77811     turnSignal.turnSignal = propertyTypes.turnSignal || 0;
77812
77813     this.__defineGetter__("turnSignal", function () {
77814         return turnSignal.turnSignal;
77815     });
77816
77817     this.__defineSetter__("turnSignal", function (val) {
77818         try {
77819             turnSignal.turnSignal = t.unsigned_short(val);
77820         }
77821         catch (err) {
77822         }
77823     });
77824 };
77825
77826 ButtonEvent = function (propertyTypes) {
77827     var buttonEvent = {};
77828
77829     VehiclePropertyType.call(this, propertyTypes);
77830
77831     buttonEvent.buttonEvent = propertyTypes.buttonEvent || 0;
77832
77833     this.__defineGetter__("buttonEvent", function () {
77834         return buttonEvent.buttonEvent;
77835     });
77836
77837     this.__defineSetter__("buttonEvent", function (val) {
77838         try {
77839             buttonEvent.buttonEvent = t.unsigned_short(val);
77840         }
77841         catch (err) {
77842         }
77843     });
77844 };
77845
77846 _initialize();
77847
77848 module.exports = _self;
77849
77850 });
77851 define('ripple/platform/phonegap/1.0.0/AVCodecsAttributes', function (require, exports, module) {
77852 /*
77853  *  Copyright 2011 Research In Motion Limited.
77854  *
77855  * Licensed under the Apache License, Version 2.0 (the "License");
77856  * you may not use this file except in compliance with the License.
77857  * You may obtain a copy of the License at
77858  *
77859  * http://www.apache.org/licenses/LICENSE-2.0
77860  *
77861  * Unless required by applicable law or agreed to in writing, software
77862  * distributed under the License is distributed on an "AS IS" BASIS,
77863  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
77864  * See the License for the specific language governing permissions and
77865  * limitations under the License.
77866  */
77867 module.exports = function (info, id, audioCodecs, videoCodecs) {
77868     return {
77869         info: info,
77870         id: id,
77871         audioCodecs: audioCodecs,
77872         videoCodecs: videoCodecs
77873     };
77874 };
77875
77876 });
77877 define('ripple/platform/phonegap/1.0.0/Acceleration', function (require, exports, module) {
77878 /*
77879  *  Copyright 2011 Research In Motion Limited.
77880  *
77881  * Licensed under the Apache License, Version 2.0 (the "License");
77882  * you may not use this file except in compliance with the License.
77883  * You may obtain a copy of the License at
77884  *
77885  * http://www.apache.org/licenses/LICENSE-2.0
77886  *
77887  * Unless required by applicable law or agreed to in writing, software
77888  * distributed under the License is distributed on an "AS IS" BASIS,
77889  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
77890  * See the License for the specific language governing permissions and
77891  * limitations under the License.
77892  */
77893 module.exports = function (x, y, z) {
77894     return {
77895         x: x || 0,
77896         y: y || 0,
77897         z: z || 0,
77898         timestamp: new Date().getTime()
77899     };
77900 };
77901
77902 });
77903 define('ripple/platform/phonegap/1.0.0/AudioCodecAttributes', function (require, exports, module) {
77904 /*
77905  *  Copyright 2011 Research In Motion Limited.
77906  *
77907  * Licensed under the Apache License, Version 2.0 (the "License");
77908  * you may not use this file except in compliance with the License.
77909  * You may obtain a copy of the License at
77910  *
77911  * http://www.apache.org/licenses/LICENSE-2.0
77912  *
77913  * Unless required by applicable law or agreed to in writing, software
77914  * distributed under the License is distributed on an "AS IS" BASIS,
77915  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
77916  * See the License for the specific language governing permissions and
77917  * limitations under the License.
77918  */
77919 module.exports = function (info, id, compFormats, encode, decode) {
77920     return {
77921         info: info,
77922         id: id,
77923         compFormats: compFormats,
77924         encode: encode,
77925         decode: decode
77926     };
77927 };
77928
77929 });
77930 define('ripple/platform/phonegap/1.0.0/AudioDeviceAttributes', function (require, exports, module) {
77931 /*
77932  *  Copyright 2011 Research In Motion Limited.
77933  *
77934  * Licensed under the Apache License, Version 2.0 (the "License");
77935  * you may not use this file except in compliance with the License.
77936  * You may obtain a copy of the License at
77937  *
77938  * http://www.apache.org/licenses/LICENSE-2.0
77939  *
77940  * Unless required by applicable law or agreed to in writing, software
77941  * distributed under the License is distributed on an "AS IS" BASIS,
77942  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
77943  * See the License for the specific language governing permissions and
77944  * limitations under the License.
77945  */
77946 module.exports = function (type, freqRangeLow, freqRangeHigh, volumeLevel, info) {
77947     return {
77948         type: type,
77949         freqRangeLow: freqRangeLow,
77950         freqRangeHigh: freqRangeHigh,
77951         volumeLevel: volumeLevel,
77952         info: info
77953     };
77954
77955 };
77956
77957 });
77958 define('ripple/platform/phonegap/1.0.0/BrailleDeviceAttributes', function (require, exports, module) {
77959 /*
77960  *  Copyright 2011 Research In Motion Limited.
77961  *
77962  * Licensed under the Apache License, Version 2.0 (the "License");
77963  * you may not use this file except in compliance with the License.
77964  * You may obtain a copy of the License at
77965  *
77966  * http://www.apache.org/licenses/LICENSE-2.0
77967  *
77968  * Unless required by applicable law or agreed to in writing, software
77969  * distributed under the License is distributed on an "AS IS" BASIS,
77970  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
77971  * See the License for the specific language governing permissions and
77972  * limitations under the License.
77973  */
77974 module.exports = function (nbCells, info) {
77975     return {
77976         nbCells: nbCells,
77977         info: info
77978     };
77979
77980 };
77981
77982 });
77983 define('ripple/platform/phonegap/1.0.0/CPUAttributes', function (require, exports, module) {
77984 /*
77985  *  Copyright 2011 Research In Motion Limited.
77986  *
77987  * Licensed under the Apache License, Version 2.0 (the "License");
77988  * you may not use this file except in compliance with the License.
77989  * You may obtain a copy of the License at
77990  *
77991  * http://www.apache.org/licenses/LICENSE-2.0
77992  *
77993  * Unless required by applicable law or agreed to in writing, software
77994  * distributed under the License is distributed on an "AS IS" BASIS,
77995  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
77996  * See the License for the specific language governing permissions and
77997  * limitations under the License.
77998  */
77999 module.exports = function (info, id, usage) {
78000     return {
78001         info: info,
78002         id: id,
78003         usage: usage
78004     };
78005 };
78006
78007 });
78008 define('ripple/platform/phonegap/1.0.0/CameraAttributes', function (require, exports, module) {
78009 /*
78010  *  Copyright 2011 Research In Motion Limited.
78011  *
78012  * Licensed under the Apache License, Version 2.0 (the "License");
78013  * you may not use this file except in compliance with the License.
78014  * You may obtain a copy of the License at
78015  *
78016  * http://www.apache.org/licenses/LICENSE-2.0
78017  *
78018  * Unless required by applicable law or agreed to in writing, software
78019  * distributed under the License is distributed on an "AS IS" BASIS,
78020  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78021  * See the License for the specific language governing permissions and
78022  * limitations under the License.
78023  */
78024 module.exports = function (supportsVideo, hasFlash, sensorPixels, maxZoomFactor) {
78025     return {
78026         supportsVideo: supportsVideo,
78027         hasFlash: hasFlash,
78028         sensorPixels: sensorPixels,
78029         maxZoomFactor: maxZoomFactor
78030     };
78031
78032 };
78033
78034 });
78035 define('ripple/platform/phonegap/1.0.0/Connection', function (require, exports, module) {
78036 /*
78037  *  Copyright 2011 Research In Motion Limited.
78038  *
78039  * Licensed under the Apache License, Version 2.0 (the "License");
78040  * you may not use this file except in compliance with the License.
78041  * You may obtain a copy of the License at
78042  *
78043  * http://www.apache.org/licenses/LICENSE-2.0
78044  *
78045  * Unless required by applicable law or agreed to in writing, software
78046  * distributed under the License is distributed on an "AS IS" BASIS,
78047  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78048  * See the License for the specific language governing permissions and
78049  * limitations under the License.
78050  */
78051 module.exports = {
78052     UNKNOWN: "unknown",
78053     ETHERNET: "ethernet",
78054     WIFI: "wifi",
78055     CELL_2G: "2g",
78056     CELL_3G: "3g",
78057     CELL_4G: "4g",
78058     NONE: "none"
78059 };
78060
78061 });
78062 define('ripple/platform/phonegap/1.0.0/ConnectionAttributes', function (require, exports, module) {
78063 /*
78064  *  Copyright 2011 Research In Motion Limited.
78065  *
78066  * Licensed under the Apache License, Version 2.0 (the "License");
78067  * you may not use this file except in compliance with the License.
78068  * You may obtain a copy of the License at
78069  *
78070  * http://www.apache.org/licenses/LICENSE-2.0
78071  *
78072  * Unless required by applicable law or agreed to in writing, software
78073  * distributed under the License is distributed on an "AS IS" BASIS,
78074  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78075  * See the License for the specific language governing permissions and
78076  * limitations under the License.
78077  */
78078 module.exports = function (info, id, type, currentOrientation, currentUploadBandwidth, maxDownloadBandwidth, maxUploadBandwidth, currentSignalStrength, roaming) {
78079     return {
78080         info: info,
78081         id: id,
78082         type: type,
78083         currentDownloadBandwidth: currentOrientation,
78084         currentUploadBandwidth: currentUploadBandwidth,
78085         maxDownloadBandwidth: maxDownloadBandwidth,
78086         maxUploadBandwidth: maxUploadBandwidth,
78087         currentSignalStrength: currentSignalStrength,
78088         roaming: roaming
78089     };
78090 };
78091
78092 });
78093 define('ripple/platform/phonegap/1.0.0/Contact', function (require, exports, module) {
78094 /*
78095  *  Copyright 2011 Research In Motion Limited.
78096  *
78097  * Licensed under the Apache License, Version 2.0 (the "License");
78098  * you may not use this file except in compliance with the License.
78099  * You may obtain a copy of the License at
78100  *
78101  * http://www.apache.org/licenses/LICENSE-2.0
78102  *
78103  * Unless required by applicable law or agreed to in writing, software
78104  * distributed under the License is distributed on an "AS IS" BASIS,
78105  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78106  * See the License for the specific language governing permissions and
78107  * limitations under the License.
78108  */
78109 var utils = require('ripple/utils'),
78110     event = require('ripple/event');
78111
78112 function _properties(obj) {
78113     var prop, newObj = {};
78114     for (prop in obj) {
78115         if (Object.prototype.hasOwnProperty.call(obj, prop)) {
78116             if (typeof obj[prop] !== "function") {
78117                 newObj[prop] = utils.copy(obj[prop]);
78118             }
78119         }
78120     }
78121     return newObj;
78122 }
78123
78124 module.exports = function (
78125         id,
78126         displayName,
78127         name,
78128         nickname,
78129         phoneNumbers,
78130         emails,
78131         addresses,
78132         ims,
78133         organizations,
78134         birthday,
78135         note,
78136         photos,
78137         categories,
78138         urls
78139 ) {
78140
78141     return {
78142         id: id || Math.uuid(undefined, 16),
78143         displayName: displayName || null,
78144         name: name || null,
78145         nickname: nickname || null,
78146         phoneNumbers: phoneNumbers || null,
78147         emails: emails || null,
78148         addresses: addresses || null,
78149         ims: ims || null,
78150         organizations: organizations || null,
78151         birthday: birthday || null,
78152         note: note || null,
78153         photos: photos || null,
78154         categories: categories || null,
78155         urls: urls || null,
78156         save: function (success, error) {
78157             var _self = this,
78158                 lastUpdated = this.updated; // hackish
78159
78160             this.updated = new Date();
78161
78162             if (!this.id) {
78163                 this.id = Math.uuid(undefined, 16);
78164             }
78165
78166             event.trigger("phonegap-contact-save", [_properties(this), success, function (e) {
78167                 _self.updated = lastUpdated;
78168                 error(e);
78169             }]);
78170         },
78171         remove: function (success, error) {
78172             event.trigger("phonegap-contact-remove", [this.id, success, error]);
78173         },
78174         clone: function () {
78175             var copy = utils.copy(this);
78176             copy.id = null;
78177             return copy;
78178         }
78179     };
78180 };
78181
78182 });
78183 define('ripple/platform/phonegap/1.0.0/ContactAccount', function (require, exports, module) {
78184 /*
78185  *  Copyright 2011 Research In Motion Limited.
78186  *
78187  * Licensed under the Apache License, Version 2.0 (the "License");
78188  * you may not use this file except in compliance with the License.
78189  * You may obtain a copy of the License at
78190  *
78191  * http://www.apache.org/licenses/LICENSE-2.0
78192  *
78193  * Unless required by applicable law or agreed to in writing, software
78194  * distributed under the License is distributed on an "AS IS" BASIS,
78195  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78196  * See the License for the specific language governing permissions and
78197  * limitations under the License.
78198  */
78199 module.exports = function (domain, username, userid) {
78200     return {
78201         domain: domain,
78202         username: username,
78203         userid: userid
78204     };
78205 };
78206
78207 });
78208 define('ripple/platform/phonegap/1.0.0/ContactAddress', function (require, exports, module) {
78209 /*
78210  *  Copyright 2011 Research In Motion Limited.
78211  *
78212  * Licensed under the Apache License, Version 2.0 (the "License");
78213  * you may not use this file except in compliance with the License.
78214  * You may obtain a copy of the License at
78215  *
78216  * http://www.apache.org/licenses/LICENSE-2.0
78217  *
78218  * Unless required by applicable law or agreed to in writing, software
78219  * distributed under the License is distributed on an "AS IS" BASIS,
78220  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78221  * See the License for the specific language governing permissions and
78222  * limitations under the License.
78223  */
78224 module.exports = function (pref, type, formatted, streetAddress, locality, region, postalCode, country, id) {
78225     return {
78226         pref: pref || null,
78227         type: type || null,
78228         formatted: formatted || null,
78229         streetAddress: streetAddress || null,
78230         locality: locality || null,
78231         region: region || null,
78232         postalCode: postalCode || null,
78233         country: country || null,
78234         id: id || null
78235     };
78236 };
78237
78238 });
78239 define('ripple/platform/phonegap/1.0.0/ContactError', function (require, exports, module) {
78240 /*
78241  *  Copyright 2011 Research In Motion Limited.
78242  *
78243  * Licensed under the Apache License, Version 2.0 (the "License");
78244  * you may not use this file except in compliance with the License.
78245  * You may obtain a copy of the License at
78246  *
78247  * http://www.apache.org/licenses/LICENSE-2.0
78248  *
78249  * Unless required by applicable law or agreed to in writing, software
78250  * distributed under the License is distributed on an "AS IS" BASIS,
78251  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78252  * See the License for the specific language governing permissions and
78253  * limitations under the License.
78254  */
78255 function ContactError(code) {
78256     this.code = code || null;
78257 }
78258
78259 ContactError.UNKNOWN_ERROR = 0;
78260 ContactError.INVALID_ARGUMENT_ERROR = 1;
78261 ContactError.NOT_FOUND_ERROR = 2;
78262 ContactError.TIMEOUT_ERROR = 3;
78263 ContactError.PENDING_OPERATION_ERROR = 4;
78264 ContactError.IO_ERROR = 5;
78265 ContactError.NOT_SUPPORTED_ERROR = 6;
78266 ContactError.PERMISSION_DENIED_ERROR = 20;
78267
78268 module.exports = ContactError;
78269
78270 });
78271 define('ripple/platform/phonegap/1.0.0/ContactField', function (require, exports, module) {
78272 /*
78273  *  Copyright 2011 Research In Motion Limited.
78274  *
78275  * Licensed under the Apache License, Version 2.0 (the "License");
78276  * you may not use this file except in compliance with the License.
78277  * You may obtain a copy of the License at
78278  *
78279  * http://www.apache.org/licenses/LICENSE-2.0
78280  *
78281  * Unless required by applicable law or agreed to in writing, software
78282  * distributed under the License is distributed on an "AS IS" BASIS,
78283  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78284  * See the License for the specific language governing permissions and
78285  * limitations under the License.
78286  */
78287 module.exports = function (type, value, pref) {
78288     return {
78289         type: type,
78290         value: value,
78291         pref: pref || false
78292     };
78293 };
78294
78295 });
78296 define('ripple/platform/phonegap/1.0.0/ContactFindOptions', function (require, exports, module) {
78297 /*
78298  *  Copyright 2011 Research In Motion Limited.
78299  *
78300  * Licensed under the Apache License, Version 2.0 (the "License");
78301  * you may not use this file except in compliance with the License.
78302  * You may obtain a copy of the License at
78303  *
78304  * http://www.apache.org/licenses/LICENSE-2.0
78305  *
78306  * Unless required by applicable law or agreed to in writing, software
78307  * distributed under the License is distributed on an "AS IS" BASIS,
78308  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78309  * See the License for the specific language governing permissions and
78310  * limitations under the License.
78311  */
78312 module.exports = function (filter, multiple, updatedSince) {
78313     return {
78314         filter: filter || "",
78315         multiple: multiple || false,
78316         updatedSince: updatedSince || ""
78317     };
78318 };
78319
78320 });
78321 define('ripple/platform/phonegap/1.0.0/ContactName', function (require, exports, module) {
78322 /*
78323  *  Copyright 2011 Research In Motion Limited.
78324  *
78325  * Licensed under the Apache License, Version 2.0 (the "License");
78326  * you may not use this file except in compliance with the License.
78327  * You may obtain a copy of the License at
78328  *
78329  * http://www.apache.org/licenses/LICENSE-2.0
78330  *
78331  * Unless required by applicable law or agreed to in writing, software
78332  * distributed under the License is distributed on an "AS IS" BASIS,
78333  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78334  * See the License for the specific language governing permissions and
78335  * limitations under the License.
78336  */
78337 module.exports = function (formatted, familyName, givenName, middleName, honorificPrefix, honorificSuffix) {
78338     return {
78339         formatted: formatted,
78340         familyName: familyName,
78341         givenName: givenName,
78342         middleName: middleName,
78343         honorificPrefix: honorificPrefix,
78344         honorificSuffix: honorificSuffix
78345     };
78346 };
78347
78348 });
78349 define('ripple/platform/phonegap/1.0.0/ContactOrganization', function (require, exports, module) {
78350 /*
78351  *  Copyright 2011 Research In Motion Limited.
78352  *
78353  * Licensed under the Apache License, Version 2.0 (the "License");
78354  * you may not use this file except in compliance with the License.
78355  * You may obtain a copy of the License at
78356  *
78357  * http://www.apache.org/licenses/LICENSE-2.0
78358  *
78359  * Unless required by applicable law or agreed to in writing, software
78360  * distributed under the License is distributed on an "AS IS" BASIS,
78361  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78362  * See the License for the specific language governing permissions and
78363  * limitations under the License.
78364  */
78365 module.exports = function (pref, type, name, dept, title) {
78366     return {
78367         pref: pref || null,
78368         type: type || null,
78369         name: name || null,
78370         department: dept || null,
78371         title: title || null
78372     };
78373 };
78374
78375 });
78376 define('ripple/platform/phonegap/1.0.0/DisplayDeviceAttributes', function (require, exports, module) {
78377 /*
78378  *  Copyright 2011 Research In Motion Limited.
78379  *
78380  * Licensed under the Apache License, Version 2.0 (the "License");
78381  * you may not use this file except in compliance with the License.
78382  * You may obtain a copy of the License at
78383  *
78384  * http://www.apache.org/licenses/LICENSE-2.0
78385  *
78386  * Unless required by applicable law or agreed to in writing, software
78387  * distributed under the License is distributed on an "AS IS" BASIS,
78388  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78389  * See the License for the specific language governing permissions and
78390  * limitations under the License.
78391  */
78392 module.exports = function (orientation, brightness, contrast, blanked, dotsPerInchW, dotsPerInchH, physicalWidth, physicalHeight, info) {
78393     return {
78394         orientation: orientation,
78395         brightness: brightness,
78396         contrast: contrast,
78397         blanked: blanked,
78398         dotsPerInchW: dotsPerInchW,
78399         dotsPerInchH: dotsPerInchH,
78400         physicalWidth: physicalWidth,
78401         physicalHeight: physicalHeight,
78402         info: info
78403     };
78404 };
78405
78406 });
78407 define('ripple/platform/phonegap/1.0.0/InputDevicesAttributes', function (require, exports, module) {
78408 /*
78409  *  Copyright 2011 Research In Motion Limited.
78410  *
78411  * Licensed under the Apache License, Version 2.0 (the "License");
78412  * you may not use this file except in compliance with the License.
78413  * You may obtain a copy of the License at
78414  *
78415  * http://www.apache.org/licenses/LICENSE-2.0
78416  *
78417  * Unless required by applicable law or agreed to in writing, software
78418  * distributed under the License is distributed on an "AS IS" BASIS,
78419  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78420  * See the License for the specific language governing permissions and
78421  * limitations under the License.
78422  */
78423 module.exports = function (info, id, pointingDevices, activePointingDevices, keyboards, activeKeyboards, cameras, activeCameras, microphones, activeMicrophones) {
78424     return {
78425         info: info,
78426         id: id,
78427         pointingDevices: pointingDevices,
78428         activePointingDevices: activePointingDevices,
78429         keyboards: keyboards,
78430         activeKeyboards: activeKeyboards,
78431         cameras: cameras,
78432         activeCameras: activeCameras,
78433         microphones: microphones,
78434         activeMicrophones: activeMicrophones
78435     };
78436
78437 };
78438
78439 });
78440 define('ripple/platform/phonegap/1.0.0/KeyboardAttributes', function (require, exports, module) {
78441 /*
78442  *  Copyright 2011 Research In Motion Limited.
78443  *
78444  * Licensed under the Apache License, Version 2.0 (the "License");
78445  * you may not use this file except in compliance with the License.
78446  * You may obtain a copy of the License at
78447  *
78448  * http://www.apache.org/licenses/LICENSE-2.0
78449  *
78450  * Unless required by applicable law or agreed to in writing, software
78451  * distributed under the License is distributed on an "AS IS" BASIS,
78452  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78453  * See the License for the specific language governing permissions and
78454  * limitations under the License.
78455  */
78456 module.exports = function (type, isHardware, info) {
78457     return {
78458         type: type,
78459         isHardware: isHardware,
78460         info: info
78461     };
78462 };
78463
78464 });
78465 define('ripple/platform/phonegap/1.0.0/MicrophoneAttributes', function (require, exports, module) {
78466 /*
78467  *  Copyright 2011 Research In Motion Limited.
78468  *
78469  * Licensed under the Apache License, Version 2.0 (the "License");
78470  * you may not use this file except in compliance with the License.
78471  * You may obtain a copy of the License at
78472  *
78473  * http://www.apache.org/licenses/LICENSE-2.0
78474  *
78475  * Unless required by applicable law or agreed to in writing, software
78476  * distributed under the License is distributed on an "AS IS" BASIS,
78477  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78478  * See the License for the specific language governing permissions and
78479  * limitations under the License.
78480  */
78481 module.exports = function (type, freqRangeLow, freqRangeHigh, info, name, types) {
78482     return {
78483         type: type,
78484         freqRangeLow: freqRangeLow,
78485         freqRangeHigh: freqRangeHigh,
78486         info: info,
78487         name: name,
78488         types: types
78489     };
78490 };
78491
78492 });
78493 define('ripple/platform/phonegap/1.0.0/NetworkAttributes', function (require, exports, module) {
78494 /*
78495  *  Copyright 2011 Research In Motion Limited.
78496  *
78497  * Licensed under the Apache License, Version 2.0 (the "License");
78498  * you may not use this file except in compliance with the License.
78499  * You may obtain a copy of the License at
78500  *
78501  * http://www.apache.org/licenses/LICENSE-2.0
78502  *
78503  * Unless required by applicable law or agreed to in writing, software
78504  * distributed under the License is distributed on an "AS IS" BASIS,
78505  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78506  * See the License for the specific language governing permissions and
78507  * limitations under the License.
78508  */
78509 module.exports = function (info, id, activeConnections) {
78510     return {
78511         info: info,
78512         id: id,
78513         activeConnections: activeConnections || []
78514     };
78515 };
78516
78517 });
78518 define('ripple/platform/phonegap/1.0.0/NetworkStatus', function (require, exports, module) {
78519 /*
78520  *  Copyright 2011 Research In Motion Limited.
78521  *
78522  * Licensed under the Apache License, Version 2.0 (the "License");
78523  * you may not use this file except in compliance with the License.
78524  * You may obtain a copy of the License at
78525  *
78526  * http://www.apache.org/licenses/LICENSE-2.0
78527  *
78528  * Unless required by applicable law or agreed to in writing, software
78529  * distributed under the License is distributed on an "AS IS" BASIS,
78530  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78531  * See the License for the specific language governing permissions and
78532  * limitations under the License.
78533  */
78534 module.exports = {
78535     NOT_REACHABLE: 0,
78536     REACHABLE_VIA_CARRIER_DATA_NETWORK: 1,
78537     REACHABLE_VIA_WIFI_NETWORK: 2
78538 };
78539
78540 });
78541 define('ripple/platform/phonegap/1.0.0/OutputDevicesAttributes', function (require, exports, module) {
78542 /*
78543  *  Copyright 2011 Research In Motion Limited.
78544  *
78545  * Licensed under the Apache License, Version 2.0 (the "License");
78546  * you may not use this file except in compliance with the License.
78547  * You may obtain a copy of the License at
78548  *
78549  * http://www.apache.org/licenses/LICENSE-2.0
78550  *
78551  * Unless required by applicable law or agreed to in writing, software
78552  * distributed under the License is distributed on an "AS IS" BASIS,
78553  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78554  * See the License for the specific language governing permissions and
78555  * limitations under the License.
78556  */
78557 module.exports = function (info, id, displayDevices, activeDisplayDevices, printingDevices, activePrintingDevice, brailleDevices, activeBrailleDevice, audioDevices, activeAudioDevices) {
78558     return {
78559         info: info,
78560         id: id,
78561         displayDevices: displayDevices,
78562         activeDisplayDevices: activeDisplayDevices,
78563         printingDevices: printingDevices,
78564         activePrintingDevice: activePrintingDevice,
78565         brailleDevices: brailleDevices,
78566         activeBrailleDevice: activeBrailleDevice,
78567         audioDevices: audioDevices,
78568         activeAudioDevices: activeAudioDevices
78569     };
78570 };
78571
78572 });
78573 define('ripple/platform/phonegap/1.0.0/PhoneGap', function (require, exports, module) {
78574 /*
78575  *  Copyright 2011 Research In Motion Limited.
78576  *
78577  * Licensed under the Apache License, Version 2.0 (the "License");
78578  * you may not use this file except in compliance with the License.
78579  * You may obtain a copy of the License at
78580  *
78581  * http://www.apache.org/licenses/LICENSE-2.0
78582  *
78583  * Unless required by applicable law or agreed to in writing, software
78584  * distributed under the License is distributed on an "AS IS" BASIS,
78585  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78586  * See the License for the specific language governing permissions and
78587  * limitations under the License.
78588  */
78589 module.exports = {
78590     available: true
78591 };
78592
78593 });
78594 define('ripple/platform/phonegap/1.0.0/PointerAttributes', function (require, exports, module) {
78595 /*
78596  *  Copyright 2011 Research In Motion Limited.
78597  *
78598  * Licensed under the Apache License, Version 2.0 (the "License");
78599  * you may not use this file except in compliance with the License.
78600  * You may obtain a copy of the License at
78601  *
78602  * http://www.apache.org/licenses/LICENSE-2.0
78603  *
78604  * Unless required by applicable law or agreed to in writing, software
78605  * distributed under the License is distributed on an "AS IS" BASIS,
78606  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78607  * See the License for the specific language governing permissions and
78608  * limitations under the License.
78609  */
78610 module.exports = function (type, supportsMultiTouch, info) {
78611     return {
78612         type: type,
78613         supportsMultiTouch: supportsMultiTouch,
78614         info: info
78615     };
78616 };
78617
78618 });
78619 define('ripple/platform/phonegap/1.0.0/PowerAttributes', function (require, exports, module) {
78620 /*
78621  *  Copyright 2011 Research In Motion Limited.
78622  *
78623  * Licensed under the Apache License, Version 2.0 (the "License");
78624  * you may not use this file except in compliance with the License.
78625  * You may obtain a copy of the License at
78626  *
78627  * http://www.apache.org/licenses/LICENSE-2.0
78628  *
78629  * Unless required by applicable law or agreed to in writing, software
78630  * distributed under the License is distributed on an "AS IS" BASIS,
78631  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78632  * See the License for the specific language governing permissions and
78633  * limitations under the License.
78634  */
78635 module.exports = function (info, id, level, timeRemaining, isBattery, isCharging) {
78636     return {
78637         info: info,
78638         id: id,
78639         level: level,
78640         timeRemaining: timeRemaining,
78641         isBattery: isBattery,
78642         isCharging: isCharging
78643     };
78644 };
78645
78646 });
78647 define('ripple/platform/phonegap/1.0.0/PrintingDeviceAttributes', function (require, exports, module) {
78648 /*
78649  *  Copyright 2011 Research In Motion Limited.
78650  *
78651  * Licensed under the Apache License, Version 2.0 (the "License");
78652  * you may not use this file except in compliance with the License.
78653  * You may obtain a copy of the License at
78654  *
78655  * http://www.apache.org/licenses/LICENSE-2.0
78656  *
78657  * Unless required by applicable law or agreed to in writing, software
78658  * distributed under the License is distributed on an "AS IS" BASIS,
78659  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78660  * See the License for the specific language governing permissions and
78661  * limitations under the License.
78662  */
78663 module.exports = function (type, resolution, color, info) {
78664     return {
78665         type: type,
78666         resolution: resolution,
78667         color: color,
78668         info: info
78669     };
78670 };
78671
78672 });
78673 define('ripple/platform/phonegap/1.0.0/SensorAttributes', function (require, exports, module) {
78674 /*
78675  *  Copyright 2011 Research In Motion Limited.
78676  *
78677  * Licensed under the Apache License, Version 2.0 (the "License");
78678  * you may not use this file except in compliance with the License.
78679  * You may obtain a copy of the License at
78680  *
78681  * http://www.apache.org/licenses/LICENSE-2.0
78682  *
78683  * Unless required by applicable law or agreed to in writing, software
78684  * distributed under the License is distributed on an "AS IS" BASIS,
78685  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78686  * See the License for the specific language governing permissions and
78687  * limitations under the License.
78688  */
78689 module.exports = function (value, min, max, normalizedValue) {
78690     return {
78691         value: value,
78692         min: min,
78693         max: max,
78694         normalizedValue: normalizedValue
78695     };
78696 };
78697
78698 });
78699 define('ripple/platform/phonegap/1.0.0/StorageUnitAttributes', function (require, exports, module) {
78700 /*
78701  *  Copyright 2011 Research In Motion Limited.
78702  *
78703  * Licensed under the Apache License, Version 2.0 (the "License");
78704  * you may not use this file except in compliance with the License.
78705  * You may obtain a copy of the License at
78706  *
78707  * http://www.apache.org/licenses/LICENSE-2.0
78708  *
78709  * Unless required by applicable law or agreed to in writing, software
78710  * distributed under the License is distributed on an "AS IS" BASIS,
78711  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78712  * See the License for the specific language governing permissions and
78713  * limitations under the License.
78714  */
78715 module.exports = function (info, id, type, isWritable, capacity, availableCapacity, isRemoveable) {
78716     return {
78717         info: info,
78718         id: id,
78719         type: type,
78720         isWritable: isWritable,
78721         capacity: capacity,
78722         availableCapacity: availableCapacity,
78723         isRemoveable: isRemoveable
78724     };
78725 };
78726
78727 });
78728 define('ripple/platform/phonegap/1.0.0/SystemInfoOptions', function (require, exports, module) {
78729 /*
78730  *  Copyright 2011 Research In Motion Limited.
78731  *
78732  * Licensed under the Apache License, Version 2.0 (the "License");
78733  * you may not use this file except in compliance with the License.
78734  * You may obtain a copy of the License at
78735  *
78736  * http://www.apache.org/licenses/LICENSE-2.0
78737  *
78738  * Unless required by applicable law or agreed to in writing, software
78739  * distributed under the License is distributed on an "AS IS" BASIS,
78740  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78741  * See the License for the specific language governing permissions and
78742  * limitations under the License.
78743  */
78744 module.exports = function (highThreshold, lowThreshold, thresholdTarget, timeout, id) {
78745     return {
78746         highThreshold: highThreshold,
78747         lowThreshold: lowThreshold,
78748         thresholdTarget: thresholdTarget,
78749         timeout: timeout,
78750         id: id
78751     };
78752 };
78753
78754 });
78755 define('ripple/platform/phonegap/1.0.0/ThermalAttributes', function (require, exports, module) {
78756 /*
78757  *  Copyright 2011 Research In Motion Limited.
78758  *
78759  * Licensed under the Apache License, Version 2.0 (the "License");
78760  * you may not use this file except in compliance with the License.
78761  * You may obtain a copy of the License at
78762  *
78763  * http://www.apache.org/licenses/LICENSE-2.0
78764  *
78765  * Unless required by applicable law or agreed to in writing, software
78766  * distributed under the License is distributed on an "AS IS" BASIS,
78767  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78768  * See the License for the specific language governing permissions and
78769  * limitations under the License.
78770  */
78771 module.exports = function (info, id, state) {
78772     return {
78773         info: info,
78774         id: id,
78775         state: state
78776     };
78777 };
78778
78779 });
78780 define('ripple/platform/phonegap/1.0.0/VideoCodecAttributes', function (require, exports, module) {
78781 /*
78782  *  Copyright 2011 Research In Motion Limited.
78783  *
78784  * Licensed under the Apache License, Version 2.0 (the "License");
78785  * you may not use this file except in compliance with the License.
78786  * You may obtain a copy of the License at
78787  *
78788  * http://www.apache.org/licenses/LICENSE-2.0
78789  *
78790  * Unless required by applicable law or agreed to in writing, software
78791  * distributed under the License is distributed on an "AS IS" BASIS,
78792  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78793  * See the License for the specific language governing permissions and
78794  * limitations under the License.
78795  */
78796 module.exports = function (info, id, compFormats, containerFormats, hwAccel, profiles, frameTypes, rateTypes) {
78797     return {
78798         info: info,
78799         id: id,
78800         compFormats: compFormats,
78801         containerFormats: containerFormats,
78802         hwAccel: hwAccel,
78803         profiles: profiles,
78804         frameTypes: frameTypes,
78805         rateTypes: rateTypes
78806     };
78807 };
78808
78809 });
78810 define('ripple/platform/phonegap/1.0.0/accelerometer', function (require, exports, module) {
78811 /*
78812  *  Copyright 2011 Research In Motion Limited.
78813  *
78814  * Licensed under the Apache License, Version 2.0 (the "License");
78815  * you may not use this file except in compliance with the License.
78816  * You may obtain a copy of the License at
78817  *
78818  * http://www.apache.org/licenses/LICENSE-2.0
78819  *
78820  * Unless required by applicable law or agreed to in writing, software
78821  * distributed under the License is distributed on an "AS IS" BASIS,
78822  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78823  * See the License for the specific language governing permissions and
78824  * limitations under the License.
78825  */
78826 var Acceleration = require('ripple/platform/phonegap/1.0.0/Acceleration'),
78827     utils = require('ripple/utils'),
78828     event = require('ripple/event'),
78829     _accelerometerInfo = new Acceleration(),
78830     _watches = {},
78831     self;
78832
78833 module.exports = self = {
78834     getCurrentAcceleration: function (onSuccess, onError) {
78835         // TODO: implement error call if accelerometer is not available, to be driven by behaviours?
78836
78837         if (typeof onSuccess === "function") {
78838             setTimeout(function () {
78839                 // TODO: build facility to trigger onError() from emulator
78840                 // see pivotal item: https://www.pivotaltracker.com/story/show/7040343
78841                 onSuccess(utils.copy(_accelerometerInfo));
78842             }, 1);
78843         }
78844
78845     },
78846
78847     watchAcceleration: function (accelerometerSuccess, accelerometerError, accelerometerOptions) {
78848         var watchId = (new Date()).getTime().toString(),
78849             watchObj = {};
78850
78851
78852         if (accelerometerOptions &&
78853                 accelerometerOptions.frequency && typeof
78854                 accelerometerOptions.frequency === "number" &&
78855                 accelerometerOptions.frequency === Math.floor(accelerometerOptions.frequency)) {
78856
78857             watchObj = {
78858                 onSuccess: accelerometerSuccess,
78859                 onError: accelerometerError,
78860                 interval: accelerometerOptions.frequency
78861             };
78862
78863             _watches[watchId] = watchObj;
78864
78865             _watches[watchId].intervalId = setInterval(function () {
78866                 self.getCurrentAcceleration(_watches[watchId].onSuccess, _watches[watchId].onError);
78867             }, accelerometerOptions.frequency);
78868
78869         }
78870         else {
78871             if (typeof accelerometerError === "function") {
78872                 setTimeout(function () {
78873                     accelerometerError();
78874                 }, 1);
78875             }
78876         }
78877
78878         return watchId;
78879     },
78880
78881     clearWatch: function (watchId) {
78882         clearInterval(_watches[watchId].intervalId);
78883     }
78884 };
78885
78886 event.on("AccelerometerInfoChangedEvent", function (accelerometerInfo) {
78887     _accelerometerInfo.x = accelerometerInfo.accelerationIncludingGravity.x / 9.8;
78888     _accelerometerInfo.y = accelerometerInfo.accelerationIncludingGravity.y / 9.8;
78889     _accelerometerInfo.z = accelerometerInfo.accelerationIncludingGravity.z / 9.8;
78890     _accelerometerInfo.timestamp = (new Date()).getTime();
78891 });
78892
78893 });
78894 define('ripple/platform/phonegap/1.0.0/camera', function (require, exports, module) {
78895 /*
78896  *  Copyright 2011 Research In Motion Limited.
78897  *
78898  * Licensed under the Apache License, Version 2.0 (the "License");
78899  * you may not use this file except in compliance with the License.
78900  * You may obtain a copy of the License at
78901  *
78902  * http://www.apache.org/licenses/LICENSE-2.0
78903  *
78904  * Unless required by applicable law or agreed to in writing, software
78905  * distributed under the License is distributed on an "AS IS" BASIS,
78906  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78907  * See the License for the specific language governing permissions and
78908  * limitations under the License.
78909  */
78910 module.exports = {
78911     getPicture: function (cameraSuccess, cameraError, cameraOptions) {
78912         if (cameraError) {
78913             cameraError.apply(null, ["not implemented"]);
78914         }
78915         else {
78916             throw "not implemented";
78917         }
78918     }
78919 };
78920
78921 });
78922 define('ripple/platform/phonegap/1.0.0/compass', function (require, exports, module) {
78923 /*
78924  *  Copyright 2011 Research In Motion Limited.
78925  *
78926  * Licensed under the Apache License, Version 2.0 (the "License");
78927  * you may not use this file except in compliance with the License.
78928  * You may obtain a copy of the License at
78929  *
78930  * http://www.apache.org/licenses/LICENSE-2.0
78931  *
78932  * Unless required by applicable law or agreed to in writing, software
78933  * distributed under the License is distributed on an "AS IS" BASIS,
78934  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78935  * See the License for the specific language governing permissions and
78936  * limitations under the License.
78937  */
78938 var geo = require('ripple/geo');
78939
78940 function _getHeading() {
78941     return geo.getPositionInfo().heading;
78942 }
78943
78944 module.exports = {
78945     getCurrentHeading: function (compassSuccess, compassError, compassOptions) {
78946         setTimeout(function () {
78947             compassSuccess(_getHeading());
78948         }, 1);
78949     },
78950     watchHeading: function (compassSuccess, compassError, compassOptions) {
78951         compassOptions = compassOptions || {};
78952         return setInterval(function () {
78953             compassSuccess(_getHeading());
78954         }, compassOptions.frequency || 100);
78955     },
78956     clearWatch: function (watchId) {
78957         clearInterval(watchId);
78958     }
78959 };
78960
78961 });
78962 define('ripple/platform/phonegap/1.0.0/contacts', function (require, exports, module) {
78963 /*
78964  *  Copyright 2011 Research In Motion Limited.
78965  *
78966  * Licensed under the Apache License, Version 2.0 (the "License");
78967  * you may not use this file except in compliance with the License.
78968  * You may obtain a copy of the License at
78969  *
78970  * http://www.apache.org/licenses/LICENSE-2.0
78971  *
78972  * Unless required by applicable law or agreed to in writing, software
78973  * distributed under the License is distributed on an "AS IS" BASIS,
78974  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78975  * See the License for the specific language governing permissions and
78976  * limitations under the License.
78977  */
78978 var Contact = require('./Contact'),
78979     ContactName = require('./ContactName'),
78980     ContactError = require('./ContactError'),
78981     ContactField = require('./ContactField'),
78982     utils = require('ripple/utils'),
78983     db = require('ripple/db'),
78984     event = require('ripple/event'),
78985     _defaultContacts = 
78986     [{
78987         "id": Math.uuid(undefined, 16),
78988         "name": new ContactName("Brent Lintner"),
78989         "displayName": "Brent Lintner",
78990         "emails": [new ContactField("work", "brent@tinyhippos.com", false)]
78991     }, {
78992         "id": Math.uuid(undefined, 16),
78993         "name": new ContactName("PJ Lowe"),
78994         "displayName": "PJ Lowe",
78995         "emails": [new ContactField("work", "pj@tinyhippos.com", false)]
78996     }, {
78997         "id": Math.uuid(undefined, 16),
78998         "name": new ContactName("Dan Silivestru"),
78999         "displayName": "Dan Silivestru",
79000         "emails": [new ContactField("work", "dan@tinyhippos.com", false)]
79001     }, {
79002         "id": Math.uuid(undefined, 16),
79003         "name": new ContactName("Gord Tanner"),
79004         "displayName": "Gord Tanner",
79005         "emails": [new ContactField("work", "gord@tinyhippos.com", true)]
79006     }, {
79007         "id": Math.uuid(undefined, 16),
79008         "name": new ContactName("Mark McArdle"),
79009         "displayName": "Mark McArdle",
79010         "emails": [new ContactField("work", "mark@tinyhippos.com", false)]
79011     }],
79012     self;
79013
79014 function _error(callback, code, msg) {
79015     var e = new ContactError();
79016     e.code = code;
79017     e.message = msg;
79018     window.setTimeout(function () {
79019         callback(e);
79020     }, 1);
79021 }
79022
79023
79024 function _getContacts() {
79025     return db.retrieveObject("phonegap-contacts") || 
79026         _defaultContacts.map(function (person) {
79027             var contact = new Contact();
79028             contact.updated = new Date();
79029             utils.forEach(person, function (value, prop) {
79030                 contact[prop] = value;
79031             });
79032
79033             return contact;
79034         });
79035 }
79036
79037 function _saveContacts(contacts) {
79038     db.saveObject("phonegap-contacts", contacts);
79039 }
79040
79041 function _filtered(compare, options) {
79042     // this could be done a lot better..
79043     var found = false;
79044     if (!options.filter || options.filter === "") {
79045         found = true;
79046     } else if (typeof compare === "string" &&
79047               compare.match(new RegExp(".*" + options.filter + ".*", "i"))) {
79048         found = true;
79049     } else if (typeof compare === "object" || compare instanceof Array) {
79050         utils.forEach(compare, function (value) {
79051             if (!found) {
79052                 found = _filtered(value, options);
79053             }
79054         });
79055     }
79056     return found;
79057 }
79058
79059 event.on("phonegap-contact-save", function (contactProperties, success, error) {
79060     var contacts = _getContacts(),
79061         existsIndex = contacts.reduce(function (result, value, index) {
79062             return value.id === contactProperties.id ? index : result;
79063         }, -1),
79064         contact = existsIndex >= 0 ? contacts[existsIndex] : new Contact();
79065
79066     utils.mixin(contactProperties, contact);
79067     if (existsIndex < 0) {
79068         contacts.push(contact);
79069     }
79070     _saveContacts(contacts);
79071     success(contact);
79072 });
79073
79074 event.on("phonegap-contact-remove", function (id, success, error) {
79075     if (!id) {
79076         _error(error, ContactError.NOT_FOUND_ERROR, "id is falsy (" + id + ")");
79077     } else {
79078         var contacts = _getContacts(),
79079             toDelete = contacts.reduce(function (result, current, index) {
79080                 return current.id === id ? index : result;
79081             }, -1);
79082
79083         if (toDelete >= 0) {
79084             contacts.splice(toDelete, 1);
79085             _saveContacts(contacts);
79086             success();
79087         } else {
79088             _error(error, ContactError.NOT_FOUND_ERROR, "could not find contact with id (" + id + ")");
79089         }
79090     }
79091 });
79092
79093 self = module.exports = {
79094     create: function (properties) {
79095         var contact = new Contact();
79096         utils.forEach(properties, function (value, key) {
79097             contact[key] = value;
79098         });
79099         return contact;
79100     },
79101     find: function (fields, success, error, options) {
79102         var foundContacts = [],
79103             tempContact = self.create(),
79104             contacts = _getContacts(),
79105             errorFlag = false;
79106
79107         options = options || {};
79108
79109         // not a fan of error handling at the moment
79110         if (!fields || !("forEach" in fields)) {
79111             errorFlag = true;
79112             _error(error, ContactError.INVALID_ARGUMENT_ERROR, "missing contact fields array");
79113             return;
79114         }
79115
79116         // handle special case of ["*"] to return all fields
79117         if (fields.length === 1 && fields[0] === "*") {
79118             fields = utils.map(tempContact, function (v, k) {
79119                 return k;
79120             });
79121         }
79122
79123         fields.forEach(function (prop) {
79124             if (!(tempContact.hasOwnProperty(prop))) {
79125                 errorFlag = true;
79126                 _error(error, ContactError.INVALID_ARGUMENT_ERROR, "invalid contact field (" + prop + ")");
79127             }
79128         });
79129
79130         if (typeof success !== "function" && !errorFlag) {
79131             errorFlag = true;
79132             _error(error, ContactError.INVALID_ARGUMENT_ERROR, "missing success callback");
79133         }
79134
79135         if (errorFlag) {
79136             return;
79137         }
79138
79139         if (fields.length > 0) {
79140             contacts.forEach(function (contact, index) {
79141                 var newContact = utils.copy(contact);
79142
79143                 if (options && (!_filtered(contact, options) ||
79144                         options.updatedSince && contact.updated && contact.updated.getTime() < options.updatedSince.getTime())) {
79145                     return;
79146                 }
79147
79148                 utils.forEach(newContact, function (value, prop) {
79149                     if (typeof newContact[prop] !== "function" && prop !== "id" &&
79150                         !fields.some(function (field) {
79151                             return field === prop;
79152                         })) {
79153                         delete newContact[prop];
79154                     }
79155                 });
79156
79157                 foundContacts.push(newContact);
79158             });
79159         }
79160
79161         window.setTimeout(function () {
79162             // TODO: don't loop over entire db just to slice the array
79163             if (options.multiple === false) {
79164                 foundContacts = foundContacts.splice(0, 1);
79165             }
79166             success(foundContacts);
79167         }, 1);
79168     }
79169 };
79170
79171 });
79172 define('ripple/platform/phonegap/1.0.0/device', function (require, exports, module) {
79173 /*
79174  *  Copyright 2011 Research In Motion Limited.
79175  *
79176  * Licensed under the Apache License, Version 2.0 (the "License");
79177  * you may not use this file except in compliance with the License.
79178  * You may obtain a copy of the License at
79179  *
79180  * http://www.apache.org/licenses/LICENSE-2.0
79181  *
79182  * Unless required by applicable law or agreed to in writing, software
79183  * distributed under the License is distributed on an "AS IS" BASIS,
79184  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79185  * See the License for the specific language governing permissions and
79186  * limitations under the License.
79187  */
79188 var _self = {},
79189     event = require('ripple/event'),
79190     devices = require('ripple/devices');
79191
79192
79193 event.on("HardwareKey", function (key) {
79194     event.trigger("HardwareKeyDefault", [key]);
79195 });
79196
79197 _self.__defineGetter__("name", function () {
79198     return devices.getCurrentDevice().name;
79199 });
79200
79201 _self.__defineGetter__("platform", function () {
79202     return devices.getCurrentDevice().osName;
79203 });
79204
79205 _self.__defineGetter__("uuid", function () {
79206     return devices.getCurrentDevice().uuid;
79207 });
79208
79209 _self.__defineGetter__("version", function () {
79210     return devices.getCurrentDevice().osVersion;
79211 });
79212
79213 _self.phonegap = "placeholder string";
79214
79215 module.exports = _self;
79216
79217 });
79218 define('ripple/platform/phonegap/1.0.0/map', function (require, exports, module) {
79219 /*
79220  *  Copyright 2011 Research In Motion Limited.
79221  *
79222  * Licensed under the Apache License, Version 2.0 (the "License");
79223  * you may not use this file except in compliance with the License.
79224  * You may obtain a copy of the License at
79225  *
79226  * http://www.apache.org/licenses/LICENSE-2.0
79227  *
79228  * Unless required by applicable law or agreed to in writing, software
79229  * distributed under the License is distributed on an "AS IS" BASIS,
79230  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79231  * See the License for the specific language governing permissions and
79232  * limitations under the License.
79233  */
79234 module.exports = {
79235     show: function () {
79236         throw "not implemented";
79237     }
79238 };
79239
79240 });
79241 define('ripple/platform/phonegap/1.0.0/navigator', function (require, exports, module) {
79242 /*
79243  *  Copyright 2011 Research In Motion Limited.
79244  *
79245  * Licensed under the Apache License, Version 2.0 (the "License");
79246  * you may not use this file except in compliance with the License.
79247  * You may obtain a copy of the License at
79248  *
79249  * http://www.apache.org/licenses/LICENSE-2.0
79250  *
79251  * Unless required by applicable law or agreed to in writing, software
79252  * distributed under the License is distributed on an "AS IS" BASIS,
79253  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79254  * See the License for the specific language governing permissions and
79255  * limitations under the License.
79256  */
79257 var nav = require('ripple/platform/w3c/1.0/navigator'),
79258     event = require('ripple/event'),
79259     _console = require('ripple/console'),
79260     utils = require('ripple/utils'),
79261     emulatorBridge = require('ripple/emulatorBridge'),
79262     _self = {};
79263
79264 event.on("TinyHipposLoaded", function () {
79265     var doc = emulatorBridge.document(),
79266         evt = doc.createEvent("Events");
79267     evt.initEvent("deviceready", true, true);
79268     doc.dispatchEvent(evt);
79269     _console.log("fired deviceready event!");
79270 });
79271
79272 utils.mixin(nav, _self);
79273
79274 module.exports = _self;
79275
79276 });
79277 define('ripple/platform/phonegap/1.0.0/network', function (require, exports, module) {
79278 /*
79279  *  Copyright 2011 Research In Motion Limited.
79280  *
79281  * Licensed under the Apache License, Version 2.0 (the "License");
79282  * you may not use this file except in compliance with the License.
79283  * You may obtain a copy of the License at
79284  *
79285  * http://www.apache.org/licenses/LICENSE-2.0
79286  *
79287  * Unless required by applicable law or agreed to in writing, software
79288  * distributed under the License is distributed on an "AS IS" BASIS,
79289  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79290  * See the License for the specific language governing permissions and
79291  * limitations under the License.
79292  */
79293 var deviceSettings = require('ripple/deviceSettings'),
79294     _self = {
79295         connection: {
79296         }
79297     };
79298
79299 _self.connection.__defineGetter__("type", function () {
79300     return deviceSettings.retrieve("NetworkStatus.connectionType");
79301 });
79302
79303 module.exports = _self;
79304
79305 });
79306 define('ripple/platform/phonegap/1.0.0/notification', function (require, exports, module) {
79307 /*
79308  *  Copyright 2011 Research In Motion Limited.
79309  *
79310  * Licensed under the Apache License, Version 2.0 (the "License");
79311  * you may not use this file except in compliance with the License.
79312  * You may obtain a copy of the License at
79313  *
79314  * http://www.apache.org/licenses/LICENSE-2.0
79315  *
79316  * Unless required by applicable law or agreed to in writing, software
79317  * distributed under the License is distributed on an "AS IS" BASIS,
79318  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79319  * See the License for the specific language governing permissions and
79320  * limitations under the License.
79321  */
79322 var notifications = require('ripple/notifications'),
79323     constants = require('ripple/constants'),
79324     _console = require('ripple/console'),
79325     ui = require('ripple/ui'),
79326     goodVibrations = require('ripple/ui/plugins/goodVibrations');
79327
79328 module.exports = {
79329     alert: function (message, title, buttonName) {
79330         notifications.openNotification("normal", message);
79331     },
79332
79333     beep: function (times) {
79334         for (var i = times; i > 0; i--) {
79335             _console.log("beep!");
79336         }
79337         notifications.openNotification("normal", "BEEP x " + times);
79338     },
79339
79340     vibrate: function (milliseconds) {
79341         milliseconds = milliseconds || 500;
79342         goodVibrations.vibrateDevice(milliseconds);
79343     }
79344 };
79345
79346 });
79347 define('ripple/platform/phonegap/1.0.0/orientation', function (require, exports, module) {
79348 /*
79349  *  Copyright 2011 Research In Motion Limited.
79350  *
79351  * Licensed under the Apache License, Version 2.0 (the "License");
79352  * you may not use this file except in compliance with the License.
79353  * You may obtain a copy of the License at
79354  *
79355  * http://www.apache.org/licenses/LICENSE-2.0
79356  *
79357  * Unless required by applicable law or agreed to in writing, software
79358  * distributed under the License is distributed on an "AS IS" BASIS,
79359  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79360  * See the License for the specific language governing permissions and
79361  * limitations under the License.
79362  */
79363 module.exports = {
79364     currentOrientation: null,
79365     getCurrentOrientation: function (onSuccess, onFail) {
79366         throw "not implemented";
79367     },
79368     watchOrientation: function () {
79369         throw "not implemented";
79370     }
79371 };
79372
79373 });
79374 define('ripple/platform/phonegap/1.0.0/service', function (require, exports, module) {
79375 /*
79376  *  Copyright 2011 Research In Motion Limited.
79377  *
79378  * Licensed under the Apache License, Version 2.0 (the "License");
79379  * you may not use this file except in compliance with the License.
79380  * You may obtain a copy of the License at
79381  *
79382  * http://www.apache.org/licenses/LICENSE-2.0
79383  *
79384  * Unless required by applicable law or agreed to in writing, software
79385  * distributed under the License is distributed on an "AS IS" BASIS,
79386  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79387  * See the License for the specific language governing permissions and
79388  * limitations under the License.
79389  */
79390 // for form, but could probably just delete
79391 module.exports = {};
79392
79393 });
79394 define('ripple/platform/phonegap/1.0.0/sms', function (require, exports, module) {
79395 /*
79396  *  Copyright 2011 Research In Motion Limited.
79397  *
79398  * Licensed under the Apache License, Version 2.0 (the "License");
79399  * you may not use this file except in compliance with the License.
79400  * You may obtain a copy of the License at
79401  *
79402  * http://www.apache.org/licenses/LICENSE-2.0
79403  *
79404  * Unless required by applicable law or agreed to in writing, software
79405  * distributed under the License is distributed on an "AS IS" BASIS,
79406  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79407  * See the License for the specific language governing permissions and
79408  * limitations under the License.
79409  */
79410 module.exports = {
79411     send: function () {
79412         throw "not implemented";
79413     }
79414 };
79415
79416 });
79417 define('ripple/platform/phonegap/1.0.0/spec/config', function (require, exports, module) {
79418 /*
79419  *  Copyright 2011 Research In Motion Limited.
79420  *
79421  * Licensed under the Apache License, Version 2.0 (the "License");
79422  * you may not use this file except in compliance with the License.
79423  * You may obtain a copy of the License at
79424  *
79425  * http://www.apache.org/licenses/LICENSE-2.0
79426  *
79427  * Unless required by applicable law or agreed to in writing, software
79428  * distributed under the License is distributed on an "AS IS" BASIS,
79429  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79430  * See the License for the specific language governing permissions and
79431  * limitations under the License.
79432  */
79433 var constants = require('ripple/constants');
79434
79435 module.exports = {
79436     fileName: "config.xml",
79437     validateVersion: function (configValidationObject) {
79438         var valid = true;
79439         valid = !((!configValidationObject.widget.validationResult[0].attributes.xmlns.valid) ||
79440             (!configValidationObject.widget.validationResult[0].attributes["xmlns:gap"].valid));
79441
79442         return valid;
79443     },
79444     extractInfo: function (configValidationObject) {
79445         if (!configValidationObject) {
79446             return null;
79447         }
79448
79449         var widgetInfo = {};
79450
79451         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
79452         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
79453         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
79454         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
79455
79456         return widgetInfo;
79457     },
79458     schema: {
79459         rootElement: "widget",
79460         widget: {
79461             nodeName: "widget",
79462             required: true,
79463             occurrence: 1,
79464             attributes: {
79465                 xmlns: {
79466                     attributeName: "xmlns",
79467                     required: true,
79468                     type: "list",
79469                     listValues: ["http://www.w3.org/ns/widgets"]
79470                 },
79471                 "xmlns:gap": {
79472                     attributeName: "xmlns:gap",
79473                     required: true,
79474                     type: "list",
79475                     listValues: ["http://phonegap.com/ns/1.0"]
79476                 },
79477                 "xml:lang": {
79478                     attributeName: "xml:lang",
79479                     required: false,
79480                     type: "iso-language"
79481                 },
79482                 dir: {
79483                     attributeName: "dir",
79484                     required: false,
79485                     type: "list",
79486                     listValues: ["ltr", "rtl", "lro", "rlo"]
79487                 },
79488                 id: {
79489                     attributeName: "id",
79490                     required: false,
79491                     type: "string"
79492                 },
79493                 version: {
79494                     attributeName: "version",
79495                     required: false,
79496                     type: "string"
79497                 },
79498                 height: {
79499                     attributeName: "height",
79500                     required: false,
79501                     type: "integer"
79502                 },
79503                 width: {
79504                     attributeName: "width",
79505                     required: false,
79506                     type: "integer"
79507                 },
79508                 viewmodes: {
79509                     attributeName: "viewmodes",
79510                     required: false,
79511                     type: "list",
79512                     listValues: ["floating", "fullscreen"]
79513                 }
79514             },
79515             children: {
79516                 name: {
79517                     nodeName: "name",
79518                     required: false,
79519                     occurrence: 0,
79520                     type: "string",
79521                     attributes: {
79522                         "short": {
79523                             attributeName: "short",
79524                             type: "string",
79525                             required: false
79526                         },
79527                         "xml:lang": {
79528                             attributeName: "xml:lang",
79529                             type: "string",
79530                             required: false,
79531                             unique: true
79532                         }
79533                     }
79534                 },
79535                 description: {
79536                     nodeName: "description",
79537                     required: false,
79538                     occurrence: 0,
79539                     type: "string",
79540                     attributes: {
79541                         "xml:lang": {
79542                             attributeName: "xml:lang",
79543                             type: "string",
79544                             required: false,
79545                             unique: true
79546                         }
79547                     }
79548                 },
79549                 author: {
79550                     nodeName: "author",
79551                     required: false,
79552                     occurrence: 1,
79553                     type: "string",
79554                     attributes: {
79555                         email: {
79556                             attributeName: "email",
79557                             type: "regex",
79558                             required: false,
79559                             regex: constants.REGEX.EMAIL
79560                         },
79561                         href: {
79562                             attributeName: "href",
79563                             type: "regex",
79564                             required: false,
79565                             regex: constants.REGEX.URL
79566                         }
79567                     }
79568                 },
79569                 license: {
79570                     nodeName: "license",
79571                     required: false,
79572                     occurrence: 1,
79573                     type: "string",
79574                     attributes: {
79575                         href: {
79576                             attributeName: "href",
79577                             type: "regex",
79578                             required: false,
79579                             regex: constants.REGEX.URL
79580                         },
79581                         "xml:lang": {
79582                             attributeName: "xml:lang",
79583                             type: "string",
79584                             required: false,
79585                             unique: true
79586                         }
79587                     }
79588                 },
79589                 icon: {
79590                     nodeName: "icon",
79591                     required: false,
79592                     occurrence: 0,
79593                     attributes: {
79594                         src: {
79595                             attributeName: "src",
79596                             type: "string",
79597                             required: true
79598                         },
79599                         height: {
79600                             attributeName: "height",
79601                             required: false,
79602                             type: "integer"
79603                         },
79604                         width: {
79605                             attributeName: "width",
79606                             required: false,
79607                             type: "integer"
79608                         }
79609                     }
79610                 },
79611                 content: {
79612                     nodeName: "content",
79613                     required: false,
79614                     occurrence: 1,
79615                     attributes: {
79616                         src: {
79617                             attributeName: "src",
79618                             type: "string",
79619                             required: true
79620                         },
79621                         encoding: {
79622                             attributeName: "encoding",
79623                             type: "string",
79624                             required: false
79625                         },
79626                         type: {
79627                             attributeName: "type",
79628                             type: "string",
79629                             required: false
79630                         }
79631                     }
79632                 },
79633                 feature: {
79634                     nodeName: "feature",
79635                     required: false,
79636                     occurrence: 0,
79637                     attributes: {
79638                         name: {
79639                             attributeName: "name",
79640                             type: "list",
79641                             required: true,
79642                             listValues: ["http://api.phonegap.com/1.0/accelerometer", "http://api.phonegap.com/1.0/camera",
79643                                 "http://api.phonegap.com/1.0/compass", "http://api.phonegap.com/1.0/contacts", "http://api.phonegap.com/1.0/device",
79644                                 "http://api.phonegap.com/1.0/events", "http://api.phonegap.com/1.0/file", "http://api.phonegap.com/1.0/geolocation",
79645                                 "http://api.phonegap.com/1.0/media", "http://api.phonegap.com/1.0/network", "http://api.phonegap.com/1.0/notification",
79646                                 "http://api.phonegap.com/1.0/storage"]
79647                         },
79648                         required: {
79649                             attributeName: "required",
79650                             type: "boolean",
79651                             required: false
79652                         }
79653                     }
79654                 },
79655                 preference: {
79656                     nodeName: "preference",
79657                     required: false,
79658                     occurrence: 0,
79659                     attributes: {
79660                         name: {
79661                             attributeName: "name",
79662                             type: "string",
79663                             required: true
79664                         },
79665                         value: {
79666                             type: "string",
79667                             attributeName: "value",
79668                             required: false
79669                         },
79670                         readonly: {
79671                             attributeName: "readonly",
79672                             type: "boolean",
79673                             required: false
79674                         }
79675                     }
79676                 }
79677             }
79678         }
79679     }
79680 };
79681
79682 });
79683 define('ripple/platform/phonegap/1.0.0/spec/device', function (require, exports, module) {
79684 /*
79685  *  Copyright 2011 Research In Motion Limited.
79686  *
79687  * Licensed under the Apache License, Version 2.0 (the "License");
79688  * you may not use this file except in compliance with the License.
79689  * You may obtain a copy of the License at
79690  *
79691  * http://www.apache.org/licenses/LICENSE-2.0
79692  *
79693  * Unless required by applicable law or agreed to in writing, software
79694  * distributed under the License is distributed on an "AS IS" BASIS,
79695  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79696  * See the License for the specific language governing permissions and
79697  * limitations under the License.
79698  */
79699 var event = require('ripple/event');
79700
79701 module.exports = {
79702     "NetworkStatus": {
79703         "connectionType": {
79704             "name": "Connection Type",
79705             "control": {
79706                 "type": "select",
79707                 "value": "ethernet"
79708             },
79709             "options": {
79710                 "unknown": "UNKNOWN",
79711                 "ethernet": "ETHERNET",
79712                 "wifi": "WIFI",
79713                 "2g": "CELL_2G",
79714                 "3g": "CELL_3G",
79715                 "4g": "CELL_4G",
79716                 "none": "none"
79717             },
79718             "callback": function (setting) {
79719                 var connected = setting !== "none";
79720                 require('ripple/bus').send("network", connected);
79721             }
79722         },
79723         "lag": {
79724             "name": "Lag the network",
79725             "control": {
79726                 type: "checkbox",
79727                 value: false
79728             },
79729             "callback": function (setting) {
79730                 require('ripple/bus').send("lag", setting);
79731             }
79732         },
79733     }
79734 };
79735
79736 });
79737 define('ripple/platform/phonegap/1.0.0/spec/events', function (require, exports, module) {
79738 function _fires(name, data) {
79739     return function () {
79740         var doc = require("ripple/emulatorBridge").document(),
79741             evt = doc.createEvent("Events");
79742
79743         evt.initEvent(name, true, false);
79744         doc.dispatchEvent(evt);
79745     };
79746 }
79747
79748 module.exports = {
79749     "deviceready": {
79750         callback: _fires("deviceready")
79751     },
79752     "backbutton": {
79753         callback: _fires("backbutton")
79754     },
79755     "menubutton": {
79756         callback: _fires("menubutton")
79757     },
79758     "pause": {
79759         callback: _fires("pause")
79760     },
79761     "resume": {
79762         callback: _fires("resume")
79763     },
79764     "searchbutton": {
79765         callback: _fires("searchbutton")
79766     },
79767     "online": {
79768         callback: _fires("online")
79769     },
79770     "offline": {
79771         callback: _fires("offline")
79772     }
79773 };
79774
79775 });
79776 define('ripple/platform/phonegap/1.0.0/spec/ui', function (require, exports, module) {
79777 /*
79778  *  Copyright 2011 Research In Motion Limited.
79779  *
79780  * Licensed under the Apache License, Version 2.0 (the "License");
79781  * you may not use this file except in compliance with the License.
79782  * You may obtain a copy of the License at
79783  *
79784  * http://www.apache.org/licenses/LICENSE-2.0
79785  *
79786  * Unless required by applicable law or agreed to in writing, software
79787  * distributed under the License is distributed on an "AS IS" BASIS,
79788  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79789  * See the License for the specific language governing permissions and
79790  * limitations under the License.
79791  */
79792 module.exports = {
79793     plugins: [
79794         "accelerometer",
79795         "deviceSettings",
79796         "geoView",
79797         "widgetConfig",
79798         "platformEvents"
79799     ]
79800 };
79801
79802 });
79803 define('ripple/platform/phonegap/1.0.0/spec', function (require, exports, module) {
79804 module.exports = {
79805     id: "phonegap",
79806     version: "1.0.0",
79807     name: "PhoneGap",
79808     type: "platform",
79809
79810     persistencePrefix: "phonegap-",
79811
79812     config: require('ripple/platform/phonegap/1.0.0/spec/config'),
79813     device: require('ripple/platform/phonegap/1.0.0/spec/device'),
79814     ui: require('ripple/platform/phonegap/1.0.0/spec/ui'),
79815     events: require('ripple/platform/phonegap/1.0.0/spec/events'),
79816
79817     initialize: function () { },
79818
79819     objects: {
79820         PhoneGap: {
79821             path: "phonegap/1.0.0/PhoneGap"
79822         },
79823         Coordinates: {
79824             path: "w3c/1.0/Coordinates"
79825         },
79826         Position: {
79827             path: "w3c/1.0/Position"
79828         },
79829         PositionError: {
79830             path: "w3c/1.0/PositionError"
79831         },
79832         Acceleration: {
79833             path: "phonegap/1.0.0/Acceleration"
79834         },
79835         navigator: {
79836             path: "phonegap/1.0.0/navigator",
79837             children: {
79838                 accelerometer: {
79839                     path: "phonegap/1.0.0/accelerometer"
79840                 },
79841                 geolocation: {
79842                     path: "w3c/1.0/geolocation"
79843                 },
79844                 notification: {
79845                     path: "phonegap/1.0.0/notification"
79846                 },
79847                 contacts: {
79848                     path: "phonegap/1.0.0/contacts"
79849                 },
79850                 network: {
79851                     path: "phonegap/1.0.0/network"
79852                 },
79853                 camera: {
79854                     path: "phonegap/1.0.0/camera"
79855                 },
79856                 sms: {
79857                     path: "phonegap/1.0.0/sms"
79858                 },
79859                 telephony: {
79860                     path: "phonegap/1.0.0/telephony"
79861                 },
79862                 map: {
79863                     path: "phonegap/1.0.0/map"
79864                 },
79865                 orientation: {
79866                     path: "phonegap/1.0.0/orientation"
79867                 },
79868                 system: {
79869                     path: "phonegap/1.0.0/system"
79870                 },
79871                 compass: {
79872                     path: "phonegap/1.0.0/compass"
79873                 }
79874             }
79875         },
79876         ContactError: {
79877             path: "phonegap/1.0.0/ContactError"
79878         },
79879         Contact: {
79880             path: "phonegap/1.0.0/Contact"
79881         },
79882         ContactName: {
79883             path: "phonegap/1.0.0/ContactName"
79884         },
79885         ContactAccount: {
79886             path: "phonegap/1.0.0/ContactAccount"
79887         },
79888         ContactAddress: {
79889             path: "phonegap/1.0.0/ContactAddress"
79890         },
79891         ContactOrganization: {
79892             path: "phonegap/1.0.0/ContactOrganization"
79893         },
79894         ContactFindOptions: {
79895             path: "phonegap/1.0.0/ContactFindOptions"
79896         },
79897         ContactField: {
79898             path: "phonegap/1.0.0/ContactField"
79899         },
79900         NetworkStatus: {
79901             path: "phonegap/1.0.0/NetworkStatus"
79902         },
79903         device: {
79904             path: "phonegap/1.0.0/device"
79905         },
79906         SystemInfoOptions: {
79907             path: "phonegap/1.0.0/SystemInfoOptions"
79908         },
79909         PowerAttributes: {
79910             path: "phonegap/1.0.0/PowerAttributes"
79911         },
79912         CPUAttributes: {
79913             path: "phonegap/1.0.0/CPUAttributes"
79914         },
79915         ThermalAttributes: {
79916             path: "phonegap/1.0.0/ThermalAttributes"
79917         },
79918         NetworkAttributes: {
79919             path: "phonegap/1.0.0/NetworkAttributes"
79920         },
79921         Connection: {
79922             path: "phonegap/1.0.0/Connection"
79923         },
79924         ConnectionAttributes: {
79925             path: "phonegap/1.0.0/ConnectionAttributes"
79926         },
79927         SensorAttributes: {
79928             path: "phonegap/1.0.0/SensorAttributes"
79929         },
79930         AVCodecsAttributes: {
79931             path: "phonegap/1.0.0/AVCodecsAttributes"
79932         },
79933         AudioCodecAttributes: {
79934             path: "phonegap/1.0.0/AudioCodecAttributes"
79935         },
79936         VideoCodecAttributes: {
79937             path: "phonegap/1.0.0/VideoCodecAttributes"
79938         },
79939         StorageUnitAttributes: {
79940             path: "phonegap/1.0.0/StorageUnitAttributes"
79941         },
79942         InputDevicesAttributes: {
79943             path: "phonegap/1.0.0/InputDevicesAttributes"
79944         },
79945         OutputDevicesAttributes: {
79946             path: "phonegap/1.0.0/OutputDevicesAttributes"
79947         },
79948         DisplayDeviceAttributes: {
79949             path: "phonegap/1.0.0/DisplayDeviceAttributes"
79950         },
79951         AudioDeviceAttributes: {
79952             path: "phonegap/1.0.0/AudioDeviceAttributes"
79953         },
79954         PrintingDeviceAttributes: {
79955             path: "phonegap/1.0.0/PrintingDeviceAttributes"
79956         },
79957         BrailleDeviceAttributes: {
79958             path: "phonegap/1.0.0/BrailleDeviceAttributes"
79959         },
79960         PointerAttributes: {
79961             path: "phonegap/1.0.0/PointerAttributes"
79962         },
79963         KeyboardAttributes: {
79964             path: "phonegap/1.0.0/KeyboardAttributes"
79965         },
79966         CameraAttributes: {
79967             path: "phonegap/1.0.0/CameraAttributes"
79968         },
79969         MicrophoneAttributes: {
79970             path: "phonegap/1.0.0/MicrophoneAttributes"
79971         }
79972     }
79973
79974 };
79975
79976 });
79977 define('ripple/platform/phonegap/1.0.0/system', function (require, exports, module) {
79978 module.exports = {
79979     get: function () {
79980         throw "not implemented";
79981     },
79982     has: function () {
79983         throw "not implemented";
79984     },
79985     monitor: function () {
79986         throw "not implemented";
79987     }
79988 };
79989
79990 });
79991 define('ripple/platform/phonegap/1.0.0/telephony', function (require, exports, module) {
79992 /*
79993  *  Copyright 2011 Research In Motion Limited.
79994  *
79995  * Licensed under the Apache License, Version 2.0 (the "License");
79996  * you may not use this file except in compliance with the License.
79997  * You may obtain a copy of the License at
79998  *
79999  * http://www.apache.org/licenses/LICENSE-2.0
80000  *
80001  * Unless required by applicable law or agreed to in writing, software
80002  * distributed under the License is distributed on an "AS IS" BASIS,
80003  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80004  * See the License for the specific language governing permissions and
80005  * limitations under the License.
80006  */
80007 module.exports = {
80008     send: function () {
80009         throw "not implemented";
80010     }
80011 };
80012
80013 });
80014 define('ripple/platform/spec', function (require, exports, module) {
80015 /*
80016  *  Copyright 2011 Research In Motion Limited.
80017  *
80018  * Licensed under the Apache License, Version 2.0 (the "License");
80019  * you may not use this file except in compliance with the License.
80020  * You may obtain a copy of the License at
80021  *
80022  * http://www.apache.org/licenses/LICENSE-2.0
80023  *
80024  * Unless required by applicable law or agreed to in writing, software
80025  * distributed under the License is distributed on an "AS IS" BASIS,
80026  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80027  * See the License for the specific language governing permissions and
80028  * limitations under the License.
80029  */
80030 module.exports = {
80031     //"phonegap": {"1.0.0": require('ripple/platform/phonegap/1.0.0/spec')},
80032     "tizen": {"2.0": require('ripple/platform/tizen/2.0/spec')},
80033     "ivi": {"3.0": require('ripple/platform/ivi/3.0/spec')},
80034     //"cordova": {"2.0.0": require('ripple/platform/cordova/2.0.0/spec')},
80035     //"webworks.bb10": {"1.0.0": require('ripple/platform/webworks.bb10/1.0.0/spec')},
80036     //"webworks.handset": {"2.0.0": require('ripple/platform/webworks.handset/2.0.0/spec')},
80037     //"webworks.tablet": {"2.0.0": require('ripple/platform/webworks.tablet/2.0.0/spec')},
80038     //"web": {"default": require('ripple/platform/web/default/spec')},
80039
80040     "get": function (name, version) {
80041         var platform = module.exports[name] || {};
80042         return (platform[version] || platform[Object.keys(platform)[0]]);
80043     }
80044 };
80045
80046 });
80047 define('ripple/platform/tizen/2.0/AccountBase', function (require, exports, module) {
80048 /*
80049  *  Copyright 2012 Intel Corporation.
80050  *
80051  * Licensed under the Apache License, Version 2.0 (the "License");
80052  * you may not use this file except in compliance with the License.
80053  * You may obtain a copy of the License at
80054  *
80055  * http://www.apache.org/licenses/LICENSE-2.0
80056  *
80057  * Unless required by applicable law or agreed to in writing, software
80058  * distributed under the License is distributed on an "AS IS" BASIS,
80059  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80060  * See the License for the specific language governing permissions and
80061  * limitations under the License.
80062  */
80063
80064 module.exports = function (appId, userName, displayName, service) {
80065     var _self,
80066         _id = Math.uuid(null, 16);
80067
80068     _self = {
80069         appId : appId || "",
80070         userName : userName || "",
80071         displayName : displayName || "",
80072         service : service || {}
80073     };
80074
80075     _self.__defineGetter__("id", function () {
80076         return _id;
80077     });
80078
80079     return _self;
80080 };
80081
80082 });
80083 define('ripple/platform/tizen/2.0/AccountService', function (require, exports, module) {
80084 /*
80085  *  Copyright 2012 Intel Corporation.
80086  *
80087  * Licensed under the Apache License, Version 2.0 (the "License");
80088  * you may not use this file except in compliance with the License.
80089  * You may obtain a copy of the License at
80090  *
80091  * http://www.apache.org/licenses/LICENSE-2.0
80092  *
80093  * Unless required by applicable law or agreed to in writing, software
80094  * distributed under the License is distributed on an "AS IS" BASIS,
80095  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80096  * See the License for the specific language governing permissions and
80097  * limitations under the License.
80098  */
80099
80100 module.exports = function (serviceName, serviceType, tag, displayName, icon, settings) {
80101     var _self,
80102         _id = Math.uuid(null, 16);
80103
80104     _self = {
80105         serviceName : serviceName || "",
80106         serviceType : serviceType || "",
80107         displayName : displayName || null,
80108         icon : icon || null,
80109         settings : settings || null,
80110         tag : tag || []
80111     };
80112
80113     _self.__defineGetter__("id", function () {
80114         return _id;
80115     });
80116
80117     return _self;
80118 };
80119
80120 });
80121 define('ripple/platform/tizen/2.0/AlarmAbsolute', function (require, exports, module) {
80122 /*
80123  *  Copyright 2012 Intel Corporation.
80124  *
80125  * Licensed under the Apache License, Version 2.0 (the "License");
80126  * you may not use this file except in compliance with the License.
80127  * You may obtain a copy of the License at
80128  *
80129  * http://www.apache.org/licenses/LICENSE-2.0
80130  *
80131  * Unless required by applicable law or agreed to in writing, software
80132  * distributed under the License is distributed on an "AS IS" BASIS,
80133  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80134  * See the License for the specific language governing permissions and
80135  * limitations under the License.
80136  */
80137
80138 var AlarmBase = require('ripple/platform/tizen/2.0/AlarmBase'),
80139     t = require('ripple/platform/tizen/2.0/typecast'),
80140     _byDayValue = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"],
80141     PERIOD_WEEK = (7 * 24 * 60 * 60), MILLI_SECOND = 1000,
80142     AlarmAbsolute;
80143
80144 AlarmAbsolute = function () {
80145     var alarm, period = null, daysOfTheWeek = [], ascDays = [], voc, date;
80146
80147     function getScheduleDateByPeriod(current, date, period) {
80148         var diff = period * MILLI_SECOND,
80149             triggerDate = new Date(date);
80150
80151         while (current > (triggerDate - MILLI_SECOND)) { // In advance 1s - MILLI_SECOND
80152             triggerDate.setTime(triggerDate.getTime() + diff);
80153         }
80154         return triggerDate;
80155     }
80156
80157     function getSchedulteDateByDay(current, triggerTime, startDay, endDay) {
80158         startDay = (7 + (endDay - startDay)) % 7;
80159         current.setHours(triggerTime.getHours());
80160         current.setMinutes(triggerTime.getMinutes());
80161         current.setSeconds(triggerTime.getSeconds());
80162         current.setMilliseconds(triggerTime.getMilliseconds());
80163         current.setDate(current.getDate() + startDay);
80164         return current;
80165     }
80166
80167     function getAscDays() { // Get asc order array
80168         for (var i in daysOfTheWeek) {
80169             ascDays.push(_byDayValue.lastIndexOf(daysOfTheWeek[i]));
80170         }
80171         return ascDays.sort();
80172     }
80173
80174     /*
80175      * Return
80176      *     true:  A is bigger than B
80177      *     false: otherwise
80178      */
80179     function compareTime(current, triggerTime) {
80180         var diff = current.getHours() - triggerTime.getHours();
80181         if (diff !== 0)
80182             return (diff > 0);
80183
80184         diff = current.getMinutes() - triggerTime.getMinutes();
80185         if (diff !== 0)
80186             return (diff > 0);
80187
80188         diff = current.getSeconds() - triggerTime.getSeconds();
80189         if (diff < -1) // Delay 1s
80190             return false;
80191
80192         return true;
80193     }
80194
80195     alarm = new AlarmBase(this);
80196
80197     voc = [
80198         function (_date, _daysOfTheWeek) {
80199             date = _date;
80200             daysOfTheWeek = _daysOfTheWeek;
80201             period = PERIOD_WEEK;
80202         },
80203         function (_date, _period) {
80204             date = _date;
80205             period = _period;
80206         },
80207         function (_date) {
80208             date = _date;
80209         }
80210     ];
80211
80212     t.AlarmAbsolute(arguments, this, voc);
80213
80214     this.getNextScheduledDate = function () {
80215         var current = new Date(),
80216             diff, isPass, today, total, i, nextDate;
80217
80218         diff = current - date;
80219         if (diff < -1000) // Advance 1s
80220             return date; // Before first trigger, return date
80221
80222         if (period === null)
80223             return null;
80224
80225         if (period !== PERIOD_WEEK)
80226             return getScheduleDateByPeriod(current, date, period); // Repeat by period
80227
80228         today = current.getDay(); // 0~6
80229         ascDays = getAscDays();
80230         total = ascDays.length;
80231
80232         if ((ascDays[0] <= today) && (today <= ascDays[total - 1])) { // Today out of ascDays
80233             for (i in ascDays) { // Today in ascDays
80234                 if (ascDays[i] < today) {
80235                     continue;
80236                 } else if (ascDays[i] > today) {
80237                     nextDate = ascDays[i];
80238                     break;
80239                 } else {
80240                     isPass = compareTime(current, date); // Is triggerTime pass
80241                     if (isPass) {
80242                         nextDate = ascDays[(i < total - 1) ? (parseInt(i, 10) + 1) : 0];
80243                     } else {
80244                         nextDate = today;
80245                     }
80246                     break;
80247                 }
80248             }
80249         } else {
80250             nextDate = ascDays[0];
80251         }
80252
80253         return getSchedulteDateByDay(current, date, today, nextDate);
80254     };
80255
80256     this.__defineGetter__("date", function () {
80257         return new Date(date);
80258     });
80259
80260     this.__defineGetter__("period", function () {
80261         return period;
80262     });
80263
80264     this.__defineGetter__("daysOfTheWeek", function () {
80265         return daysOfTheWeek;
80266     });
80267 };
80268
80269 module.exports = AlarmAbsolute;
80270
80271 });
80272 define('ripple/platform/tizen/2.0/AlarmBase', function (require, exports, module) {
80273 /*
80274  *  Copyright 2012 Intel Corporation.
80275  *
80276  * Licensed under the Apache License, Version 2.0 (the "License");
80277  * you may not use this file except in compliance with the License.
80278  * You may obtain a copy of the License at
80279  *
80280  * http://www.apache.org/licenses/LICENSE-2.0
80281  *
80282  * Unless required by applicable law or agreed to in writing, software
80283  * distributed under the License is distributed on an "AS IS" BASIS,
80284  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80285  * See the License for the specific language governing permissions and
80286  * limitations under the License.
80287  */
80288
80289 module.exports = function (self) {
80290     self = self || this;
80291
80292     self.__defineGetter__("id", function () {
80293         return null;
80294     });
80295 };
80296
80297 });
80298 define('ripple/platform/tizen/2.0/AlarmRelative', function (require, exports, module) {
80299 /*
80300  *  Copyright 2012 Intel Corporation.
80301  *
80302  * Licensed under the Apache License, Version 2.0 (the "License");
80303  * you may not use this file except in compliance with the License.
80304  * You may obtain a copy of the License at
80305  *
80306  * http://www.apache.org/licenses/LICENSE-2.0
80307  *
80308  * Unless required by applicable law or agreed to in writing, software
80309  * distributed under the License is distributed on an "AS IS" BASIS,
80310  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80311  * See the License for the specific language governing permissions and
80312  * limitations under the License.
80313  */
80314
80315 var AlarmBase = require('ripple/platform/tizen/2.0/AlarmBase'),
80316     t = require('ripple/platform/tizen/2.0/typecast'),
80317     AlarmRelative;
80318
80319 AlarmRelative = function (delay, period) {
80320     var alarm, date;
80321
80322     t.AlarmRelative(arguments, this);
80323
80324     alarm  = new AlarmBase(this);
80325     period = period || null;
80326     date   = new Date(); // Alarm settime
80327
80328     this.getRemainingSeconds = function () {
80329         var current, diff, triggerDate, MILLI_SECOND = 1000;
80330         current     = new Date();
80331         triggerDate = new Date(delay * MILLI_SECOND + date.getTime()); // First triggerDate
80332         diff        = Math.round((triggerDate - current) / MILLI_SECOND);
80333
80334         if (diff > 0) // Before first trigger
80335             return diff;
80336
80337         if (period === null)
80338             return null; // Alarm is expired
80339
80340         while (current - triggerDate >= 0) { // Trigger repeatly
80341             triggerDate = new Date(period * MILLI_SECOND + triggerDate.getTime());
80342         }
80343         diff = Math.round(((triggerDate - current) / MILLI_SECOND));
80344         return diff;
80345     };
80346
80347     this.__defineGetter__("delay", function () {
80348         return delay;
80349     });
80350
80351     this.__defineGetter__("period", function () {
80352         return period;
80353     });
80354 };
80355
80356 module.exports = AlarmRelative;
80357
80358 });
80359 define('ripple/platform/tizen/2.0/ApplicationControl', function (require, exports, module) {
80360 /*
80361  *  Copyright 2013 Intel Corporation.
80362  *
80363  * Licensed under the Apache License, Version 2.0 (the "License");
80364  * you may not use this file except in compliance with the License.
80365  * You may obtain a copy of the License at
80366  *
80367  * http://www.apache.org/licenses/LICENSE-2.0
80368  *
80369  * Unless required by applicable law or agreed to in writing, software
80370  * distributed under the License is distributed on an "AS IS" BASIS,
80371  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80372  * See the License for the specific language governing permissions and
80373  * limitations under the License.
80374  */
80375
80376 var t = require('ripple/platform/tizen/2.0/typecast'),
80377     ApplicationControlData = require('ripple/platform/tizen/2.0/ApplicationControlData');
80378
80379 var ApplicationControl = function (operation, uri, mime, category, data) {
80380     var applicationControl = {}, i;
80381
80382     t.ApplicationControl(arguments, this);
80383
80384     applicationControl.operation = operation;
80385     applicationControl.uri       = uri || null;
80386     applicationControl.mime      = mime || null;
80387     applicationControl.category  = category || null;
80388     applicationControl.data      = [];
80389
80390     if (data) {
80391         for (i in data) {
80392             applicationControl.data[i] = new ApplicationControlData(data[i].key,
80393                     data[i].value);
80394         }
80395     }
80396
80397     this.__defineGetter__("operation", function () {
80398         return applicationControl.operation;
80399     });
80400     this.__defineSetter__("operation", function (val) {
80401         try {
80402             applicationControl.operation = t.DOMString(val);
80403         } catch (e) {
80404         }
80405     });
80406
80407     this.__defineGetter__("uri", function () {
80408         return applicationControl.uri;
80409     });
80410     this.__defineSetter__("uri", function (val) {
80411         try {
80412             applicationControl.uri = t.DOMString(val, "?");
80413         } catch (e) {
80414         }
80415     });
80416
80417     this.__defineGetter__("mime", function () {
80418         return applicationControl.mime;
80419     });
80420     this.__defineSetter__("mime", function (val) {
80421         try {
80422             applicationControl.mime = t.DOMString(val, "?");
80423         } catch (e) {
80424         }
80425     });
80426
80427     this.__defineGetter__("category", function () {
80428         return applicationControl.category;
80429     });
80430     this.__defineSetter__("category", function (val) {
80431         try {
80432             applicationControl.category = t.DOMString(val, "?");
80433         } catch (e) {
80434         }
80435     });
80436
80437     this.__defineGetter__("data", function () {
80438         return applicationControl.data;
80439     });
80440     this.__defineSetter__("data", function (val) {
80441         var i;
80442
80443         try {
80444             t.ApplicationControlData(val, "[]");
80445             for (i in val) {
80446                 applicationControl.data[i] = new ApplicationControlData(
80447                         val[i].key, val[i].value);
80448             }
80449         } catch (e) {
80450         }
80451     });
80452 };
80453
80454 module.exports = ApplicationControl;
80455
80456 });
80457 define('ripple/platform/tizen/2.0/ApplicationControlData', function (require, exports, module) {
80458 /*
80459  *  Copyright 2013 Intel Corporation.
80460  *
80461  * Licensed under the Apache License, Version 2.0 (the "License");
80462  * you may not use this file except in compliance with the License.
80463  * You may obtain a copy of the License at
80464  *
80465  * http://www.apache.org/licenses/LICENSE-2.0
80466  *
80467  * Unless required by applicable law or agreed to in writing, software
80468  * distributed under the License is distributed on an "AS IS" BASIS,
80469  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80470  * See the License for the specific language governing permissions and
80471  * limitations under the License.
80472  */
80473
80474 var t = require('ripple/platform/tizen/2.0/typecast'),
80475     ApplicationControlData;
80476
80477 ApplicationControlData = function (key, value) {
80478     var applicationControlData = {};
80479
80480     t.ApplicationControlData(arguments, this);
80481
80482     applicationControlData.key   = key;
80483     applicationControlData.value = value;
80484
80485     this.__defineGetter__("key", function () {
80486         return applicationControlData.key;
80487     });
80488     this.__defineSetter__("key", function (val) {
80489         try {
80490             applicationControlData.key = t.DOMString(val);
80491         } catch (e) {
80492         }
80493     });
80494
80495     this.__defineGetter__("value", function () {
80496         return applicationControlData.value;
80497     });
80498     this.__defineSetter__("value", function (val) {
80499         try {
80500             applicationControlData.value = t.DOMString(val, '[]');
80501         } catch (e) {
80502         }
80503     });
80504 };
80505
80506 module.exports = ApplicationControlData;
80507
80508 });
80509 define('ripple/platform/tizen/2.0/AttributeFilter', function (require, exports, module) {
80510 /*
80511  *  Copyright 2013 Intel Corporation.
80512  *
80513  * Licensed under the Apache License, Version 2.0 (the "License");
80514  * you may not use this file except in compliance with the License.
80515  * You may obtain a copy of the License at
80516  *
80517  * http://www.apache.org/licenses/LICENSE-2.0
80518  *
80519  * Unless required by applicable law or agreed to in writing, software
80520  * distributed under the License is distributed on an "AS IS" BASIS,
80521  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80522  * See the License for the specific language governing permissions and
80523  * limitations under the License.
80524  */
80525
80526 var t = require('ripple/platform/tizen/2.0/typecast'),
80527     AttributeFilter;
80528
80529 AttributeFilter = function (attributeName, matchFlag, matchValue) {
80530     var attributeFilter = {};
80531
80532     t.AttributeFilter(arguments, this);
80533
80534     attributeFilter.attributeName = attributeName;
80535     attributeFilter.matchFlag     = matchFlag || "EXACTLY";
80536     attributeFilter.matchValue    = (matchFlag === "EXISTS") ? null :
80537             matchValue || null;
80538
80539     this.__defineGetter__("attributeName", function () {
80540         return attributeFilter.attributeName;
80541     });
80542     this.__defineSetter__("attributeName", function (val) {
80543         try {
80544             attributeFilter.attributeName = t.DOMString(val);
80545         } catch (e) {
80546         }
80547     });
80548
80549     this.__defineGetter__("matchFlag", function () {
80550         return attributeFilter.matchFlag;
80551     });
80552     this.__defineSetter__("matchFlag", function (val) {
80553         try {
80554             attributeFilter.matchFlag = t.FilterMatchFlag(val);
80555         } catch (e) {
80556         }
80557     });
80558
80559     this.__defineGetter__("matchValue", function () {
80560         return attributeFilter.matchValue;
80561     });
80562     this.__defineSetter__("matchValue", function (val) {
80563         try {
80564             if (attributeFilter.matchFlag === "EXISTS") {
80565                 return;
80566             }
80567             attributeFilter.matchValue = t.any(val);
80568         } catch (e) {
80569         }
80570     });
80571 };
80572
80573 module.exports = AttributeFilter;
80574
80575 });
80576 define('ripple/platform/tizen/2.0/AttributeRangeFilter', function (require, exports, module) {
80577 /*
80578  *  Copyright 2013 Intel Corporation.
80579  *
80580  * Licensed under the Apache License, Version 2.0 (the "License");
80581  * you may not use this file except in compliance with the License.
80582  * You may obtain a copy of the License at
80583  *
80584  * http://www.apache.org/licenses/LICENSE-2.0
80585  *
80586  * Unless required by applicable law or agreed to in writing, software
80587  * distributed under the License is distributed on an "AS IS" BASIS,
80588  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80589  * See the License for the specific language governing permissions and
80590  * limitations under the License.
80591  */
80592
80593 var t = require('ripple/platform/tizen/2.0/typecast'),
80594     AttributeRangeFilter;
80595
80596 AttributeRangeFilter = function (attributeName, initialValue, endValue) {
80597     var attributeRangeFilter = {};
80598
80599     t.AttributeRangeFilter(arguments, this);
80600
80601     this.__defineGetter__("attributeName", function () {
80602         return attributeRangeFilter.attributeName;
80603     });
80604     this.__defineSetter__("attributeName", function (val) {
80605         try {
80606             attributeRangeFilter.attributeName = t.DOMString(val);
80607         } catch (e) {
80608         }
80609     });
80610
80611     attributeRangeFilter.attributeName = attributeName;
80612
80613     this.initialValue = initialValue || null;
80614     this.endValue     = endValue || null;
80615 };
80616
80617 module.exports = AttributeRangeFilter;
80618
80619 });
80620 define('ripple/platform/tizen/2.0/BluetoothClass', function (require, exports, module) {
80621 /*
80622  *  Copyright 2013 Intel Corporation.
80623  *
80624  * Licensed under the Apache License, Version 2.0 (the "License");
80625  * you may not use this file except in compliance with the License.
80626  * You may obtain a copy of the License at
80627  *
80628  * http://www.apache.org/licenses/LICENSE-2.0
80629  *
80630  * Unless required by applicable law or agreed to in writing, software
80631  * distributed under the License is distributed on an "AS IS" BASIS,
80632  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80633  * See the License for the specific language governing permissions and
80634  * limitations under the License.
80635  */
80636
80637 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
80638     t = require('ripple/platform/tizen/2.0/typecast'),
80639     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
80640     BluetoothClass,
80641     _security;
80642
80643 BluetoothClass = function (prop, metaData) {
80644     var bluetoothClass = {};
80645
80646     _security = metaData;
80647
80648     bluetoothClass.major    = prop.major || 0;
80649     bluetoothClass.minor    = prop.minor || 0;
80650     bluetoothClass.services = prop.services || [];
80651
80652     this.__defineGetter__("major", function () {
80653         return bluetoothClass.major;
80654     });
80655
80656     this.__defineGetter__("minor", function () {
80657         return bluetoothClass.minor;
80658     });
80659
80660     this.__defineGetter__("services", function () {
80661         return bluetoothClass.services;
80662     });
80663
80664     bluetoothClass.services.forEach(function (service, i) {
80665         bluetoothClass.services.__defineGetter__(i, function () {
80666             return service;
80667         });
80668     });
80669
80670     this.hasService = function (service) {
80671         if (!_security.hasService) {
80672             throw new WebAPIException(errorcode.SECURITY_ERR);
80673         }
80674
80675         t.BluetoothClass("hasService", arguments);
80676
80677         return (bluetoothClass.services.join(",").indexOf(service) !== -1);
80678     };
80679 };
80680
80681 module.exports = BluetoothClass;
80682
80683 });
80684 define('ripple/platform/tizen/2.0/BluetoothClassDeviceMajor', function (require, exports, module) {
80685 /*
80686  *  Copyright 2013 Intel Corporation.
80687  *
80688  * Licensed under the Apache License, Version 2.0 (the "License");
80689  * you may not use this file except in compliance with the License.
80690  * You may obtain a copy of the License at
80691  *
80692  * http://www.apache.org/licenses/LICENSE-2.0
80693  *
80694  * Unless required by applicable law or agreed to in writing, software
80695  * distributed under the License is distributed on an "AS IS" BASIS,
80696  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80697  * See the License for the specific language governing permissions and
80698  * limitations under the License.
80699  */
80700
80701 var BluetoothClassDeviceMajor = function () {
80702     this.__defineGetter__("MISC", function () {
80703         return 0x00;
80704     });
80705
80706     this.__defineGetter__("COMPUTER", function () {
80707         return 0x01;
80708     });
80709
80710     this.__defineGetter__("PHONE", function () {
80711         return 0x02;
80712     });
80713
80714     this.__defineGetter__("NETWORK", function () {
80715         return 0x03;
80716     });
80717
80718     this.__defineGetter__("AUDIO_VIDEO", function () {
80719         return 0x04;
80720     });
80721
80722     this.__defineGetter__("PERIPHERAL", function () {
80723         return 0x05;
80724     });
80725
80726     this.__defineGetter__("IMAGING", function () {
80727         return 0x06;
80728     });
80729
80730     this.__defineGetter__("WEARABLE", function () {
80731         return 0x07;
80732     });
80733
80734     this.__defineGetter__("TOY", function () {
80735         return 0x08;
80736     });
80737
80738     this.__defineGetter__("HEALTH", function () {
80739         return 0x09;
80740     });
80741
80742     this.__defineGetter__("UNCATEGORIZED", function () {
80743         return 0x1F;
80744     });
80745 };
80746
80747 module.exports = BluetoothClassDeviceMajor;
80748
80749 });
80750 define('ripple/platform/tizen/2.0/BluetoothClassDeviceMinor', function (require, exports, module) {
80751 /*
80752  *  Copyright 2013 Intel Corporation.
80753  *
80754  * Licensed under the Apache License, Version 2.0 (the "License");
80755  * you may not use this file except in compliance with the License.
80756  * You may obtain a copy of the License at
80757  *
80758  * http://www.apache.org/licenses/LICENSE-2.0
80759  *
80760  * Unless required by applicable law or agreed to in writing, software
80761  * distributed under the License is distributed on an "AS IS" BASIS,
80762  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80763  * See the License for the specific language governing permissions and
80764  * limitations under the License.
80765  */
80766
80767 var BluetoothClassDeviceMinor = function () {
80768     // COMPUTER
80769     this.__defineGetter__("COMPUTER_UNCATEGORIZED", function () {
80770         return 0x00;
80771     });
80772
80773     this.__defineGetter__("COMPUTER_DESKTOP", function () {
80774         return 0x01;
80775     });
80776
80777     this.__defineGetter__("COMPUTER_SERVER", function () {
80778         return 0x02;
80779     });
80780
80781     this.__defineGetter__("COMPUTER_LAPTOP", function () {
80782         return 0x03;
80783     });
80784
80785     this.__defineGetter__("COMPUTER_HANDHELD_PC_OR_PDA", function () {
80786         return 0x04;
80787     });
80788
80789     this.__defineGetter__("COMPUTER_PALM_PC_OR_PDA", function () {
80790         return 0x05;
80791     });
80792
80793     this.__defineGetter__("COMPUTER_WEARABLE", function () {
80794         return 0x06;
80795     });
80796
80797     // PHONE
80798     this.__defineGetter__("PHONE_UNCATEGORIZED", function () {
80799         return 0x00;
80800     });
80801
80802     this.__defineGetter__("PHONE_CELLULAR", function () {
80803         return 0x01;
80804     });
80805
80806     this.__defineGetter__("PHONE_CORDLESS", function () {
80807         return 0x02;
80808     });
80809
80810     this.__defineGetter__("PHONE_SMARTPHONE", function () {
80811         return 0x03;
80812     });
80813
80814     this.__defineGetter__("PHONE_MODEM_OR_GATEWAY", function () {
80815         return 0x04;
80816     });
80817
80818     this.__defineGetter__("PHONE_ISDN", function () {
80819         return 0x05;
80820     });
80821
80822     // AUDIO_VIDEO
80823     this.__defineGetter__("AV_UNRECOGNIZED", function () {
80824         return 0x00;
80825     });
80826
80827     this.__defineGetter__("AV_WEARABLE_HEADSET", function () {
80828         return 0x01;
80829     });
80830
80831     this.__defineGetter__("AV_HANDSFREE", function () {
80832         return 0x02;
80833     });
80834
80835     this.__defineGetter__("AV_MICROPHONE", function () {
80836         return 0x04;
80837     });
80838
80839     this.__defineGetter__("AV_LOUDSPEAKER", function () {
80840         return 0x05;
80841     });
80842
80843     this.__defineGetter__("AV_HEADPHONES", function () {
80844         return 0x06;
80845     });
80846
80847     this.__defineGetter__("AV_PORTABLE_AUDIO", function () {
80848         return 0x07;
80849     });
80850
80851     this.__defineGetter__("AV_CAR_AUDIO", function () {
80852         return 0x08;
80853     });
80854
80855     this.__defineGetter__("AV_SETTOP_BOX", function () {
80856         return 0x09;
80857     });
80858
80859     this.__defineGetter__("AV_HIFI", function () {
80860         return 0x0a;
80861     });
80862
80863     this.__defineGetter__("AV_VCR", function () {
80864         return 0x0b;
80865     });
80866
80867     this.__defineGetter__("AV_VIDEO_CAMERA", function () {
80868         return 0x0c;
80869     });
80870
80871     this.__defineGetter__("AV_CAMCORDER", function () {
80872         return 0x0d;
80873     });
80874
80875     this.__defineGetter__("AV_MONITOR", function () {
80876         return 0x0e;
80877     });
80878
80879     this.__defineGetter__("AV_DISPLAY_AND_LOUDSPEAKER", function () {
80880         return 0x0f;
80881     });
80882
80883     this.__defineGetter__("AV_VIDEO_CONFERENCING", function () {
80884         return 0x10;
80885     });
80886
80887     this.__defineGetter__("AV_GAMING_TOY", function () {
80888         return 0x12;
80889     });
80890
80891     // PERIPHERAL
80892     this.__defineGetter__("PERIPHERAL_UNCATEGORIZED", function () {
80893         return 0;
80894     });
80895
80896     this.__defineGetter__("PERIPHERAL_KEYBOARD", function () {
80897         return 0x10;
80898     });
80899
80900     this.__defineGetter__("PERIPHERAL_POINTING_DEVICE", function () {
80901         return 0x20;
80902     });
80903
80904     this.__defineGetter__("PERIPHERAL_KEYBOARD_AND_POINTING_DEVICE", function () {
80905         return 0x30;
80906     });
80907
80908     this.__defineGetter__("PERIPHERAL_JOYSTICK", function () {
80909         return 0x01;
80910     });
80911
80912     this.__defineGetter__("PERIPHERAL_GAMEPAD", function () {
80913         return 0x02;
80914     });
80915
80916     this.__defineGetter__("PERIPHERAL_REMOTE_CONTROL", function () {
80917         return 0x03;
80918     });
80919
80920     this.__defineGetter__("PERIPHERAL_SENSING_DEVICE", function () {
80921         return 0x04;
80922     });
80923
80924     this.__defineGetter__("PERIPHERAL_DEGITIZER_TABLET", function () {
80925         return 0x05;
80926     });
80927
80928     this.__defineGetter__("PERIPHERAL_CARD_READER", function () {
80929         return 0x06;
80930     });
80931
80932     this.__defineGetter__("PERIPHERAL_DIGITAL_PEN", function () {
80933         return 0x07;
80934     });
80935
80936     this.__defineGetter__("PERIPHERAL_HANDHELD_SCANNER", function () {
80937         return 0x08;
80938     });
80939
80940     this.__defineGetter__("PERIPHERAL_HANDHELD_INPUT_DEVICE", function () {
80941         return 0x09;
80942     });
80943
80944     // IMAGING
80945     this.__defineGetter__("IMAGING_UNCATEGORIZED", function () {
80946         return 0x00;
80947     });
80948
80949     this.__defineGetter__("IMAGING_DISPLAY", function () {
80950         return 0x04;
80951     });
80952
80953     this.__defineGetter__("IMAGING_CAMERA", function () {
80954         return 0x08;
80955     });
80956
80957     this.__defineGetter__("IMAGING_SCANNER", function () {
80958         return 0x10;
80959     });
80960
80961     this.__defineGetter__("IMAGING_PRINTER", function () {
80962         return 0x20;
80963     });
80964
80965     // WEARABLE
80966     this.__defineGetter__("WEARABLE_WRITST_WATCH", function () {
80967         return 0x01;
80968     });
80969
80970     this.__defineGetter__("WEARABLE_PAGER", function () {
80971         return 0x02;
80972     });
80973
80974     this.__defineGetter__("WEARABLE_JACKET", function () {
80975         return 0x03;
80976     });
80977
80978     this.__defineGetter__("WEARABLE_HELMET", function () {
80979         return 0x04;
80980     });
80981
80982     this.__defineGetter__("WEARABLE_GLASSES", function () {
80983         return 0x05;
80984     });
80985
80986     // TOY
80987     this.__defineGetter__("TOY_ROBOT", function () {
80988         return 0x01;
80989     });
80990
80991     this.__defineGetter__("TOY_VEHICLE", function () {
80992         return 0x02;
80993     });
80994
80995     this.__defineGetter__("TOY_DOLL", function () {
80996         return 0x03;
80997     });
80998
80999     this.__defineGetter__("TOY_CONTROLLER", function () {
81000         return 0x04;
81001     });
81002
81003     this.__defineGetter__("TOY_GAME", function () {
81004         return 0x05;
81005     });
81006
81007     // HEALTH
81008     this.__defineGetter__("HEALTH_UNDEFINED", function () {
81009         return 0x00;
81010     });
81011
81012     this.__defineGetter__("HEALTH_BLOOD_PRESSURE_MONITOR", function () {
81013         return 0x01;
81014     });
81015
81016     this.__defineGetter__("HEALTH_THERMOMETER", function () {
81017         return 0x02;
81018     });
81019
81020     this.__defineGetter__("HEALTH_WEIGHING_SCALE", function () {
81021         return 0x03;
81022     });
81023
81024     this.__defineGetter__("HEALTH_GLUCOSE_METER", function () {
81025         return 0x04;
81026     });
81027
81028     this.__defineGetter__("HEALTH_PULSE_OXIMETER", function () {
81029         return 0x05;
81030     });
81031
81032     this.__defineGetter__("HEALTH_PULSE_RATE_MONITOR", function () {
81033         return 0x06;
81034     });
81035
81036     this.__defineGetter__("HEALTH_DATA_DISPLAY", function () {
81037         return 0x07;
81038     });
81039
81040     this.__defineGetter__("HEALTH_STEP_COUNTER", function () {
81041         return 0x08;
81042     });
81043
81044     this.__defineGetter__("HEALTH_BODY_COMPOSITION_ANALYZER", function () {
81045         return 0x09;
81046     });
81047
81048     this.__defineGetter__("HEALTH_PEAK_FLOW_MONITOR", function () {
81049         return 0x0a;
81050     });
81051
81052     this.__defineGetter__("HEALTH_MEDICATION_MONITOR", function () {
81053         return 0x0b;
81054     });
81055
81056     this.__defineGetter__("HEALTH_KNEE_PROSTHESIS", function () {
81057         return 0x0c;
81058     });
81059
81060     this.__defineGetter__("HEALTH_ANKLE_PROSTHESIS", function () {
81061         return 0x0d;
81062     });
81063 };
81064
81065 module.exports = BluetoothClassDeviceMinor;
81066
81067 });
81068 define('ripple/platform/tizen/2.0/BluetoothClassDeviceService', function (require, exports, module) {
81069 /*
81070  *  Copyright 2013 Intel Corporation
81071  *
81072  * Licensed under the Apache License, Version 2.0 (the "License");
81073  * you may not use this file except in compliance with the License.
81074  * You may obtain a copy of the License at
81075  *
81076  * http://www.apache.org/licenses/LICENSE-2.0
81077  *
81078  * Unless required by applicable law or agreed to in writing, software
81079  * distributed under the License is distributed on an "AS IS" BASIS,
81080  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81081  * See the License for the specific language governing permissions and
81082  * limitations under the License.
81083  */
81084
81085 var BluetoothClassDeviceService = function () {
81086     this.__defineGetter__("LIMITED_DISCOVERABILITY", function () {
81087         return 0x0001;
81088     });
81089
81090     this.__defineGetter__("POSITIONING", function () {
81091         return 0x0008;
81092     });
81093
81094     this.__defineGetter__("NETWORKING", function () {
81095         return 0x0010;
81096     });
81097
81098     this.__defineGetter__("RENDERING", function () {
81099         return 0x0020;
81100     });
81101
81102     this.__defineGetter__("CAPTURING", function () {
81103         return 0x0040;
81104     });
81105
81106     this.__defineGetter__("OBJECT_TRANSFER", function () {
81107         return 0x0080;
81108     });
81109
81110     this.__defineGetter__("AUDIO", function () {
81111         return 0x0100;
81112     });
81113
81114     this.__defineGetter__("TELEPHONY", function () {
81115         return 0x0200;
81116     });
81117
81118     this.__defineGetter__("INFORMATION", function () {
81119         return 0x0400;
81120     });
81121 };
81122
81123 module.exports = BluetoothClassDeviceService;
81124
81125 });
81126 define('ripple/platform/tizen/2.0/BluetoothDevice', function (require, exports, module) {
81127 /*
81128  *  Copyright 2013 Intel Corporation.
81129  *
81130  * Licensed under the Apache License, Version 2.0 (the "License");
81131  * you may not use this file except in compliance with the License.
81132  * You may obtain a copy of the License at
81133  *
81134  * http://www.apache.org/licenses/LICENSE-2.0
81135  *
81136  * Unless required by applicable law or agreed to in writing, software
81137  * distributed under the License is distributed on an "AS IS" BASIS,
81138  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81139  * See the License for the specific language governing permissions and
81140  * limitations under the License.
81141  */
81142
81143 var utils = require('ripple/utils'),
81144     event = require('ripple/event'),
81145     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
81146     t = require('ripple/platform/tizen/2.0/typecast'),
81147     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
81148     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
81149     BluetoothClass = require('ripple/platform/tizen/2.0/BluetoothClass'),
81150     BluetoothSocket = require('ripple/platform/tizen/2.0/BluetoothSocket'),
81151     BluetoothDevice,
81152     _security;
81153
81154 BluetoothDevice = function (prop) {
81155     var bluetoothDevice = {}, sockets = {}, self;
81156
81157     bluetoothDevice.name        = prop.name || "";
81158     bluetoothDevice.address     = prop.address || "";
81159     bluetoothDevice.deviceClass = new BluetoothClass(prop.deviceClass,
81160             prop.metaData) || {};
81161     bluetoothDevice.isBonded    = prop.isBonded || false;
81162     bluetoothDevice.isTrusted   = prop.isTrusted || false;
81163     bluetoothDevice.isConnected = prop.isConnected || false;
81164     bluetoothDevice.services    = prop.services;
81165     bluetoothDevice.uuids       = [];
81166
81167     _security = prop.metaData;
81168     self = this;
81169
81170     event.on("bt-device-connected-update", function (addr, isConnected) {
81171         if (addr === bluetoothDevice.address) {
81172             bluetoothDevice.isConnected = isConnected;
81173             event.trigger("bt-device-connected-changed",
81174                     [bluetoothDevice.address, bluetoothDevice.isConnected]);
81175         }
81176     });
81177
81178     utils.forEach(bluetoothDevice.services, function (service) {
81179         bluetoothDevice.uuids.push(service.uuid);
81180         sockets[service.uuid] = new BluetoothSocket({
81181             uuid: service.uuid,
81182             protocol: service.protocol,
81183             state: "CLOSED",
81184             peer: self,
81185             metaData: _security
81186         });
81187     });
81188
81189     this.__defineGetter__("name", function () {
81190         return bluetoothDevice.name;
81191     });
81192
81193     this.__defineGetter__("address", function () {
81194         return bluetoothDevice.address;
81195     });
81196
81197     this.__defineGetter__("deviceClass", function () {
81198         return bluetoothDevice.deviceClass;
81199     });
81200
81201     this.__defineGetter__("isBonded", function () {
81202         return bluetoothDevice.isBonded;
81203     });
81204
81205     this.__defineGetter__("isTrusted", function () {
81206         return bluetoothDevice.isTrusted;
81207     });
81208
81209     this.__defineGetter__("isConnected", function () {
81210         return bluetoothDevice.isConnected;
81211     });
81212
81213     this.__defineGetter__("uuids", function () {
81214         return bluetoothDevice.uuids;
81215     });
81216
81217     this.connectToServiceByUUID = function (uuid, successCallback,
81218             errorCallback) {
81219         if (!_security.all && !_security.connectToServiceByUUID) {
81220             throw new WebAPIException(errorcode.SECURITY_ERR);
81221         }
81222
81223         t.BluetoothDevice("connectToServiceByUUID", arguments);
81224
81225         window.setTimeout(function () {
81226             if (bluetoothDevice.uuids.join(",").indexOf(uuid) === -1) {
81227                 if (errorCallback) {
81228                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
81229                 }
81230                 return;
81231             }
81232
81233             bluetoothDevice.isConnected = true;
81234             event.trigger("bt-device-connected-changed", [bluetoothDevice.address,
81235                     true]);
81236             sockets[uuid].__defineGetter__("state", function () {
81237                 return "OPEN";
81238             });
81239             event.trigger("bt-service-state-changed", [bluetoothDevice.address,
81240                     uuid, true]);
81241
81242             successCallback(sockets[uuid]);
81243         }, 1);
81244     };
81245 };
81246
81247 module.exports = BluetoothDevice;
81248
81249 });
81250 define('ripple/platform/tizen/2.0/BluetoothServiceHandler', function (require, exports, module) {
81251 /*
81252  *  Copyright 2013 Intel Corporation
81253  *
81254  * Licensed under the Apache License, Version 2.0 (the "License");
81255  * you may not use this file except in compliance with the License.
81256  * You may obtain a copy of the License at
81257  *
81258  * http://www.apache.org/licenses/LICENSE-2.0
81259  *
81260  * Unless required by applicable law or agreed to in writing, software
81261  * distributed under the License is distributed on an "AS IS" BASIS,
81262  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81263  * See the License for the specific language governing permissions and
81264  * limitations under the License.
81265  */
81266
81267 var event = require('ripple/event'),
81268     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
81269     t = require('ripple/platform/tizen/2.0/typecast'),
81270     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
81271     BluetoothServiceHandler,
81272     _security;
81273
81274 BluetoothServiceHandler = function (prop) {
81275     var bluetoothServiceHandler = {};
81276
81277     _security = prop.metaData;
81278
81279     bluetoothServiceHandler.uuid        = prop.uuid || "";
81280     bluetoothServiceHandler.name        = prop.name || "";
81281     bluetoothServiceHandler.isConnected = prop.isConnected || false;
81282     bluetoothServiceHandler.onconnect   = null;
81283
81284     this.__defineGetter__("uuid", function () {
81285         return bluetoothServiceHandler.uuid;
81286     });
81287
81288     this.__defineGetter__("name", function () {
81289         return bluetoothServiceHandler.name;
81290     });
81291
81292     this.__defineGetter__("isConnected", function () {
81293         return bluetoothServiceHandler.isConnected;
81294     });
81295
81296     this.__defineGetter__("onconnect", function () {
81297         return bluetoothServiceHandler.onconnect;
81298     });
81299     this.__defineSetter__("onconnect", function (val) {
81300         try {
81301             bluetoothServiceHandler.onconnect =
81302                     t.BluetoothSocketSuccessCallback(val, "?");
81303         } catch (e) {
81304         }
81305     });
81306
81307     this.unregister = function (successCallback, errorCallback) {
81308         if (!_security.unregister) {
81309             throw new WebAPIException(errorcode.SECURITY_ERR);
81310         }
81311
81312         t.BluetoothServiceHandler("unregister", arguments);
81313
81314         event.trigger("bt-unregister-service", [bluetoothServiceHandler.uuid,
81315                 successCallback, errorCallback]);
81316     };
81317 };
81318
81319 module.exports = BluetoothServiceHandler;
81320
81321 });
81322 define('ripple/platform/tizen/2.0/BluetoothSocket', function (require, exports, module) {
81323 /*
81324  *  Copyright 2013 Intel Corporation.
81325  *
81326  * Licensed under the Apache License, Version 2.0 (the "License");
81327  * you may not use this file except in compliance with the License.
81328  * You may obtain a copy of the License at
81329  *
81330  * http://www.apache.org/licenses/LICENSE-2.0
81331  *
81332  * Unless required by applicable law or agreed to in writing, software
81333  * distributed under the License is distributed on an "AS IS" BASIS,
81334  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81335  * See the License for the specific language governing permissions and
81336  * limitations under the License.
81337  */
81338
81339 var utils = require('ripple/utils'),
81340     event = require('ripple/event'),
81341     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
81342     t = require('ripple/platform/tizen/2.0/typecast'),
81343     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
81344     BluetoothSocket,
81345     _security;
81346
81347 BluetoothSocket = function (prop) {
81348     var bluetoothSocket = {}, buffer = [], that = this;
81349
81350     _security = prop.metaData;
81351
81352     bluetoothSocket.uuid      = prop.uuid;
81353     bluetoothSocket.state     = prop.state;
81354     bluetoothSocket.peer      = prop.peer;
81355     bluetoothSocket.onmessage = null;
81356     bluetoothSocket.onclose   = null;
81357
81358     this.__defineGetter__("uuid", function () {
81359         return bluetoothSocket.uuid;
81360     });
81361
81362     this.__defineGetter__("state", function () {
81363         return bluetoothSocket.state;
81364     });
81365
81366     this.__defineGetter__("peer", function () {
81367         return bluetoothSocket.peer;
81368     });
81369
81370     this.__defineGetter__("onmessage", function () {
81371         return bluetoothSocket.onmessage;
81372     });
81373     this.__defineSetter__("onmessage", function (val) {
81374         try {
81375             bluetoothSocket.onmessage = t.SuccessCallback(val, "?");
81376         } catch (e) {
81377         }
81378     });
81379
81380     this.__defineGetter__("onclose", function () {
81381         return bluetoothSocket.onclose;
81382     });
81383     this.__defineSetter__("onclose", function (val) {
81384         try {
81385             bluetoothSocket.onclose = t.SuccessCallback(val, "?");
81386         } catch (e) {
81387         }
81388     });
81389
81390     this.writeData = function (data) {
81391         if (!_security.writeData) {
81392             throw new WebAPIException(errorcode.SECURITY_ERR);
81393         }
81394
81395         t.BluetoothSocket("writeData", arguments);
81396
81397         if (this.state === "CLOSED") {
81398             return;
81399         }
81400
81401         event.trigger("bt-service-write-msg", [bluetoothSocket.peer.address,
81402                 bluetoothSocket.uuid, data]);
81403
81404         return data.length;
81405     };
81406
81407     this.readData = function () {
81408         var data;
81409
81410         if (!_security.readData) {
81411             throw new WebAPIException(errorcode.SECURITY_ERR);
81412         }
81413
81414         if (this.state === "CLOSED") {
81415             return;
81416         }
81417
81418         data = utils.copy(buffer);
81419         buffer = [];
81420
81421         return data;
81422     };
81423
81424     this.close = function () {
81425         if (!_security.close) {
81426             throw new WebAPIException(errorcode.SECURITY_ERR);
81427         }
81428
81429         this.__defineGetter__("state", function () {
81430             return "CLOSED";
81431         });
81432
81433         event.trigger("bt-service-state-changed", [bluetoothSocket.peer.address,
81434                 bluetoothSocket.uuid, false]);
81435         event.trigger("bt-device-connected-update",
81436                 [bluetoothSocket.peer.address, false]);
81437
81438         if (bluetoothSocket.onclose) {
81439             bluetoothSocket.onclose();
81440         }
81441     };
81442
81443     event.on("bt-service-state-update", function (addr, state) {
81444         var stateStr = "CLOSED";
81445
81446         if (addr !== bluetoothSocket.peer.address) {
81447             return;
81448         }
81449         if (state) {
81450             stateStr = "OPEN";
81451         }
81452
81453         that.__defineGetter__("state", function () {
81454             return stateStr;
81455         });
81456
81457         event.trigger("bt-service-state-changed",
81458                 [bluetoothSocket.peer.address, bluetoothSocket.uuid,
81459                 state]);
81460         event.trigger("bt-device-connected-update",
81461                 [bluetoothSocket.peer.address, state]);
81462     });
81463
81464     event.on("bt-service-rawdata-received", function (addr, uuid, msg) {
81465         var i;
81466
81467         if ((addr !== bluetoothSocket.peer.address) ||
81468                 (uuid !== bluetoothSocket.uuid)) {
81469             return;
81470         }
81471         buffer = [];
81472         for (i = 0; i < msg.length; i++) {
81473             buffer.push(msg.charCodeAt(i));
81474         }
81475         if (bluetoothSocket.onmessage) {
81476             bluetoothSocket.onmessage();
81477         }
81478     });
81479 };
81480
81481 module.exports = BluetoothSocket;
81482
81483 });
81484 define('ripple/platform/tizen/2.0/BookmarkFolder', function (require, exports, module) {
81485 /*
81486  *  Copyright 2013 Intel Corporation.
81487  *
81488  * Licensed under the Apache License, Version 2.0 (the "License");
81489  * you may not use this file except in compliance with the License.
81490  * You may obtain a copy of the License at
81491  *
81492  * http://www.apache.org/licenses/LICENSE-2.0
81493  *
81494  * Unless required by applicable law or agreed to in writing, software
81495  * distributed under the License is distributed on an "AS IS" BASIS,
81496  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81497  * See the License for the specific language governing permissions and
81498  * limitations under the License.
81499  */
81500
81501 var t = require('ripple/platform/tizen/2.0/typecast'),
81502     BookmarkFolder;
81503
81504 BookmarkFolder = function (title) {
81505     t.BookmarkFolder(arguments, this);
81506
81507     this.__defineGetter__("parent", function () {
81508         return undefined;
81509     });
81510
81511     this.__defineGetter__("title", function () {
81512         return title;
81513     });
81514 };
81515
81516 module.exports = BookmarkFolder;
81517
81518 });
81519 define('ripple/platform/tizen/2.0/BookmarkItem', function (require, exports, module) {
81520 /*
81521  *  Copyright 2013 Intel Corporation.
81522  *
81523  * Licensed under the Apache License, Version 2.0 (the "License");
81524  * you may not use this file except in compliance with the License.
81525  * You may obtain a copy of the License at
81526  *
81527  * http://www.apache.org/licenses/LICENSE-2.0
81528  *
81529  * Unless required by applicable law or agreed to in writing, software
81530  * distributed under the License is distributed on an "AS IS" BASIS,
81531  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81532  * See the License for the specific language governing permissions and
81533  * limitations under the License.
81534  */
81535
81536 var t = require('ripple/platform/tizen/2.0/typecast'),
81537     BookmarkItem;
81538
81539 BookmarkItem = function (title, url) {
81540     t.BookmarkItem(arguments, this);
81541
81542     this.__defineGetter__("parent", function () {
81543         return undefined;
81544     });
81545     this.__defineGetter__("title", function () {
81546         return title;
81547     });
81548     this.__defineGetter__("url", function () {
81549         return url;
81550     });
81551 };
81552
81553 module.exports = BookmarkItem;
81554
81555 });
81556 define('ripple/platform/tizen/2.0/CalendarAlarm', function (require, exports, module) {
81557 /*
81558  *  Copyright 2013 Intel Corporation.
81559  *
81560  * Licensed under the Apache License, Version 2.0 (the "License");
81561  * you may not use this file except in compliance with the License.
81562  * You may obtain a copy of the License at
81563  *
81564  * http://www.apache.org/licenses/LICENSE-2.0
81565  *
81566  * Unless required by applicable law or agreed to in writing, software
81567  * distributed under the License is distributed on an "AS IS" BASIS,
81568  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81569  * See the License for the specific language governing permissions and
81570  * limitations under the License.
81571  */
81572
81573 var t = require('ripple/platform/tizen/2.0/typecast'),
81574     CalendarAlarm;
81575
81576 CalendarAlarm = function () {
81577     var voc, calendarAlarm = {};
81578
81579     // private
81580     function construct() {
81581         this.__defineGetter__("absoluteDate", function () {
81582             return calendarAlarm.absoluteDate;
81583         });
81584         this.__defineSetter__("absoluteDate", function (val) {
81585             try {
81586                 calendarAlarm.absoluteDate = t.TZDate(val, "?");
81587             } catch (e) {
81588             }
81589         });
81590
81591         this.__defineGetter__("before", function () {
81592             return calendarAlarm.before;
81593         });
81594         this.__defineSetter__("before", function (val) {
81595             try {
81596                 calendarAlarm.before = t.TimeDuration(val, "?");
81597             } catch (e) {
81598             }
81599         });
81600
81601         this.__defineGetter__("method", function () {
81602             return calendarAlarm.method;
81603         });
81604         this.__defineSetter__("method", function (val) {
81605             try {
81606                 calendarAlarm.method = t.AlarmMethod(val);
81607             } catch (e) {
81608             }
81609         });
81610
81611         this.__defineGetter__("description", function () {
81612             return calendarAlarm.description;
81613         });
81614         this.__defineSetter__("description", function (val) {
81615             try {
81616                 calendarAlarm.description = t.DOMString(val, "?");
81617             } catch (e) {
81618             }
81619         });
81620     }
81621
81622     // Constructor
81623     function CalendarAlarm_TZDate_AlarmMethod_DOMString(absoluteDate, method,
81624             description) {
81625         construct.call(this);
81626
81627         calendarAlarm.absoluteDate = absoluteDate;
81628         calendarAlarm.before       = null;
81629         calendarAlarm.method       = method;
81630         calendarAlarm.description  = description || "";
81631     }
81632
81633     function CalendarAlarm_TimeDuration_AlarmMethod_DOMString(before, method,
81634             description) {
81635         construct.call(this);
81636
81637         calendarAlarm.absoluteDate = null;
81638         calendarAlarm.before       = before;
81639         calendarAlarm.method       = method;
81640         calendarAlarm.description  = description || "";
81641     }
81642
81643     voc = [CalendarAlarm_TZDate_AlarmMethod_DOMString,
81644            CalendarAlarm_TimeDuration_AlarmMethod_DOMString];
81645     t.CalendarAlarm(arguments, this, voc);
81646 };
81647
81648 module.exports = CalendarAlarm;
81649
81650 });
81651 define('ripple/platform/tizen/2.0/CalendarAttendee', function (require, exports, module) {
81652 /*
81653  *  Copyright 2013 Intel Corporation.
81654  *
81655  * Licensed under the Apache License, Version 2.0 (the "License");
81656  * you may not use this file except in compliance with the License.
81657  * You may obtain a copy of the License at
81658  *
81659  * http://www.apache.org/licenses/LICENSE-2.0
81660  *
81661  * Unless required by applicable law or agreed to in writing, software
81662  * distributed under the License is distributed on an "AS IS" BASIS,
81663  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81664  * See the License for the specific language governing permissions and
81665  * limitations under the License.
81666  */
81667
81668 var t = require('ripple/platform/tizen/2.0/typecast'),
81669     CalendarAttendee;
81670
81671 CalendarAttendee = function (uri, attendeeInitDict) {
81672     var calendarAttendee = {}, attr;
81673
81674     t.CalendarAttendee(arguments, this);
81675
81676     calendarAttendee.uri          = uri;
81677     calendarAttendee.name         = undefined;
81678     calendarAttendee.role         = "REQ_PARTICIPANT";
81679     calendarAttendee.status       = "PENDING";
81680     calendarAttendee.RSVP         = false;
81681     calendarAttendee.type         = "INDIVIDUAL";
81682     calendarAttendee.group        = undefined;
81683     calendarAttendee.delegatorURI = undefined;
81684     calendarAttendee.delegateURI  = undefined;
81685     calendarAttendee.contactRef   = null;
81686
81687     if (attendeeInitDict) {
81688         for (attr in attendeeInitDict) {
81689             calendarAttendee[attr] = attendeeInitDict[attr];
81690         }
81691     }
81692
81693     this.__defineGetter__("uri", function () {
81694         return calendarAttendee.uri;
81695     });
81696     this.__defineSetter__("uri", function (val) {
81697         try {
81698             calendarAttendee.uri = t.DOMString(val);
81699         } catch (e) {
81700         }
81701     });
81702
81703     this.__defineGetter__("name", function () {
81704         return calendarAttendee.name;
81705     });
81706     this.__defineSetter__("name", function (val) {
81707         try {
81708             calendarAttendee.name = t.DOMString(val, "?");
81709         } catch (e) {
81710         }
81711     });
81712
81713     this.__defineGetter__("role", function () {
81714         return calendarAttendee.role;
81715     });
81716     this.__defineSetter__("role", function (val) {
81717         try {
81718             calendarAttendee.role = t.AttendeeRole(val);
81719         } catch (e) {
81720         }
81721     });
81722
81723     this.__defineGetter__("status", function () {
81724         return calendarAttendee.status;
81725     });
81726     this.__defineSetter__("status", function (val) {
81727         try {
81728             calendarAttendee.status = t.AttendeeStatus(val);
81729         } catch (e) {
81730         }
81731     });
81732
81733     this.__defineGetter__("RSVP", function () {
81734         return calendarAttendee.RSVP;
81735     });
81736     this.__defineSetter__("RSVP", function (val) {
81737         try {
81738             calendarAttendee.RSVP = t.boolean(val);
81739         } catch (e) {
81740         }
81741     });
81742
81743     this.__defineGetter__("type", function () {
81744         return calendarAttendee.type;
81745     });
81746     this.__defineSetter__("type", function (val) {
81747         try {
81748             calendarAttendee.type = t.AttendeeType(val);
81749         } catch (e) {
81750         }
81751     });
81752
81753     this.__defineGetter__("group", function () {
81754         return calendarAttendee.group;
81755     });
81756     this.__defineSetter__("group", function (val) {
81757         try {
81758             calendarAttendee.group = t.DOMString(val, "?");
81759         } catch (e) {
81760         }
81761     });
81762
81763     this.__defineGetter__("delegatorURI", function () {
81764         return calendarAttendee.delegatorURI;
81765     });
81766     this.__defineSetter__("delegatorURI", function (val) {
81767         try {
81768             calendarAttendee.delegatorURI = t.DOMString(val, "?");
81769         } catch (e) {
81770         }
81771     });
81772
81773     this.__defineGetter__("delegateURI", function () {
81774         return calendarAttendee.delegateURI;
81775     });
81776     this.__defineSetter__("delegateURI", function (val) {
81777         try {
81778             calendarAttendee.delegateURI = t.DOMString(val, "?");
81779         } catch (e) {
81780         }
81781     });
81782
81783     this.__defineGetter__("contactRef", function () {
81784         return calendarAttendee.contactRef;
81785     });
81786     this.__defineSetter__("contactRef", function (val) {
81787         try {
81788             calendarAttendee.contactRef = t.ContactRef(val, "?");
81789         } catch (e) {
81790         }
81791     });
81792 };
81793
81794 module.exports = CalendarAttendee;
81795
81796 });
81797 define('ripple/platform/tizen/2.0/CalendarEvent', function (require, exports, module) {
81798 /*
81799  *  Copyright 2013 Intel Corporation.
81800  *
81801  * Licensed under the Apache License, Version 2.0 (the "License");
81802  * you may not use this file except in compliance with the License.
81803  * You may obtain a copy of the License at
81804  *
81805  * http://www.apache.org/licenses/LICENSE-2.0
81806  *
81807  * Unless required by applicable law or agreed to in writing, software
81808  * distributed under the License is distributed on an "AS IS" BASIS,
81809  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81810  * See the License for the specific language governing permissions and
81811  * limitations under the License.
81812  */
81813
81814 var t = require('ripple/platform/tizen/2.0/typecast'),
81815     typedef = require('ripple/platform/tizen/2.0/typedef'),
81816     CalendarItem = require('ripple/platform/tizen/2.0/CalendarItem'),
81817     CalendarEvent;
81818
81819 CalendarEvent = function () {
81820     var voc, calendarEvent = {};
81821
81822     // private
81823     function construct(eventInitDict) {
81824         CalendarItem.call(this, eventInitDict);
81825
81826         this.status = "CONFIRMED";
81827
81828         calendarEvent.convertToString  = this.convertToString;
81829         calendarEvent.isDetached       = false;
81830         calendarEvent.endDate          = null;
81831         calendarEvent.availability     = "BUSY";
81832         calendarEvent.recurrenceRule   = null;
81833
81834         this.__defineGetter__("isDetached", function () {
81835             return calendarEvent.isDetached;
81836         });
81837
81838         this.__defineGetter__("endDate", function () {
81839             return calendarEvent.endDate;
81840         });
81841         this.__defineSetter__("endDate", function (val) {
81842             try {
81843                 calendarEvent.endDate = t.TZDate(val, "?");
81844             } catch (e) {
81845             }
81846         });
81847
81848         this.__defineGetter__("availability", function () {
81849             return calendarEvent.availability;
81850         });
81851         this.__defineSetter__("availability", function (val) {
81852             try {
81853                 calendarEvent.availability = t.EventAvailability(val);
81854             } catch (e) {
81855             }
81856         });
81857
81858         this.__defineGetter__("recurrenceRule", function () {
81859             return calendarEvent.recurrenceRule;
81860         });
81861         this.__defineSetter__("recurrenceRule", function (val) {
81862             try {
81863                 calendarEvent.recurrenceRule = t.CalendarRecurrenceRule(val,
81864                         "?");
81865             } catch (e) {
81866             }
81867         });
81868
81869         this.convertToString  = convertToString;
81870         this.clone            = clone(this);
81871         this.expandRecurrence = expandRecurrence;
81872     }
81873
81874     function clone(self) {
81875         return function () {
81876             return new CalendarEvent(self);
81877         };
81878     }
81879
81880     // public
81881     function convertToString(format) {
81882         var str;
81883
81884         str = calendarEvent.convertToString.call(this, format);
81885         str = str.replace(/#TYPE#/g, "VEVENT");
81886
81887         // TODO: endDate is not supported
81888         // TODO: recurrenceRule is not supported
81889         str = str.replace(/#AVAILABILITY#/g, "FREEBUSY;FBTYPE=" +
81890                 calendarEvent.availability);
81891
81892         str = str.replace(/#[^#]*#/g, "");
81893
81894         return str;
81895     }
81896
81897     function expandRecurrence(startDate, endDate, successCallback,
81898             errorCallback) {
81899     }
81900
81901     // Constructor
81902     function CalendarEvent_CalendarEventInit(eventInitDict) {
81903         var attr;
81904
81905         construct.call(this, eventInitDict);
81906
81907         if (eventInitDict) {
81908             for (attr in eventInitDict) {
81909                 if (attr in typedef.CalendarEventInit) {
81910                     calendarEvent[attr] = eventInitDict[attr];
81911                 }
81912             }
81913         }
81914     }
81915
81916     function CalendarEvent_DOMString_CalendarTextFormat(stringRepresentation,
81917             format) {
81918     }
81919
81920     voc = [CalendarEvent_CalendarEventInit,
81921            CalendarEvent_DOMString_CalendarTextFormat];
81922     t.CalendarEvent(arguments, this, voc);
81923 };
81924
81925 module.exports = CalendarEvent;
81926
81927 });
81928 define('ripple/platform/tizen/2.0/CalendarEventId', function (require, exports, module) {
81929 /*
81930  *  Copyright 2013 Intel Corporation.
81931  *
81932  * Licensed under the Apache License, Version 2.0 (the "License");
81933  * you may not use this file except in compliance with the License.
81934  * You may obtain a copy of the License at
81935  *
81936  * http://www.apache.org/licenses/LICENSE-2.0
81937  *
81938  * Unless required by applicable law or agreed to in writing, software
81939  * distributed under the License is distributed on an "AS IS" BASIS,
81940  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81941  * See the License for the specific language governing permissions and
81942  * limitations under the License.
81943  */
81944
81945 var t = require('ripple/platform/tizen/2.0/typecast'),
81946     CalendarEventId;
81947
81948 CalendarEventId = function (uid, rid) {
81949     var calendarEventId = {};
81950
81951     t.CalendarEventId(arguments, this);
81952
81953     calendarEventId.uid = uid;
81954     calendarEventId.rid = rid || null;
81955
81956     this.__defineGetter__("uid", function () {
81957         return calendarEventId.uid;
81958     });
81959     this.__defineSetter__("uid", function (val) {
81960         try {
81961             calendarEventId.uid = t.DOMString(val);
81962         } catch (e) {
81963         }
81964     });
81965
81966     this.__defineGetter__("rid", function () {
81967         return calendarEventId.rid;
81968     });
81969     this.__defineSetter__("rid", function (val) {
81970         try {
81971             calendarEventId.rid = t.DOMString(val, "?");
81972         } catch (e) {
81973         }
81974     });
81975 };
81976
81977 module.exports = CalendarEventId;
81978
81979 });
81980 define('ripple/platform/tizen/2.0/CalendarItem', function (require, exports, module) {
81981 /*
81982  *  Copyright 2013 Intel Corporation.
81983  *
81984  * Licensed under the Apache License, Version 2.0 (the "License");
81985  * you may not use this file except in compliance with the License.
81986  * You may obtain a copy of the License at
81987  *
81988  * http://www.apache.org/licenses/LICENSE-2.0
81989  *
81990  * Unless required by applicable law or agreed to in writing, software
81991  * distributed under the License is distributed on an "AS IS" BASIS,
81992  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81993  * See the License for the specific language governing permissions and
81994  * limitations under the License.
81995  */
81996
81997 var t = require('ripple/platform/tizen/2.0/typecast'),
81998     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
81999     typedef = require('ripple/platform/tizen/2.0/typedef'),
82000     CalendarItem;
82001
82002 CalendarItem = function (itemInitDict) {
82003     var calendarItem = {}, attr;
82004
82005     // private
82006     function toDigit(number) {
82007         return ((number >= 10) ? "" : "0") + number;
82008     }
82009
82010     // public
82011     function convertToString(format) {
82012         var header = "BEGIN:VCALENDAR\r\nPRODID:-//Tizen.org//Tizen Calendar//EN\r\nVERSION:2.0\r\n",
82013             end = "END:VCALENDAR\r\n", str = "", pri, i, date, before, y, m, d,
82014             hh, mm, ss, dateStart = "", dateEnd = "";
82015
82016         t.CalendarItem("convertToString", arguments);
82017
82018         //TODO: vcalendar 1.0 doesn't support yet
82019         if (format === "VCALENDAR_10") {
82020             return;
82021         }
82022
82023         str = header + "BEGIN:#TYPE#\r\n";
82024
82025         if (this.isAllDay) {
82026             if (this.startDate) {
82027                 date = this.startDate;
82028                 y = date.getFullYear();
82029                 m = toDigit(date.getMonth() + 1);
82030                 d = toDigit(date.getDate());
82031                 str += "DTSTART;VALUE=DATE:" + y + m + d + "\r\n";
82032                 dateStart = "" + y + m + d + "T000000Z";
82033                 if (this.duration) {
82034                     date = date.addDuration(this.duration);
82035                     y = date.getFullYear();
82036                     m = toDigit(date.getMonth() + 1);
82037                     d = toDigit(date.getDate());
82038                     str += "DTEND;VALUE=DATE:" + y + m + d + "\r\n";
82039                     dateEnd = "" + y + m + d + "T000000Z";
82040                 }
82041             }
82042         } else {
82043             if (this.startDate) {
82044                 date = this.startDate;
82045                 y = date.getFullYear();
82046                 m = toDigit(date.getMonth() + 1);
82047                 d = toDigit(date.getDate());
82048                 hh = toDigit(date.getHours());
82049                 mm = toDigit(date.getMinutes());
82050                 ss = toDigit(date.getSeconds());
82051                 str += "DTSTART:" + y + m + d + "T" + hh + mm + ss + "Z" + "\r\n";
82052                 dateStart = "" + y + m + d + "T" + hh + mm + ss + "Z";
82053                 if (this.duration && this.duration.length && this.duration.unit) {
82054                     date = date.addDuration(this.duration);
82055                     y = date.getFullYear();
82056                     m = toDigit(date.getMonth() + 1);
82057                     d = toDigit(date.getDate());
82058                     hh = toDigit(date.getHours());
82059                     mm = toDigit(date.getMinutes());
82060                     ss = toDigit(date.getSeconds());
82061                     str += "DTEND:" + y + m + d + "T" + hh + mm + ss + "Z" + "\r\n";
82062                     dateEnd = "" + y + m + d + "T" + hh + mm + ss + "Z";
82063                 }
82064             }
82065         }
82066
82067         if (this.description) {
82068             str += "DESCRIPTION:" + this.description + "\r\n";
82069         }
82070         if (this.summary) {
82071             str += "SUMMARY:" + this.summary + "\r\n";
82072         }
82073         if (this.location) {
82074             str += "LOCATION:" + this.location + "\r\n";
82075         }
82076         if (this.geolocation) {
82077             // Don't need to check latitude and longitude due to they are mandatory attributes
82078             str += "GEO:" + this.geolocation.latitude + "," + this.geolocation.longitude + "\r\n";
82079         }
82080         if (this.organizer) {
82081             str += "ORGANIZER:" + this.organizer + "\r\n";
82082         }
82083         if (this.visibility) {
82084             str += "CLASS:" + this.visibility + "\r\n";
82085         }
82086         if (this.status) {
82087             str += "STATUS:" + this.status + "\r\n";
82088         }
82089         if (this.priority) {
82090             switch (this.priority) {
82091             case "HIGH":
82092                 pri = 2;
82093                 break;
82094             case "MEDIUM":
82095                 pri = 5;
82096                 break;
82097             case "LOW":
82098                 pri = 7;
82099                 break;
82100             }
82101             str += "PRIORITY:" + pri + "\r\n";
82102         }
82103         if (tizen1_utils.isValidArray(this.alarms)) {
82104             for (i = 0; i < this.alarms.length; i++) {
82105                 str += "BEGIN:VALARM\r\n";
82106                 // Don't need to check this.alarms[i].method due to it is a mandatory attribute
82107                 str += "ACTION:" + this.alarms[i].method + "\r\n";
82108                 if (this.alarms[i].description) {
82109                     str += "DESCRIPTION:" + this.alarms[i].description + "\r\n";
82110                 } else {
82111                     // description property MUST included if action is DISPLAY (RFC5545 3.6.6)
82112                     str += "DESCRIPTION:This is a reminder\r\n";
82113                 }
82114                 if (this.alarms[i].absoluteDate) {
82115                     date = this.alarms[i].absoluteDate;
82116                     y = date.getFullYear();
82117                     m = toDigit(date.getMonth() + 1);
82118                     d = toDigit(date.getDate());
82119                     hh = toDigit(date.getHours());
82120                     mm = toDigit(date.getMinutes());
82121                     ss = toDigit(date.getSeconds());
82122                     str += "TRIGGER;VALUE=DATE-TIME:" + y + m + d + "T" + hh + mm + ss + "Z" + "\r\n";
82123                 } else {
82124                     //it must be included before attribute
82125                     before = this.alarms[i].before;
82126                     switch (before.unit) {
82127                     case "DAYS":
82128                         str += "TRIGGER:-P" + before.length + "D" + "\r\n";
82129                         break;
82130                     case "HOURS":
82131                         str += "TRIGGER:-P0DT" + before.length + "H0M0S" + "\r\n";
82132                         break;
82133                     case "MINS":
82134                         str += "TRIGGER:-P0DT0H" + before.length + "M0S" + "\r\n";
82135                         break;
82136                     case "SECS":
82137                         str += "TRIGGER:-P0DT0H0M" + before.length + "S" + "\r\n";
82138                         break;
82139                     }
82140                 }
82141                 str += "END:VALARM\r\n";
82142             }
82143         }
82144         if (tizen1_utils.isValidArray(this.categories)) {
82145             str += "CATEGORIES:";
82146             for (i = 0; i < this.categories.length; i++) {
82147                 str += this.categories[i] + ",";
82148             }
82149             str = str.slice(0, -1);
82150             str += "\r\n";
82151         }
82152         if (tizen1_utils.isValidArray(this.attendees)) {
82153             for (i = 0; i < this.attendees.length; i++) {
82154                 //TODO: basic implementation
82155                 str += "ATTENDEE:mailto:" + this.attendees[i].uri + "\r\n";
82156             }
82157         }
82158
82159         if ((dateStart !== "") && (dateEnd !== "")) {
82160             str += "#AVAILABILITY#:" + dateStart + "/" + dateEnd + "\r\n";
82161         }
82162
82163         str += "#ENDDATE##RECURRENCERULE#";
82164         str += "#DUEDATE##COMPLETEDDATE##PROGRESS#";
82165         str += "END:#TYPE#\r\n" + end;
82166
82167         return str;
82168     }
82169
82170     calendarItem.description = "";
82171     calendarItem.summary     = "";
82172     calendarItem.isAllDay    = false;
82173     calendarItem.startDate   = null;
82174     calendarItem.duration    = null;
82175     calendarItem.location    = "";
82176     calendarItem.geolocation = null;
82177     calendarItem.organizer   = "";
82178     calendarItem.visibility  = "PUBLIC";
82179     calendarItem.status      = "TENTATIVE";
82180     calendarItem.priority    = "LOW";
82181     calendarItem.alarms      = [];
82182     calendarItem.categories  = [];
82183     calendarItem.attendees   = [];
82184
82185     if (itemInitDict) {
82186         for (attr in itemInitDict) {
82187             if (!(attr in typedef.CalendarItemInit))
82188                 continue;
82189
82190             switch (attr) {
82191             case "alarms":
82192                 calendarItem.alarms = t.CalendarAlarm(itemInitDict.alarms,
82193                         "[]+");
82194                 break;
82195
82196             case "categories":
82197                 calendarItem.categories = t.DOMString(itemInitDict.categories,
82198                         "[]+");
82199                 break;
82200
82201             case "attendees":
82202                 calendarItem.attendees = t.CalendarAttendee(
82203                         itemInitDict.attendees, "[]+");
82204                 break;
82205
82206             default:
82207                 calendarItem[attr] = itemInitDict[attr];
82208                 break;
82209             }
82210         }
82211     }
82212
82213     this.__defineGetter__("id", function () {
82214         return null;
82215     });
82216
82217     this.__defineGetter__("calendarId", function () {
82218         return null;
82219     });
82220
82221     this.__defineGetter__("lastModificationDate", function () {
82222         return null;
82223     });
82224
82225     this.__defineGetter__("description", function () {
82226         return calendarItem.description;
82227     });
82228     this.__defineSetter__("description", function (val) {
82229         try {
82230             calendarItem.description = t.DOMString(val, "?");
82231         } catch (e) {
82232         }
82233     });
82234
82235     this.__defineGetter__("summary", function () {
82236         return calendarItem.summary;
82237     });
82238     this.__defineSetter__("summary", function (val) {
82239         try {
82240             calendarItem.summary = t.DOMString(val, "?");
82241         } catch (e) {
82242         }
82243     });
82244
82245     this.__defineGetter__("isAllDay", function () {
82246         return calendarItem.isAllDay;
82247     });
82248     this.__defineSetter__("isAllDay", function (val) {
82249         try {
82250             calendarItem.isAllDay = t.boolean(val);
82251         } catch (e) {
82252         }
82253     });
82254
82255     this.__defineGetter__("startDate", function () {
82256         return calendarItem.startDate;
82257     });
82258     this.__defineSetter__("startDate", function (val) {
82259         try {
82260             calendarItem.startDate = t.TZDate(val, "?");
82261         } catch (e) {
82262         }
82263     });
82264
82265     this.__defineGetter__("duration", function () {
82266         return calendarItem.duration;
82267     });
82268     this.__defineSetter__("duration", function (val) {
82269         try {
82270             calendarItem.duration = t.TimeDuration(val, "?");
82271         } catch (e) {
82272         }
82273     });
82274
82275     this.__defineGetter__("location", function () {
82276         return calendarItem.location;
82277     });
82278     this.__defineSetter__("location", function (val) {
82279         try {
82280             calendarItem.location = t.DOMString(val, "?");
82281         } catch (e) {
82282         }
82283     });
82284
82285     this.__defineGetter__("geolocation", function () {
82286         return calendarItem.geolocation;
82287     });
82288     this.__defineSetter__("geolocation", function (val) {
82289         try {
82290             calendarItem.geolocation = t.SimpleCoordinates(val, "?");
82291         } catch (e) {
82292         }
82293     });
82294
82295     this.__defineGetter__("organizer", function () {
82296         return calendarItem.organizer;
82297     });
82298     this.__defineSetter__("organizer", function (val) {
82299         try {
82300             calendarItem.organizer = t.DOMString(val, "?");
82301         } catch (e) {
82302         }
82303     });
82304
82305     this.__defineGetter__("visibility", function () {
82306         return calendarItem.visibility;
82307     });
82308     this.__defineSetter__("visibility", function (val) {
82309         try {
82310             calendarItem.visibility = t.CalendarItemVisibility(val);
82311         } catch (e) {
82312         }
82313     });
82314
82315     this.__defineGetter__("status", function () {
82316         return calendarItem.status;
82317     });
82318     this.__defineSetter__("status", function (val) {
82319         try {
82320             calendarItem.status = t.CalendarItemStatus(val);
82321         } catch (e) {
82322         }
82323     });
82324
82325     this.__defineGetter__("priority", function () {
82326         return calendarItem.priority;
82327     });
82328     this.__defineSetter__("priority", function (val) {
82329         try {
82330             calendarItem.priority = t.CalendarItemPriority(val);
82331         } catch (e) {
82332         }
82333     });
82334
82335     this.__defineGetter__("alarms", function () {
82336         return calendarItem.alarms;
82337     });
82338     this.__defineSetter__("alarms", function (val) {
82339         try {
82340             calendarItem.alarms = t.CalendarAlarm(val, "[]");
82341         } catch (e) {
82342         }
82343     });
82344
82345     this.__defineGetter__("categories", function () {
82346         return calendarItem.categories;
82347     });
82348     this.__defineSetter__("categories", function (val) {
82349         try {
82350             calendarItem.categories = t.DOMString(val, "[]");
82351         } catch (e) {
82352         }
82353     });
82354
82355     this.__defineGetter__("attendees", function () {
82356         return calendarItem.attendees;
82357     });
82358     this.__defineSetter__("attendees", function (val) {
82359         try {
82360             calendarItem.attendees = t.CalendarAttendee(val, "[]");
82361         } catch (e) {
82362         }
82363     });
82364
82365     this.convertToString = convertToString;
82366 };
82367
82368 module.exports = CalendarItem;
82369
82370 });
82371 define('ripple/platform/tizen/2.0/CalendarRecurrenceRule', function (require, exports, module) {
82372 /*
82373  *  Copyright 2013 Intel Corporation.
82374  *
82375  * Licensed under the Apache License, Version 2.0 (the "License");
82376  * you may not use this file except in compliance with the License.
82377  * You may obtain a copy of the License at
82378  *
82379  * http://www.apache.org/licenses/LICENSE-2.0
82380  *
82381  * Unless required by applicable law or agreed to in writing, software
82382  * distributed under the License is distributed on an "AS IS" BASIS,
82383  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82384  * See the License for the specific language governing permissions and
82385  * limitations under the License.
82386  */
82387
82388 var t = require('ripple/platform/tizen/2.0/typecast'),
82389     CalendarRecurrenceRule;
82390
82391 CalendarRecurrenceRule = function (frequency, ruleInitDict) {
82392     var calendarRecurrenceRule = {}, attr;
82393
82394     t.CalendarRecurrenceRule(arguments, this);
82395
82396     calendarRecurrenceRule.frequency       = frequency;
82397     calendarRecurrenceRule.interval        = 1;
82398     calendarRecurrenceRule.untilDate       = null;
82399     calendarRecurrenceRule.occurrenceCount = -1;
82400     calendarRecurrenceRule.daysOfTheWeek   = [];
82401     calendarRecurrenceRule.setPositions    = [];
82402     calendarRecurrenceRule.exceptions      = [];
82403
82404     if (ruleInitDict) {
82405         for (attr in ruleInitDict) {
82406             switch (attr) {
82407             case "daysOfTheWeek":
82408                 calendarRecurrenceRule.daysOfTheWeek = t.ByDayValue(
82409                         ruleInitDict.daysOfTheWeek, "[]+");
82410                 break;
82411
82412             case "setPositions":
82413                 calendarRecurrenceRule.setPositions = t.short(
82414                         ruleInitDict.setPositions, "[]+");
82415                 break;
82416
82417             case "exceptions":
82418                 calendarRecurrenceRule.exceptions = t.TZDate(
82419                         ruleInitDict.exceptions, "[]+");
82420                 break;
82421
82422             default:
82423                 calendarRecurrenceRule[attr] = ruleInitDict[attr];
82424                 break;
82425             }
82426         }
82427     }
82428
82429     this.__defineGetter__("frequency", function () {
82430         return calendarRecurrenceRule.frequency;
82431     });
82432     this.__defineSetter__("frequency", function (val) {
82433         try {
82434             calendarRecurrenceRule.frequency = t.RecurrenceRuleFrequency(val);
82435         } catch (e) {
82436         }
82437     });
82438
82439     this.__defineGetter__("interval", function () {
82440         return calendarRecurrenceRule.interval;
82441     });
82442     this.__defineSetter__("interval", function (val) {
82443         try {
82444             calendarRecurrenceRule.interval = t.unsigned_short(val);
82445         } catch (e) {
82446         }
82447     });
82448
82449     this.__defineGetter__("untilDate", function () {
82450         return calendarRecurrenceRule.untilDate;
82451     });
82452     this.__defineSetter__("untilDate", function (val) {
82453         try {
82454             calendarRecurrenceRule.untilDate = t.TZDate(val, "?");
82455         } catch (e) {
82456         }
82457     });
82458
82459     this.__defineGetter__("occurrenceCount", function () {
82460         return calendarRecurrenceRule.occurrenceCount;
82461     });
82462     this.__defineSetter__("occurrenceCount", function (val) {
82463         try {
82464             calendarRecurrenceRule.occurrenceCount = t.long(val);
82465         } catch (e) {
82466         }
82467     });
82468
82469     this.__defineGetter__("daysOfTheWeek", function () {
82470         return calendarRecurrenceRule.daysOfTheWeek;
82471     });
82472     this.__defineSetter__("daysOfTheWeek", function (val) {
82473         try {
82474             calendarRecurrenceRule.daysOfTheWeek = t.ByDayValue(val, "[]");
82475         } catch (e) {
82476         }
82477     });
82478
82479     this.__defineGetter__("setPositions", function () {
82480         return calendarRecurrenceRule.setPositions;
82481     });
82482     this.__defineSetter__("setPositions", function (val) {
82483         try {
82484             calendarRecurrenceRule.setPositions = t.short(val, "[]");
82485         } catch (e) {
82486         }
82487     });
82488
82489     this.__defineGetter__("exceptions", function () {
82490         return calendarRecurrenceRule.exceptions;
82491     });
82492     this.__defineSetter__("exceptions", function (val) {
82493         try {
82494             calendarRecurrenceRule.exceptions = t.TZDate(val, "[]");
82495         } catch (e) {
82496         }
82497     });
82498 };
82499
82500 module.exports = CalendarRecurrenceRule;
82501
82502 });
82503 define('ripple/platform/tizen/2.0/CalendarTask', function (require, exports, module) {
82504 /*
82505  *  Copyright 2013 Intel Corporation.
82506  *
82507  * Licensed under the Apache License, Version 2.0 (the "License");
82508  * you may not use this file except in compliance with the License.
82509  * You may obtain a copy of the License at
82510  *
82511  * http://www.apache.org/licenses/LICENSE-2.0
82512  *
82513  * Unless required by applicable law or agreed to in writing, software
82514  * distributed under the License is distributed on an "AS IS" BASIS,
82515  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82516  * See the License for the specific language governing permissions and
82517  * limitations under the License.
82518  */
82519
82520 var t = require('ripple/platform/tizen/2.0/typecast'),
82521     typedef = require('ripple/platform/tizen/2.0/typedef'),
82522     CalendarItem = require('ripple/platform/tizen/2.0/CalendarItem'),
82523     CalendarTask;
82524
82525 CalendarTask = function () {
82526     var voc, calendarTask = {};
82527
82528     // private
82529     function construct(taskInitDict) {
82530         CalendarItem.call(this, taskInitDict);
82531
82532         this.status = "NEEDS_ACTION";
82533
82534         calendarTask.convertToString = this.convertToString;
82535         calendarTask.dueDate         = null;
82536         calendarTask.completedDate   = null;
82537         calendarTask.progress        = 0;
82538
82539         this.__defineGetter__("dueDate", function () {
82540             return calendarTask.dueDate;
82541         });
82542         this.__defineSetter__("dueDate", function (val) {
82543             try {
82544                 calendarTask.dueDate = t.TZDate(val, "?");
82545             } catch (e) {
82546             }
82547         });
82548
82549         this.__defineGetter__("completedDate", function () {
82550             return calendarTask.completedDate;
82551         });
82552         this.__defineSetter__("completedDate", function (val) {
82553             try {
82554                 calendarTask.completedDate = t.TZDate(val, "?");
82555             } catch (e) {
82556             }
82557         });
82558
82559         this.__defineGetter__("progress", function () {
82560             return calendarTask.progress;
82561         });
82562         this.__defineSetter__("progress", function (val) {
82563             try {
82564                 calendarTask.progress = t.unsigned_short(val);
82565             } catch (e) {
82566             }
82567         });
82568
82569         this.convertToString = convertToString;
82570         this.clone           = clone(this);
82571     }
82572
82573     function clone(self) {
82574         return function () {
82575             return new CalendarTask(self);
82576         };
82577     }
82578
82579     // public
82580     function convertToString(format) {
82581         var str;
82582
82583         str = calendarTask.convertToString.call(this, format);
82584         str = str.replace(/#TYPE#/g, "VTASK");
82585
82586         // TODO: dueDate is not supported
82587         // TODO: completedDate is not supported
82588         if (this.progress) {
82589             str = str.replace(/#PROGRESS#/g, "PERCENT-COMPLETE:" +
82590                     this.progress + "\r\n");
82591         }
82592
82593         str = str.replace(/#AVAILABILITY#.*\r\n/g, "");
82594         str = str.replace(/#[^#]*#/g, "");
82595
82596         return str;
82597     }
82598
82599     // Constructor
82600     function CalendarTask_CalendarTaskInit(taskInitDict) {
82601         var attr;
82602
82603         construct.call(this, taskInitDict);
82604
82605         if (taskInitDict) {
82606             for (attr in taskInitDict) {
82607                 if (attr in typedef.CalendarTaskInit) {
82608                     calendarTask[attr] = taskInitDict[attr];
82609                 }
82610             }
82611         }
82612     }
82613
82614     function CalendarTask_DOMString_CalendarTextFormat(stringRepresentation,
82615             format) {
82616     }
82617
82618     voc = [CalendarTask_CalendarTaskInit,
82619            CalendarTask_DOMString_CalendarTextFormat];
82620     t.CalendarTask(arguments, this, voc);
82621 };
82622
82623 module.exports = CalendarTask;
82624
82625 });
82626 define('ripple/platform/tizen/2.0/CompositeFilter', function (require, exports, module) {
82627 /*
82628  *  Copyright 2013 Intel Corporation.
82629  *
82630  * Licensed under the Apache License, Version 2.0 (the "License");
82631  * you may not use this file except in compliance with the License.
82632  * You may obtain a copy of the License at
82633  *
82634  * http://www.apache.org/licenses/LICENSE-2.0
82635  *
82636  * Unless required by applicable law or agreed to in writing, software
82637  * distributed under the License is distributed on an "AS IS" BASIS,
82638  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82639  * See the License for the specific language governing permissions and
82640  * limitations under the License.
82641  */
82642
82643 var t = require('ripple/platform/tizen/2.0/typecast'),
82644     CompositeFilter;
82645
82646 CompositeFilter = function (type, filters) {
82647     var compositeFilter = {};
82648
82649     t.CompositeFilter(arguments, this);
82650
82651     this.__defineGetter__("type", function () {
82652         return compositeFilter.type;
82653     });
82654     this.__defineSetter__("type", function (val) {
82655         try {
82656             compositeFilter.type = t.CompositeFilterType(val);
82657         } catch (e) {
82658         }
82659     });
82660
82661     this.__defineGetter__("filters", function () {
82662         return compositeFilter.filters;
82663     });
82664     this.__defineSetter__("filters", function (val) {
82665         try {
82666             compositeFilter.filters = t.AbstractFilter(val, "[]");
82667         } catch (e) {
82668         }
82669     });
82670
82671     compositeFilter.type    = type;
82672     compositeFilter.filters = filters || [];
82673 };
82674
82675 module.exports = CompositeFilter;
82676
82677 });
82678 define('ripple/platform/tizen/2.0/ContactAddress', function (require, exports, module) {
82679 /*
82680  *  Copyright 2013 Intel Corporation.
82681  *
82682  * Licensed under the Apache License, Version 2.0 (the "License");
82683  * you may not use this file except in compliance with the License.
82684  * You may obtain a copy of the License at
82685  *
82686  * http://www.apache.org/licenses/LICENSE-2.0
82687  *
82688  * Unless required by applicable law or agreed to in writing, software
82689  * distributed under the License is distributed on an "AS IS" BASIS,
82690  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82691  * See the License for the specific language governing permissions and
82692  * limitations under the License.
82693  */
82694
82695 var t = require('ripple/platform/tizen/2.0/typecast'),
82696     ContactAddress;
82697
82698 ContactAddress = function (addressInitDict) {
82699     var contactAddress = {}, attr, arr, i;
82700
82701     t.ContactAddress(arguments, this);
82702
82703     contactAddress.country               = null;
82704     contactAddress.region                = null;
82705     contactAddress.city                  = null;
82706     contactAddress.streetAddress         = null;
82707     contactAddress.additionalInformation = null;
82708     contactAddress.postalCode            = null;
82709     contactAddress.isDefault             = false;
82710     contactAddress.types                 = ["HOME"];
82711
82712     this.__defineGetter__("country", function () {
82713         return contactAddress.country;
82714     });
82715     this.__defineSetter__("country", function (val) {
82716         try {
82717             contactAddress.country = t.DOMString(val, "?");
82718         } catch (e) {
82719         }
82720     });
82721
82722     this.__defineGetter__("region", function () {
82723         return contactAddress.region;
82724     });
82725     this.__defineSetter__("region", function (val) {
82726         try {
82727             contactAddress.region = t.DOMString(val, "?");
82728         } catch (e) {
82729         }
82730     });
82731
82732     this.__defineGetter__("city", function () {
82733         return contactAddress.city;
82734     });
82735     this.__defineSetter__("city", function (val) {
82736         try {
82737             contactAddress.city = t.DOMString(val, "?");
82738         } catch (e) {
82739         }
82740     });
82741
82742     this.__defineGetter__("streetAddress", function () {
82743         return contactAddress.streetAddress;
82744     });
82745     this.__defineSetter__("streetAddress", function (val) {
82746         try {
82747             contactAddress.streetAddress = t.DOMString(val, "?");
82748         } catch (e) {
82749         }
82750     });
82751
82752     this.__defineGetter__("additionalInformation", function () {
82753         return contactAddress.additionalInformation;
82754     });
82755     this.__defineSetter__("additionalInformation", function (val) {
82756         try {
82757             contactAddress.additionalInformation = t.DOMString(val, "?");
82758         } catch (e) {
82759         }
82760     });
82761
82762     this.__defineGetter__("postalCode", function () {
82763         return contactAddress.postalCode;
82764     });
82765     this.__defineSetter__("postalCode", function (val) {
82766         try {
82767             contactAddress.postalCode = t.DOMString(val, "?");
82768         } catch (e) {
82769         }
82770     });
82771
82772     this.__defineGetter__("isDefault", function () {
82773         return contactAddress.isDefault;
82774     });
82775     this.__defineSetter__("isDefault", function (val) {
82776         try {
82777             contactAddress.isDefault = t.boolean(val);
82778         } catch (e) {
82779         }
82780     });
82781
82782     this.__defineGetter__("types", function () {
82783         return contactAddress.types;
82784     });
82785     this.__defineSetter__("types", function (val) {
82786         try {
82787             contactAddress.types = t.DOMString(val, "[]");
82788         } catch (e) {
82789         }
82790     });
82791
82792     if (addressInitDict) {
82793         for (attr in addressInitDict) {
82794             switch (attr) {
82795             case "types":
82796                 arr = addressInitDict[attr];
82797                 if (arr) {
82798                     for (i in arr) {
82799                         contactAddress[attr][i] = arr[i];
82800                     }
82801                 }
82802                 break;
82803
82804             default:
82805                 contactAddress[attr] = addressInitDict[attr];
82806                 break;
82807             }
82808         }
82809     }
82810 };
82811
82812 module.exports = ContactAddress;
82813
82814 });
82815 define('ripple/platform/tizen/2.0/ContactAnniversary', function (require, exports, module) {
82816 /*
82817  *  Copyright 2013 Intel Corporation.
82818  *
82819  * Licensed under the Apache License, Version 2.0 (the "License");
82820  * you may not use this file except in compliance with the License.
82821  * You may obtain a copy of the License at
82822  *
82823  * http://www.apache.org/licenses/LICENSE-2.0
82824  *
82825  * Unless required by applicable law or agreed to in writing, software
82826  * distributed under the License is distributed on an "AS IS" BASIS,
82827  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82828  * See the License for the specific language governing permissions and
82829  * limitations under the License.
82830  */
82831
82832 var t = require('ripple/platform/tizen/2.0/typecast'),
82833     ContactAnniversary;
82834
82835 ContactAnniversary = function (date, label) {
82836     var contactAnniversary = {};
82837
82838     t.ContactAnniversary(arguments, this);
82839
82840     contactAnniversary.date  = date;
82841     contactAnniversary.label = label || null;
82842
82843     this.__defineGetter__("date", function () {
82844         return contactAnniversary.date;
82845     });
82846     this.__defineSetter__("date", function (val) {
82847         try {
82848             contactAnniversary.date = t.Date(val);
82849         } catch (e) {
82850         }
82851     });
82852
82853     this.__defineGetter__("label", function () {
82854         return contactAnniversary.label;
82855     });
82856     this.__defineSetter__("label", function (val) {
82857         try {
82858             contactAnniversary.label = t.DOMString(val, "?");
82859         } catch (e) {
82860         }
82861     });
82862 };
82863
82864 module.exports = ContactAnniversary;
82865
82866 });
82867 define('ripple/platform/tizen/2.0/ContactBase', function (require, exports, module) {
82868 /*
82869  *  Copyright 2013 Intel Corporation.
82870  *
82871  * Licensed under the Apache License, Version 2.0 (the "License");
82872  * you may not use this file except in compliance with the License.
82873  * You may obtain a copy of the License at
82874  *
82875  * http://www.apache.org/licenses/LICENSE-2.0
82876  *
82877  * Unless required by applicable law or agreed to in writing, software
82878  * distributed under the License is distributed on an "AS IS" BASIS,
82879  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82880  * See the License for the specific language governing permissions and
82881  * limitations under the License.
82882  */
82883
82884 var decorator = require('ripple/platform/tizen/2.0/decorator'),
82885     t = require('ripple/platform/tizen/2.0/typecast'),
82886     ContactName = require('ripple/platform/tizen/2.0/ContactName'),
82887     ContactAddress = require('ripple/platform/tizen/2.0/ContactAddress'),
82888     ContactPhoneNumber = require('ripple/platform/tizen/2.0/ContactPhoneNumber'),
82889     ContactEmailAddress = require('ripple/platform/tizen/2.0/ContactEmailAddress'),
82890     ContactAnniversary = require('ripple/platform/tizen/2.0/ContactAnniversary'),
82891     ContactOrganization = require('ripple/platform/tizen/2.0/ContactOrganization'),
82892     ContactWebSite = require('ripple/platform/tizen/2.0/ContactWebSite'),
82893     Contact;
82894
82895 Contact = function () {
82896     var voc;
82897
82898     // private
82899     function construct() {
82900         this.name          = null;
82901         this.addresses     = [];
82902         this.photoURI      = null;
82903         this.phoneNumbers  = [];
82904         this.emails        = [];
82905         this.birthday      = null;
82906         this.anniversaries = [];
82907         this.organizations = [];
82908         this.notes         = [];
82909         this.urls          = [];
82910         this.ringtoneURI   = null;
82911         this.groupIds      = [];
82912     }
82913
82914     // Constructor
82915     function Contact_ContactInit(contactInitDict) {
82916         var i, attr, arr;
82917
82918         construct.apply(this);
82919
82920         for (attr in contactInitDict) {
82921             switch (attr) {
82922             case "name":
82923                 this[attr] = new ContactName(contactInitDict[attr]);
82924                 break;
82925
82926             case "addresses":
82927                 arr = contactInitDict[attr];
82928                 if (arr) {
82929                     for (i in arr) {
82930                         this[attr][i] = new ContactAddress(arr[i]);
82931                     }
82932                 }
82933                 break;
82934
82935             case "phoneNumbers":
82936                 arr = contactInitDict[attr];
82937                 if (arr) {
82938                     for (i in arr) {
82939                         this[attr][i] = new ContactPhoneNumber(arr[i].number,
82940                                 arr[i].types || null, arr[i].isDefault || null);
82941                     }
82942                 }
82943                 break;
82944
82945             case "emails":
82946                 arr = contactInitDict[attr];
82947                 if (arr) {
82948                     for (i in arr) {
82949                         this[attr][i] = new ContactEmailAddress(arr[i].email,
82950                                 arr[i].types || null, arr[i].isDefault || null);
82951                     }
82952                 }
82953                 break;
82954
82955             case "birthday":
82956                 this[attr] = new Date(contactInitDict[attr]);
82957                 break;
82958
82959             case "anniversaries":
82960                 arr = contactInitDict[attr];
82961                 if (arr) {
82962                     for (i in arr) {
82963                         this[attr][i] = new ContactAnniversary(arr[i].date,
82964                                 arr[i].label || null);
82965                     }
82966                 }
82967                 break;
82968
82969             case "organizations":
82970                 arr = contactInitDict[attr];
82971                 if (arr) {
82972                     for (i in arr) {
82973                         this[attr][i] = new ContactOrganization(arr[i]);
82974                     }
82975                 }
82976                 break;
82977
82978             case "notes":
82979             case "groupIds":
82980                 arr = contactInitDict[attr];
82981                 if (arr) {
82982                     for (i in arr) {
82983                         this[attr][i] = arr[i];
82984                     }
82985                 }
82986                 break;
82987
82988             case "urls":
82989                 arr = contactInitDict[attr];
82990                 if (arr) {
82991                     for (i in arr) {
82992                         this[attr][i] = new ContactWebSite(arr[i].url,
82993                                 arr[i].type || null);
82994                     }
82995                 }
82996                 break;
82997
82998             default:
82999                 this[attr] = contactInitDict[attr];
83000                 break;
83001             }
83002         }
83003
83004         decorator.Contact(this);
83005     }
83006
83007     function Contact_DOMString(stringRepresentation) {
83008     }
83009
83010     voc = [Contact_ContactInit, Contact_DOMString];
83011     t.Contact(arguments, this, voc);
83012 };
83013
83014 module.exports = Contact;
83015
83016 });
83017 define('ripple/platform/tizen/2.0/ContactEmailAddress', function (require, exports, module) {
83018 /*
83019  *  Copyright 2013 Intel Corporation.
83020  *
83021  * Licensed under the Apache License, Version 2.0 (the "License");
83022  * you may not use this file except in compliance with the License.
83023  * You may obtain a copy of the License at
83024  *
83025  * http://www.apache.org/licenses/LICENSE-2.0
83026  *
83027  * Unless required by applicable law or agreed to in writing, software
83028  * distributed under the License is distributed on an "AS IS" BASIS,
83029  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83030  * See the License for the specific language governing permissions and
83031  * limitations under the License.
83032  */
83033
83034 var t = require('ripple/platform/tizen/2.0/typecast'),
83035     ContactEmailAddress;
83036
83037 ContactEmailAddress = function (email, types, isDefault) {
83038     var contactEmailAddress = {};
83039
83040     t.ContactEmailAddress(arguments, this);
83041
83042     contactEmailAddress.email     = email;
83043     contactEmailAddress.isDefault = isDefault || false;
83044     contactEmailAddress.types     = (types && types[0]) ? types : ["WORK"];
83045
83046     this.__defineGetter__("email", function () {
83047         return contactEmailAddress.email;
83048     });
83049     this.__defineSetter__("email", function (val) {
83050         try {
83051             contactEmailAddress.email = t.DOMString(val);
83052         } catch (e) {
83053         }
83054     });
83055
83056     this.__defineGetter__("isDefault", function () {
83057         return contactEmailAddress.isDefault;
83058     });
83059     this.__defineSetter__("isDefault", function (val) {
83060         try {
83061             contactEmailAddress.isDefault = t.boolean(val);
83062         } catch (e) {
83063         }
83064     });
83065
83066     this.__defineGetter__("types", function () {
83067         return contactEmailAddress.types;
83068     });
83069     this.__defineSetter__("types", function (val) {
83070         try {
83071             contactEmailAddress.types = t.DOMString(val, "[]");
83072         } catch (e) {
83073         }
83074     });
83075 };
83076
83077 module.exports = ContactEmailAddress;
83078
83079 });
83080 define('ripple/platform/tizen/2.0/ContactGroup', function (require, exports, module) {
83081 /*
83082  *  Copyright 2013 Intel Corporation.
83083  *
83084  * Licensed under the Apache License, Version 2.0 (the "License");
83085  * you may not use this file except in compliance with the License.
83086  * You may obtain a copy of the License at
83087  *
83088  * http://www.apache.org/licenses/LICENSE-2.0
83089  *
83090  * Unless required by applicable law or agreed to in writing, software
83091  * distributed under the License is distributed on an "AS IS" BASIS,
83092  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83093  * See the License for the specific language governing permissions and
83094  * limitations under the License.
83095  */
83096
83097 var t = require('ripple/platform/tizen/2.0/typecast'),
83098     ContactGroup;
83099
83100 ContactGroup = function (name, ringtoneURI, photoURI) {
83101     var contactGroup = {};
83102
83103     t.ContactGroup(arguments, this);
83104
83105     contactGroup.name        = name;
83106     contactGroup.ringtoneURI = ringtoneURI || null;
83107     contactGroup.photoURI    = photoURI || null;
83108
83109     this.__defineGetter__("id", function () {
83110         return null;
83111     });
83112
83113     this.__defineGetter__("addressBookId", function () {
83114         return null;
83115     });
83116
83117     this.__defineGetter__("name", function () {
83118         return contactGroup.name;
83119     });
83120     this.__defineSetter__("name", function (val) {
83121         try {
83122             contactGroup.name = t.DOMString(val);
83123         } catch (e) {
83124         }
83125     });
83126
83127     this.__defineGetter__("ringtoneURI", function () {
83128         return contactGroup.ringtoneURI;
83129     });
83130     this.__defineSetter__("ringtoneURI", function (val) {
83131         try {
83132             contactGroup.ringtoneURI = t.DOMString(val, "?");
83133         } catch (e) {
83134         }
83135     });
83136
83137     this.__defineGetter__("photoURI", function () {
83138         return contactGroup.photoURI;
83139     });
83140     this.__defineSetter__("photoURI", function (val) {
83141         try {
83142             contactGroup.photoURI = t.DOMString(val, "?");
83143         } catch (e) {
83144         }
83145     });
83146
83147     this.__defineGetter__("readOnly", function () {
83148         return false;
83149     });
83150 };
83151
83152 module.exports = ContactGroup;
83153
83154 });
83155 define('ripple/platform/tizen/2.0/ContactName', function (require, exports, module) {
83156 /*
83157  *  Copyright 2013 Intel Corporation.
83158  *
83159  * Licensed under the Apache License, Version 2.0 (the "License");
83160  * you may not use this file except in compliance with the License.
83161  * You may obtain a copy of the License at
83162  *
83163  * http://www.apache.org/licenses/LICENSE-2.0
83164  *
83165  * Unless required by applicable law or agreed to in writing, software
83166  * distributed under the License is distributed on an "AS IS" BASIS,
83167  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83168  * See the License for the specific language governing permissions and
83169  * limitations under the License.
83170  */
83171
83172 var t = require('ripple/platform/tizen/2.0/typecast'),
83173     ContactName;
83174
83175 ContactName = function (nameInitDict) {
83176     var contactName = {}, attr;
83177
83178     t.ContactName(arguments, this);
83179
83180     contactName.prefix            = null;
83181     contactName.suffix            = null;
83182     contactName.firstName         = null;
83183     contactName.middleName        = null;
83184     contactName.lastName          = null;
83185     contactName.nicknames         = [];
83186     contactName.phoneticFirstName = null;
83187     contactName.phoneticLastName  = null;
83188
83189     this.__defineGetter__("prefix", function () {
83190         return contactName.prefix;
83191     });
83192     this.__defineSetter__("prefix", function (val) {
83193         try {
83194             contactName.prefix = t.DOMString(val, "?");
83195         } catch (e) {
83196         }
83197     });
83198
83199     this.__defineGetter__("suffix", function () {
83200         return contactName.suffix;
83201     });
83202     this.__defineSetter__("suffix", function (val) {
83203         try {
83204             contactName.suffix = t.DOMString(val, "?");
83205         } catch (e) {
83206         }
83207     });
83208
83209     this.__defineGetter__("firstName", function () {
83210         return contactName.firstName;
83211     });
83212     this.__defineSetter__("firstName", function (val) {
83213         try {
83214             contactName.firstName = t.DOMString(val, "?");
83215         } catch (e) {
83216         }
83217     });
83218
83219     this.__defineGetter__("middleName", function () {
83220         return contactName.middleName;
83221     });
83222     this.__defineSetter__("middleName", function (val) {
83223         try {
83224             contactName.middleName = t.DOMString(val, "?");
83225         } catch (e) {
83226         }
83227     });
83228
83229     this.__defineGetter__("lastName", function () {
83230         return contactName.lastName;
83231     });
83232     this.__defineSetter__("lastName", function (val) {
83233         try {
83234             contactName.lastName = t.DOMString(val, "?");
83235         } catch (e) {
83236         }
83237     });
83238
83239     this.__defineGetter__("nicknames", function () {
83240         return contactName.nicknames;
83241     });
83242     this.__defineSetter__("nicknames", function (val) {
83243         try {
83244             contactName.nicknames = t.DOMString(val, "[]");
83245         } catch (e) {
83246         }
83247     });
83248
83249     this.__defineGetter__("phoneticFirstName", function () {
83250         return contactName.phoneticFirstName;
83251     });
83252     this.__defineSetter__("phoneticFirstName", function (val) {
83253         try {
83254             contactName.phoneticFirstName = t.DOMString(val, "?");
83255         } catch (e) {
83256         }
83257     });
83258
83259     this.__defineGetter__("phoneticLastName", function () {
83260         return contactName.phoneticLastName;
83261     });
83262     this.__defineSetter__("phoneticLastName", function (val) {
83263         try {
83264             contactName.phoneticLastName = t.DOMString(val, "?");
83265         } catch (e) {
83266         }
83267     });
83268
83269     this.__defineGetter__("displayName", function () {
83270         return null;
83271     });
83272
83273     if (nameInitDict) {
83274         for (attr in nameInitDict) {
83275             contactName[attr] = nameInitDict[attr];
83276         }
83277     }
83278 };
83279
83280 module.exports = ContactName;
83281
83282 });
83283 define('ripple/platform/tizen/2.0/ContactOrganization', function (require, exports, module) {
83284 /*
83285  *  Copyright 2013 Intel Corporation.
83286  *
83287  * Licensed under the Apache License, Version 2.0 (the "License");
83288  * you may not use this file except in compliance with the License.
83289  * You may obtain a copy of the License at
83290  *
83291  * http://www.apache.org/licenses/LICENSE-2.0
83292  *
83293  * Unless required by applicable law or agreed to in writing, software
83294  * distributed under the License is distributed on an "AS IS" BASIS,
83295  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83296  * See the License for the specific language governing permissions and
83297  * limitations under the License.
83298  */
83299
83300 var t = require('ripple/platform/tizen/2.0/typecast'),
83301     ContactOrganization;
83302
83303 ContactOrganization = function (orgInitDict) {
83304     var contactOrganization = {}, attr;
83305
83306     t.ContactOrganization(arguments, this);
83307
83308     contactOrganization.name       = null;
83309     contactOrganization.department = null;
83310     contactOrganization.title      = null;
83311     contactOrganization.role       = null;
83312     contactOrganization.logoURI    = null;
83313
83314     this.__defineGetter__("name", function () {
83315         return contactOrganization.name;
83316     });
83317     this.__defineSetter__("name", function (val) {
83318         try {
83319             contactOrganization.name = t.DOMString(val, "?");
83320         } catch (e) {
83321         }
83322     });
83323
83324     this.__defineGetter__("department", function () {
83325         return contactOrganization.department;
83326     });
83327     this.__defineSetter__("department", function (val) {
83328         try {
83329             contactOrganization.department = t.DOMString(val, "?");
83330         } catch (e) {
83331         }
83332     });
83333
83334     this.__defineGetter__("title", function () {
83335         return contactOrganization.title;
83336     });
83337     this.__defineSetter__("title", function (val) {
83338         try {
83339             contactOrganization.title = t.DOMString(val, "?");
83340         } catch (e) {
83341         }
83342     });
83343
83344     this.__defineGetter__("role", function () {
83345         return contactOrganization.role;
83346     });
83347     this.__defineSetter__("role", function (val) {
83348         try {
83349             contactOrganization.role = t.DOMString(val, "?");
83350         } catch (e) {
83351         }
83352     });
83353
83354     this.__defineGetter__("logoURI", function () {
83355         return contactOrganization.logoURI;
83356     });
83357     this.__defineSetter__("logoURI", function (val) {
83358         try {
83359             contactOrganization.logoURI = t.DOMString(val, "?");
83360         } catch (e) {
83361         }
83362     });
83363
83364     if (orgInitDict) {
83365         for (attr in orgInitDict) {
83366             contactOrganization[attr] = orgInitDict[attr];
83367         }
83368     }
83369 };
83370
83371 module.exports = ContactOrganization;
83372
83373 });
83374 define('ripple/platform/tizen/2.0/ContactPhoneNumber', function (require, exports, module) {
83375 /*
83376  *  Copyright 2013 Intel Corporation.
83377  *
83378  * Licensed under the Apache License, Version 2.0 (the "License");
83379  * you may not use this file except in compliance with the License.
83380  * You may obtain a copy of the License at
83381  *
83382  * http://www.apache.org/licenses/LICENSE-2.0
83383  *
83384  * Unless required by applicable law or agreed to in writing, software
83385  * distributed under the License is distributed on an "AS IS" BASIS,
83386  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83387  * See the License for the specific language governing permissions and
83388  * limitations under the License.
83389  */
83390
83391 var t = require('ripple/platform/tizen/2.0/typecast'),
83392     ContactPhoneNumber;
83393
83394 ContactPhoneNumber = function (number, types, isDefault) {
83395     var contactPhoneNumber = {};
83396
83397     t.ContactPhoneNumber(arguments, this);
83398
83399     contactPhoneNumber.number    = number;
83400     contactPhoneNumber.isDefault = isDefault || false;
83401     contactPhoneNumber.types     = (types && types[0]) ? types : ["VOICE"];
83402
83403     this.__defineGetter__("number", function () {
83404         return contactPhoneNumber.number;
83405     });
83406     this.__defineSetter__("number", function (val) {
83407         try {
83408             contactPhoneNumber.number = t.DOMString(val);
83409         } catch (e) {
83410         }
83411     });
83412
83413     this.__defineGetter__("isDefault", function () {
83414         return contactPhoneNumber.isDefault;
83415     });
83416     this.__defineSetter__("isDefault", function (val) {
83417         try {
83418             contactPhoneNumber.isDefault = t.boolean(val);
83419         } catch (e) {
83420         }
83421     });
83422
83423     this.__defineGetter__("types", function () {
83424         return contactPhoneNumber.types;
83425     });
83426     this.__defineSetter__("types", function (val) {
83427         try {
83428             contactPhoneNumber.types = t.DOMString(val, "[]");
83429         } catch (e) {
83430         }
83431     });
83432 };
83433
83434 module.exports = ContactPhoneNumber;
83435
83436 });
83437 define('ripple/platform/tizen/2.0/ContactRef', function (require, exports, module) {
83438 /*
83439  *  Copyright 2013 Intel Corporation.
83440  *
83441  * Licensed under the Apache License, Version 2.0 (the "License");
83442  * you may not use this file except in compliance with the License.
83443  * You may obtain a copy of the License at
83444  *
83445  * http://www.apache.org/licenses/LICENSE-2.0
83446  *
83447  * Unless required by applicable law or agreed to in writing, software
83448  * distributed under the License is distributed on an "AS IS" BASIS,
83449  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83450  * See the License for the specific language governing permissions and
83451  * limitations under the License.
83452  */
83453
83454 var t = require('ripple/platform/tizen/2.0/typecast'),
83455     ContactRef;
83456
83457 ContactRef = function (addressBookId, contactId) {
83458     var contactRef = {};
83459
83460     t.ContactRef(arguments, this);
83461
83462     contactRef.addressBookId = addressBookId;
83463     contactRef.contactId     = contactId;
83464
83465     this.__defineGetter__("addressBookId", function () {
83466         return contactRef.addressBookId;
83467     });
83468     this.__defineSetter__("addressBookId", function (val) {
83469         try {
83470             contactRef.addressBookId = t.AddressBookId(val);
83471         } catch (e) {
83472         }
83473     });
83474
83475     this.__defineGetter__("contactId", function () {
83476         return contactRef.contactId;
83477     });
83478     this.__defineSetter__("contactId", function (val) {
83479         try {
83480             contactRef.contactId = t.ContactId(val);
83481         } catch (e) {
83482         }
83483     });
83484 };
83485
83486 module.exports = ContactRef;
83487
83488 });
83489 define('ripple/platform/tizen/2.0/ContactWebSite', function (require, exports, module) {
83490 /*
83491  *  Copyright 2013 Intel Corporation.
83492  *
83493  * Licensed under the Apache License, Version 2.0 (the "License");
83494  * you may not use this file except in compliance with the License.
83495  * You may obtain a copy of the License at
83496  *
83497  * http://www.apache.org/licenses/LICENSE-2.0
83498  *
83499  * Unless required by applicable law or agreed to in writing, software
83500  * distributed under the License is distributed on an "AS IS" BASIS,
83501  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83502  * See the License for the specific language governing permissions and
83503  * limitations under the License.
83504  */
83505
83506 var t = require('ripple/platform/tizen/2.0/typecast'),
83507     ContactWebSite;
83508
83509 ContactWebSite = function (url, type) {
83510     var contactWebSite = {};
83511
83512     t.ContactWebSite(arguments, this);
83513
83514     contactWebSite.url  = url;
83515     contactWebSite.type = type || "HOMEPAGE";
83516
83517     this.__defineGetter__("url", function () {
83518         return contactWebSite.url;
83519     });
83520     this.__defineSetter__("url", function (val) {
83521         try {
83522             contactWebSite.url = t.DOMString(val);
83523         } catch (e) {
83524         }
83525     });
83526
83527     this.__defineGetter__("type", function () {
83528         return contactWebSite.type;
83529     });
83530     this.__defineSetter__("type", function (val) {
83531         try {
83532             contactWebSite.type = t.DOMString(val);
83533         } catch (e) {
83534         }
83535     });
83536 };
83537
83538 module.exports = ContactWebSite;
83539
83540 });
83541 define('ripple/platform/tizen/2.0/Conversation', function (require, exports, module) {
83542 /*
83543  *  Copyright 2012 Intel Corporation.
83544  *
83545  * Licensed under the Apache License, Version 2.0 (the "License"),
83546  * you may not use this file except in compliance with the License.
83547  * You may obtain a copy of the License at
83548  *
83549  * http://www.apache.org/licenses/LICENSE-2.0
83550  *
83551  * Unless required by applicable law or agreed to in writing, software
83552  * distributed under the License is distributed on an "AS IS" BASIS,
83553  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83554  * See the License for the specific language governing permissions and
83555  * limitations under the License.
83556  */
83557 var utils = require('ripple/utils');
83558
83559 module.exports = function (opt) {
83560     var conv = {}, priv = utils.copy(opt);
83561
83562     conv.__defineGetter__("id", function () {
83563         return priv.id;
83564     });
83565     conv.__defineGetter__("type", function () {
83566         return priv.type;
83567     });
83568     conv.__defineGetter__("timestamp", function () {
83569         return priv.timestamp;
83570     });
83571     conv.__defineGetter__("messageCount", function () {
83572         return priv.messageCount;
83573     });
83574     conv.__defineGetter__("unreadMessages", function () {
83575         return priv.unreadMessages;
83576     });
83577     conv.__defineGetter__("preview", function () {
83578         return priv.preview;
83579     });
83580     conv.__defineGetter__("subject", function () {
83581         return priv.subject;
83582     });
83583     conv.__defineGetter__("isRead", function () {
83584         return priv.isRead;
83585     });
83586     conv.__defineGetter__("from", function () {
83587         return priv.from;
83588     });
83589     conv.__defineGetter__("to", function () {
83590         return priv.to;
83591     });
83592     conv.__defineGetter__("cc", function () {
83593         return priv.cc;
83594     });
83595     conv.__defineGetter__("bcc", function () {
83596         return priv.bcc;
83597     });
83598     conv.__defineGetter__("lastMessageId", function () {
83599         return priv.lastMessageId;
83600     });
83601     return conv;
83602 };
83603
83604 });
83605 define('ripple/platform/tizen/2.0/DeviceMotionEvent', function (require, exports, module) {
83606 /*
83607  *  Copyright 2012 Intel Corporation.
83608  *
83609  * Licensed under the Apache License, Version 2.0 (the "License");
83610  * you may not use this file except in compliance with the License.
83611  * You may obtain a copy of the License at
83612  *
83613  * http://www.apache.org/licenses/LICENSE-2.0
83614  *
83615  * Unless required by applicable law or agreed to in writing, software
83616  * distributed under the License is distributed on an "AS IS" BASIS,
83617  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83618  * See the License for the specific language governing permissions and
83619  * limitations under the License.
83620  */
83621
83622 var utils = require('ripple/utils'),
83623     Event = require('ripple/platform/tizen/2.0/EventBase');
83624
83625 module.exports = function () {
83626     var _self = {
83627             acceleration: {
83628                 x: null,
83629                 y: null,
83630                 z: null
83631             },
83632             accelerationIncludingGravity: {
83633                 x: null,
83634                 y: null,
83635                 z: null
83636             },
83637             rotationRate: {
83638                 alpha: null,
83639                 beta: null,
83640                 gamma: null
83641             },
83642             interval: 0
83643         };
83644
83645     Event.call(this);
83646
83647     this.__defineGetter__("acceleration", function () {
83648         return _self.acceleration;
83649     });
83650
83651     this.__defineGetter__("accelerationIncludingGravity", function () {
83652         return _self.accelerationIncludingGravity;
83653     });
83654
83655     this.__defineGetter__("rotationRate", function () {
83656         return _self.rotationRate;
83657     });
83658
83659     this.__defineGetter__("interval", function () {
83660         return _self.interval;
83661     });
83662
83663     this.initAccelerometerEvent = function (accelerometerType, accelerometerBubbles, accelerometerCancelable,
83664                                             accelerationData, accelerationGData, rotationRateData, intervalValue) {
83665         this.initEvent(accelerometerType, accelerometerBubbles, accelerometerCancelable);
83666
83667         _self.acceleration = utils.copy(accelerationData);
83668         _self.accelerationIncludingGravity = utils.copy(accelerationGData);
83669         _self.rotationRate = utils.copy(rotationRateData);
83670         _self.interval = intervalValue;
83671     };
83672 };
83673
83674
83675 });
83676 define('ripple/platform/tizen/2.0/DeviceOrientationEvent', function (require, exports, module) {
83677 /*
83678  *  Copyright 2012 Intel Corporation.
83679  *
83680  * Licensed under the Apache License, Version 2.0 (the "License");
83681  * you may not use this file except in compliance with the License.
83682  * You may obtain a copy of the License at
83683  *
83684  * http://www.apache.org/licenses/LICENSE-2.0
83685  *
83686  * Unless required by applicable law or agreed to in writing, software
83687  * distributed under the License is distributed on an "AS IS" BASIS,
83688  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83689  * See the License for the specific language governing permissions and
83690  * limitations under the License.
83691  */
83692
83693 var Event = require('ripple/platform/tizen/2.0/EventBase');
83694
83695 module.exports = function () {
83696     var _self = {
83697             alpha: null,
83698             beta: null,
83699             gamma: null,
83700             absolute: false,
83701         };
83702
83703     Event.call(this);
83704
83705     this.__defineGetter__("alpha", function () {
83706         return _self.alpha;
83707     });
83708
83709     this.__defineGetter__("beta", function () {
83710         return _self.beta;
83711     });
83712
83713     this.__defineGetter__("gamma", function () {
83714         return _self.gamma;
83715     });
83716
83717     this.__defineGetter__("absolute", function () {
83718         return _self.absolute;
83719     });
83720
83721     this.initDeviceOrientationEvent = function (orientationType, orientationBubbles, orientationCancelable,
83722                                                alphaData, betaData, gammaData, isAbsolute) {
83723         this.initEvent(orientationType, orientationBubbles, orientationCancelable);
83724
83725         _self.alpha    = alphaData;
83726         _self.beta     = betaData;
83727         _self.gamma    = gammaData;
83728         _self.absolute = isAbsolute;
83729     };
83730 };
83731
83732
83733 });
83734 define('ripple/platform/tizen/2.0/DownloadRequest', function (require, exports, module) {
83735 /*
83736  *  Copyright 2013 Intel Corporation.
83737  *
83738  * Licensed under the Apache License, Version 2.0 (the "License");
83739  * you may not use this file except in compliance with the License.
83740  * You may obtain a copy of the License at
83741  *
83742  * http://www.apache.org/licenses/LICENSE-2.0
83743  *
83744  * Unless required by applicable law or agreed to in writing, software
83745  * distributed under the License is distributed on an "AS IS" BASIS,
83746  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83747  * See the License for the specific language governing permissions and
83748  * limitations under the License.
83749  */
83750
83751 var t = require('ripple/platform/tizen/2.0/typecast'),
83752     DownloadRequest;
83753
83754 DownloadRequest = function (url, destination, fileName, networkType,
83755         httpHeader) {
83756     var downloadRequest = {};
83757
83758     t.DownloadRequest(arguments, this);
83759
83760     this.__defineGetter__("url", function () {
83761         return downloadRequest.url;
83762     });
83763     this.__defineSetter__("url", function (val) {
83764         try {
83765             downloadRequest.url = t.DOMString(val);
83766         } catch (e) {
83767         }
83768     });
83769
83770     this.__defineGetter__("networkType", function () {
83771         return downloadRequest.networkType;
83772     });
83773     this.__defineSetter__("networkType", function (val) {
83774         try {
83775             downloadRequest.networkType = t.DownloadNetworkType(val, "?");
83776         } catch (e) {
83777         }
83778     });
83779
83780     this.destination            = destination || "";
83781     this.fileName               = fileName || "";
83782     this.httpHeader             = httpHeader || {};
83783
83784     downloadRequest.url         = url;
83785     downloadRequest.networkType = networkType || "ALL";
83786 };
83787
83788 module.exports = DownloadRequest;
83789
83790 });
83791 define('ripple/platform/tizen/2.0/EventBase', function (require, exports, module) {
83792 /*
83793  *  Copyright 2012 Intel Corporation.
83794  *
83795  * Licensed under the Apache License, Version 2.0 (the "License");
83796  * you may not use this file except in compliance with the License.
83797  * You may obtain a copy of the License at
83798  *
83799  * http://www.apache.org/licenses/LICENSE-2.0
83800  *
83801  * Unless required by applicable law or agreed to in writing, software
83802  * distributed under the License is distributed on an "AS IS" BASIS,
83803  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83804  * See the License for the specific language governing permissions and
83805  * limitations under the License.
83806  */
83807
83808 module.exports = function () {
83809     var _self = {
83810         CAPTURING_PHASE: 1,
83811         AT_TARGET:  2,
83812         BUBBLING_PHASE: 3,
83813
83814         type: '',
83815         target: null, //new EventTarget(),
83816         currentTarget: null, //new EventTarget(),
83817         eventPhase: 0,
83818         bubbles: false,
83819         cancelable: false,
83820         timeStamp: 0
83821     };
83822
83823     this.__defineGetter__("type", function () {
83824         return _self.type;
83825     });
83826
83827     this.__defineGetter__("target", function () {
83828         return _self.target;
83829     });
83830
83831     this.__defineGetter__("currentTarget", function () {
83832         return _self.currentTarget;
83833     });
83834
83835     this.__defineGetter__("eventPhase", function () {
83836         return _self.eventPhase;
83837     });
83838
83839     this.__defineGetter__("bubbles", function () {
83840         return _self.bubbles;
83841     });
83842
83843     this.__defineGetter__("cancelable", function () {
83844         return _self.cancelable;
83845     });
83846
83847     this.__defineGetter__("timeStamp", function () {
83848         return _self.timeStamp;
83849     });
83850
83851     this.stopPropagation = function () {};
83852
83853     this.preventDefault = function () {};
83854
83855     this.initEvent = function (eventTypeArg, canBubbleArg, cancelableArg) {
83856         _self.type = eventTypeArg;
83857         _self.bubbles = canBubbleArg;
83858         _self.cancelable = cancelableArg;
83859
83860         _self.timeStamp = (new Date()).getTime();
83861     };
83862
83863     return _self;
83864 };
83865
83866
83867 });
83868 define('ripple/platform/tizen/2.0/GeoCircleBounds', function (require, exports, module) {
83869 /*
83870  *  Copyright 2012 Intel Corporation.
83871  *
83872  * Licensed under the Apache License, Version 2.0 (the "License");
83873  * you may not use this file except in compliance with the License.
83874  * You may obtain a copy of the License at
83875  *
83876  * http://www.apache.org/licenses/LICENSE-2.0
83877  *
83878  * Unless required by applicable law or agreed to in writing, software
83879  * distributed under the License is distributed on an "AS IS" BASIS,
83880  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83881  * See the License for the specific language governing permissions and
83882  * limitations under the License.
83883  */
83884
83885 module.exports = function (_center, _radius) {
83886     var center, radius;
83887     center = _center || null;
83888     radius = _radius || 0;
83889
83890     this.__defineGetter__("center", function () {
83891         return center;
83892     });
83893
83894     this.__defineGetter__("radius", function () {
83895         return radius;
83896     });
83897 };
83898
83899 });
83900 define('ripple/platform/tizen/2.0/GeoPolyBounds', function (require, exports, module) {
83901 /*
83902  *  Copyright 2012 Intel Corporation.
83903  *
83904  * Licensed under the Apache License, Version 2.0 (the "License");
83905  * you may not use this file except in compliance with the License.
83906  * You may obtain a copy of the License at
83907  *
83908  * http://www.apache.org/licenses/LICENSE-2.0
83909  *
83910  * Unless required by applicable law or agreed to in writing, software
83911  * distributed under the License is distributed on an "AS IS" BASIS,
83912  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83913  * See the License for the specific language governing permissions and
83914  * limitations under the License.
83915  */
83916
83917 module.exports = function (_points) {
83918     var points = _points || [];
83919
83920     this.__defineGetter__("points", function () {
83921         return points;
83922     });
83923 };
83924
83925 });
83926 define('ripple/platform/tizen/2.0/GeoRectBounds', function (require, exports, module) {
83927 /*
83928  *  Copyright 2012 Intel Corporation.
83929  *
83930  * Licensed under the Apache License, Version 2.0 (the "License");
83931  * you may not use this file except in compliance with the License.
83932  * You may obtain a copy of the License at
83933  *
83934  * http://www.apache.org/licenses/LICENSE-2.0
83935  *
83936  * Unless required by applicable law or agreed to in writing, software
83937  * distributed under the License is distributed on an "AS IS" BASIS,
83938  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83939  * See the License for the specific language governing permissions and
83940  * limitations under the License.
83941  */
83942
83943 module.exports = function (_southWest, _northEast) {
83944     var southWest, northEast;
83945     southWest = _southWest || null;
83946     northEast = _northEast || null;
83947
83948     this.__defineGetter__("southWest", function () {
83949         return southWest;
83950     });
83951
83952     this.__defineGetter__("northEast", function () {
83953         return northEast;
83954     });
83955 };
83956
83957 });
83958 define('ripple/platform/tizen/2.0/GeocodeOptions', function (require, exports, module) {
83959 /*      
83960  *  Copyright 2012 Intel Corporation.
83961  *  
83962  * Licensed under the Apache License, Version 2.0 (the "License");
83963  * you may not use this file except in compliance with the License.
83964  * You may obtain a copy of the License at
83965  *  
83966  * http://www.apache.org/licenses/LICENSE-2.0
83967  *  
83968  * Unless required by applicable law or agreed to in writing, software
83969  * distributed under the License is distributed on an "AS IS" BASIS,
83970  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83971  * See the License for the specific language governing permissions and
83972  * limitations under the License.
83973  */
83974
83975 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
83976     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
83977     SortMode = require('ripple/platform/tizen/2.0/SortMode');
83978
83979 module.exports = function (_sortMode, _maxResults) {
83980     var _self;
83981     if (_sortMode !== null && _sortMode !== undefined) {
83982         if (typeof _sortMode !== "object") {
83983             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
83984         }
83985         try {
83986             new SortMode(_sortMode.attributeName, _sortMode.order);
83987         } catch (e) {
83988             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
83989         }
83990     }
83991     if (_maxResults !== null && _maxResults !== undefined) {
83992         if (typeof _maxResults !== "number") {
83993             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
83994         }
83995     }
83996
83997     _self = {
83998         sortMode : _sortMode,
83999         maxResults : _maxResults || 0
84000     };
84001
84002     return _self;
84003 };
84004
84005
84006 });
84007 define('ripple/platform/tizen/2.0/GeocodeResult', function (require, exports, module) {
84008 /*      
84009  *  Copyright 2012 Intel Corporation.
84010  *  
84011  * Licensed under the Apache License, Version 2.0 (the "License");
84012  * you may not use this file except in compliance with the License.
84013  * You may obtain a copy of the License at
84014  *  
84015  * http://www.apache.org/licenses/LICENSE-2.0
84016  *  
84017  * Unless required by applicable law or agreed to in writing, software
84018  * distributed under the License is distributed on an "AS IS" BASIS,
84019  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84020  * See the License for the specific language governing permissions and
84021  * limitations under the License.
84022  */
84023
84024 var SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates');
84025
84026 module.exports = function (lat, lon) {
84027     var _self, _coordinates, jsonStr, jsonObj;
84028
84029     _coordinates = new SimpleCoordinates(lat, lon);
84030
84031     jsonObj = {
84032         "type" : "Point",
84033         "coordinates" : [lat, lon]
84034     };
84035
84036     jsonStr = JSON.stringify(jsonObj);
84037
84038     _self = {
84039         coordinates : _coordinates,
84040         toGeoJSON : function () {
84041             return jsonStr;
84042         }
84043     };
84044     return _self;
84045 };
84046
84047
84048 });
84049 define('ripple/platform/tizen/2.0/GeometryFilter', function (require, exports, module) {
84050 /*
84051  *  Copyright 2012 Intel Corporation.
84052  *
84053  * Licensed under the Apache License, Version 2.0 (the "License");
84054  * you may not use this file except in compliance with the License.
84055  * You may obtain a copy of the License at
84056  *
84057  * http://www.apache.org/licenses/LICENSE-2.0
84058  *
84059  * Unless required by applicable law or agreed to in writing, software
84060  * distributed under the License is distributed on an "AS IS" BASIS,
84061  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84062  * See the License for the specific language governing permissions and
84063  * limitations under the License.
84064  */
84065
84066 module.exports = function (criteria, geometry) {
84067     var _self;
84068
84069     _self = {
84070         criteria: criteria,
84071         geometry: geometry
84072     };
84073
84074     return _self;
84075 };
84076
84077 });
84078 define('ripple/platform/tizen/2.0/Message', function (require, exports, module) {
84079 /*
84080  *  Copyright 2012 Intel Corporation.
84081  *
84082  * Licensed under the Apache License, Version 2.0 (the "License");
84083  * you may not use this file except in compliance with the License.
84084  * You may obtain a copy of the License at
84085  *
84086  * http://www.apache.org/licenses/LICENSE-2.0
84087  *
84088  * Unless required by applicable law or agreed to in writing, software
84089  * distributed under the License is distributed on an "AS IS" BASIS,
84090  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84091  * See the License for the specific language governing permissions and
84092  * limitations under the License.
84093  */
84094
84095 var msg_utils = require('ripple/platform/tizen/2.0/msg_utils'),
84096     MessageBody = require('ripple/platform/tizen/2.0/MessageBody'),
84097     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
84098     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException');
84099
84100 module.exports = function (type, messageInit) {
84101     var _id = null, _serviceId = null, _conversationId = null,
84102         _folderId = null, _type = type, _timestamp = null,
84103         _from = null, _hasAttachment = false, _messageStatus = null,
84104         msg = {};
84105
84106     if (messageInit !== undefined && messageInit !== null) {
84107         if (msg_utils.setMsg(messageInit, msg) === false) {
84108             throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
84109         }
84110         if (messageInit.priv !== undefined) {
84111             /* secret constructor for PrivateMessage */
84112             _id = messageInit.priv.id;
84113             _serviceId = messageInit.priv.serviceId;
84114             _conversationId = messageInit.priv.conversationId;
84115             _folderId = messageInit.priv.folderId;
84116             _type = messageInit.priv.type;
84117             _timestamp = new Date(messageInit.priv.timestamp);
84118             _from = messageInit.priv.from;
84119             _hasAttachment = messageInit.priv.hasAttachment;
84120             _messageStatus = messageInit.priv.messageStatus;
84121         }
84122         msg.body = new MessageBody(_id, msg.body.loaded, msg.body.plainBody, msg.body.htmlBody, []);
84123     }
84124
84125     msg.__defineGetter__("id", function () {
84126         return _id;
84127     });
84128     msg.__defineGetter__("conversationId", function () {
84129         return _conversationId;
84130     });
84131     msg.__defineGetter__("folderId", function () {
84132         return _folderId;
84133     });
84134     msg.__defineGetter__("type", function () {
84135         return _type;
84136     });
84137     msg.__defineGetter__("timestamp", function () {
84138         return _timestamp;
84139     });
84140     msg.__defineGetter__("from", function () {
84141         return _from;
84142     });
84143     msg.__defineGetter__("hasAttachment", function () {
84144         return _hasAttachment;
84145     });
84146     msg.__defineGetter__("messageStatus", function () {
84147         return _messageStatus;
84148     });
84149     return msg;
84150 };
84151
84152 });
84153 define('ripple/platform/tizen/2.0/MessageBody', function (require, exports, module) {
84154 /*
84155  *  Copyright 2012 Intel Corporation.
84156  *
84157  * Licensed under the Apache License, Version 2.0 (the "License");
84158  * you may not use this file except in compliance with the License.
84159  * You may obtain a copy of the License at
84160  *
84161  * http://www.apache.org/licenses/LICENSE-2.0
84162  *
84163  * Unless required by applicable law or agreed to in writing, software
84164  * distributed under the License is distributed on an "AS IS" BASIS,
84165  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84166  * See the License for the specific language governing permissions and
84167  * limitations under the License.
84168  */
84169
84170 module.exports = function (id, isloaded, _plainbody, _htmlbody, inlineattachments) {
84171     var msgbody, _id = id, _loaded = isloaded;
84172     msgbody = {
84173         plainBody: _plainbody,
84174         htmlBody: _htmlbody,
84175         inlineAttachments: [] // TODO: not support attachment yet
84176     };
84177     msgbody.__defineGetter__("messageId", function () {
84178         return _id;
84179     });
84180     msgbody.__defineGetter__("loaded", function () {
84181         return _loaded;
84182     });
84183     return msgbody;
84184 };
84185
84186 });
84187 define('ripple/platform/tizen/2.0/MessageFolder', function (require, exports, module) {
84188 /*
84189  *  Copyright 2012 Intel Corporation.
84190  *
84191  * Licensed under the Apache License, Version 2.0 (the "License");
84192  * you may not use this file except in compliance with the License.
84193  * You may obtain a copy of the License at
84194  *
84195  * http://www.apache.org/licenses/LICENSE-2.0
84196  *
84197  * Unless required by applicable law or agreed to in writing, software
84198  * distributed under the License is distributed on an "AS IS" BASIS,
84199  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84200  * See the License for the specific language governing permissions and
84201  * limitations under the License.
84202  */
84203
84204 module.exports = function (opt) {
84205     var folder = {}, _id = opt.id, _parentId = null, _serviceId = opt.serviceId,
84206         _contentType = opt.contentType, _name = opt.id, _path = opt.path,
84207         _type = opt.type, _synchronizable = opt.synchronizable;
84208
84209     folder.name = _name;
84210     folder.synchronizable = _synchronizable;
84211     
84212     folder.__defineGetter__("id", function () {
84213         return _id;
84214     });
84215     folder.__defineGetter__("parentId", function () {
84216         return _parentId;
84217     });
84218     folder.__defineGetter__("serviceId", function () {
84219         return _serviceId;
84220     });
84221     folder.__defineGetter__("contentType", function () {
84222         return _contentType;
84223     });
84224     folder.__defineGetter__("path", function () {
84225         return _path;
84226     });
84227     folder.__defineGetter__("type", function () {
84228         return _type;
84229     });
84230     return folder;
84231 };
84232
84233 });
84234 define('ripple/platform/tizen/2.0/MessageStorage', function (require, exports, module) {
84235 /*
84236  *  Copyright 2012 Intel Corporation.
84237  *
84238  * Licensed under the Apache License, Version 2.0 (the "License");
84239  * you may not use this file except in compliance with the License.
84240  * You may obtain a copy of the License at
84241  *
84242  * http://www.apache.org/licenses/LICENSE-2.0
84243  *
84244  * Unless required by applicable law or agreed to in writing, software
84245  * distributed under the License is distributed on an "AS IS" BASIS,
84246  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84247  * See the License for the specific language governing permissions and
84248  * limitations under the License.
84249  */
84250 var _self,
84251     utils = require('ripple/utils'),
84252     event = require('ripple/event'),
84253     Message = require('ripple/platform/tizen/2.0/Message'),
84254     Conversation = require('ripple/platform/tizen/2.0/Conversation'),
84255     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
84256     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
84257     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
84258     PrivMessage = require('ripple/platform/tizen/2.0/PrivMessage'),
84259     MessageFolder = require('ripple/platform/tizen/2.0/MessageFolder'),
84260     msg_utils = require('ripple/platform/tizen/2.0/msg_utils'),
84261     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
84262     t = require('ripple/platform/tizen/2.0/typedef'),
84263     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
84264     TIZEN_DEFAULT_MSG_FROM = {"messaging.sms": "13572468",
84265                               "messaging.mms": "13572468",
84266                               "messaging.email": "tizen.simulator@tizen.org"};
84267
84268 _self = function (messages, security_check) {
84269     var message_storage = {},
84270         _findMessage, _findConversation,
84271         _processMessageChange, _processConversationChange,
84272         _folders = {}, folderOpt = {},
84273         _msgListeners = {},
84274         _convListeners = {},
84275         _folderListeners = {},
84276         _security_check = security_check,
84277         _messages = messages;
84278
84279     // init folders
84280     folderOpt = {id: "INBOX", serviceId: _messages.id, contentType: _messages.type,
84281                  path: "inbox", type: "INBOX", synchronizable: true};
84282     _folders.INBOX = new MessageFolder(folderOpt);
84283     folderOpt = {id: "OUTBOX", serviceId: _messages.id, contentType: _messages.type,
84284                  path: "outbox", type: "OUTBOX", synchronizable: false};
84285     _folders.OUTBOX = new MessageFolder(folderOpt);
84286     folderOpt = {id: "DRAFT", serviceId: _messages.id, contentType: _messages.type,
84287                  path: "draft", type: "DRAFTS", synchronizable: false};
84288     _folders.DRAFT = new MessageFolder(folderOpt);
84289     folderOpt = {id: "SENTBOX", serviceId: _messages.id, contentType: _messages.type,
84290                  path: "sentbox", type: "SENTBOX", synchronizable: false};
84291     _folders.SENTBOX = new MessageFolder(folderOpt);
84292
84293     event.on("MsgRecv", function (msg) {
84294         // msg sent from panel to module
84295         if (msg.priv.type !== _messages.type ||
84296             msg.priv.serviceId !== _messages.id) {
84297             return;
84298         }
84299         // trigger Message add
84300         _processMessageChange([msg], "add");
84301         _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
84302
84303         if (_messages.conv[msg.priv.conversationId].messageCount === 1) {
84304             _processConversationChange([_messages.conv[msg.priv.conversationId]], "add");
84305         } else {
84306             _processConversationChange([_messages.conv[msg.priv.conversationId]], "update");
84307         }
84308     });
84309
84310     event.on("OutsideMessageReceived", function (msg) {
84311         // msg sent from module to panel
84312         if (msg.msg.priv.type !== _messages.type ||
84313             msg.msg.priv.serviceId !== _messages.id) {
84314             return;
84315         }
84316         // trigger conversation/Message add
84317         _processMessageChange([msg.msg], "add");
84318         _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
84319
84320         if (_messages.conv[msg.msg.priv.conversationId].messageCount === 1) {
84321             _processConversationChange([_messages.conv[msg.msg.priv.conversationId]], "add");
84322         } else {
84323             _processConversationChange([_messages.conv[msg.msg.priv.conversationId]], "update");
84324         }
84325     });
84326
84327     event.on("MsgSentRst", function (rst) {
84328         // ACK from panel when module sent a msg to panel
84329         if (rst.priv.type !== _messages.type ||
84330             rst.priv.serviceId !== _messages.id) {
84331             return;
84332         }
84333         // trigger conversation/Message Update
84334         _processMessageChange([rst], "update");
84335         _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
84336         _processConversationChange([_messages.conv[rst.priv.conversationId]], "update");
84337     });
84338
84339     _findMessage = function (src, filter) {
84340         var ret, foo = {};
84341         switch (filter.attributeName) {
84342         case "type":
84343             foo[filter.attributeName] = _messages.type;
84344             ret = tizen1_utils.matchAttributeFilter([foo],
84345                       filter.attributeName, filter.matchFlag, filter.matchValue);
84346             if (ret.length === 0) {
84347                 ret = [];
84348             } else {
84349                 // make an array
84350                 ret = utils.filter(src, function () { return true; });
84351             }
84352             break;
84353         case "id":
84354         case "conversationId":
84355         case "folderId":
84356         case "from":
84357         case "messageStatus":
84358             ret = tizen1_utils.matchAttributeFilter(src,
84359                       "priv." + filter.attributeName,
84360                       filter.matchFlag, filter.matchValue);
84361             break;
84362         case "hasAttachment":
84363             if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
84364                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
84365                               "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
84366             }
84367             ret = tizen1_utils.matchAttributeBooleanFilter(src,
84368                       "priv." + filter.attributeName, filter.matchValue);
84369             break;
84370         case "to":
84371         case "cc":
84372         case "bcc":
84373             ret = tizen1_utils.matchAttributeArrayFilter(src,
84374                       filter.attributeName, filter.matchFlag, filter.matchValue);
84375             break;
84376         case "body":
84377             ret = tizen1_utils.matchAttributeFilter(src,
84378                       filter.attributeName + ".plainBody",
84379                       filter.matchFlag, filter.matchValue);
84380             break;
84381         case "subject":
84382         case "inResponseTo":
84383             ret = tizen1_utils.matchAttributeFilter(src, filter.attributeName,
84384                       filter.matchFlag, filter.matchValue);
84385             break;
84386         case "isRead":
84387         case "isHighPriority":
84388             if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
84389                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
84390                               "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
84391             }
84392             ret = tizen1_utils.matchAttributeBooleanFilter(src,
84393                       filter.attributeName, filter.matchValue);
84394             break;
84395         case "timestamp":
84396             ret = tizen1_utils.matchAttributeRangeFilter(src,
84397                       "priv." + filter.attributeName,
84398                       filter.initialValue, filter.endValue);
84399             break;
84400
84401         case "attachments":
84402             throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR,
84403                                   "not support find by " + filter.attributeName));
84404         default:
84405             throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
84406                                    "invalid attributeName"));
84407         }
84408         return ret;
84409     };
84410
84411     _processMessageChange = function (messages, type) {
84412         var i, j, ret = [], tmp,
84413             operation = {"add": "messagesadded",
84414                          "remove": "messagesremoved",
84415                          "update": "messagesupdated"};
84416
84417         for (i in _msgListeners) {
84418             ret = [];
84419             if (_msgListeners[i].filter !== null) {
84420                 tmp = _findMessage(messages, _msgListeners[i].filter);
84421             } else {
84422                 tmp = messages;
84423             }
84424             if (tmp.length !== 0) {
84425                 for (j = 0; j < tmp.length; j++) {
84426                     ret.push(new Message(tmp[j].priv.type, tmp[j]));
84427                 }
84428                 _msgListeners[i].callback[operation[type]](ret);
84429             }
84430         }
84431     };
84432
84433     _findConversation = function (src, filter) {
84434         var ret, foo = {};
84435         switch (filter.attributeName) {
84436         case "type":
84437             foo[filter.attributeName] = _messages.type;
84438             ret = tizen1_utils.matchAttributeFilter([foo], filter.attributeName, filter.matchFlag, filter.matchValue);
84439             if (ret.length === 0) {
84440                 ret = [];
84441             } else {
84442                 // make an array
84443                 ret = utils.filter(_messages.conv, function () { return true; });
84444             }
84445             break;
84446         case "id":
84447         case "preview":
84448         case "subject":
84449         case "from":
84450         case "lastMessageId":
84451             ret = tizen1_utils.matchAttributeFilter(src, filter.attributeName, filter.matchFlag, filter.matchValue);
84452             break;
84453         case "to":
84454         case "cc":
84455         case "bcc":
84456             ret = tizen1_utils.matchAttributeArrayFilter(src,
84457                       filter.attributeName, filter.matchFlag, filter.matchValue);
84458             break;
84459         case "isRead":
84460             if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
84461                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
84462                               "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
84463             }
84464             ret = tizen1_utils.matchAttributeBooleanFilter(src,
84465                       filter.attributeName, filter.matchValue);
84466             break;
84467         case "timestamp":
84468         case "messageCount":
84469         case "unreadMessages":
84470             ret = tizen1_utils.matchAttributeRangeFilter(src,
84471                       filter.attributeName,
84472                       filter.initialValue, filter.endValue);
84473             break;
84474         default:
84475             throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
84476                                    "invalid attributeName"));
84477         }
84478         return ret;
84479     };
84480
84481     _processConversationChange = function (conversations, type) {
84482         var i, j, ret = [], tmp,
84483             operation = {"add": "conversationsadded",
84484                          "remove": "conversationsremoved",
84485                          "update": "conversationsupdated"};
84486
84487         for (i in _convListeners) {
84488             ret = [];
84489             if (_convListeners[i].filter !== null) {
84490                 tmp = _findConversation(conversations, _convListeners[i].filter);
84491             } else {
84492                 tmp = conversations;
84493             }
84494             if (tmp.length !== 0) {
84495                 for (j = 0; j < tmp.length; j++) {
84496                     ret.push(new Conversation(tmp[j]));
84497                 }
84498                 _convListeners[i].callback[operation[type]](ret);
84499             }
84500         }
84501     };
84502
84503     message_storage = {
84504         addDraftMessage: function (_msg, onSuccess, onError) {
84505             var m, msg = {}, opt = {};
84506
84507             if (_security_check.write === false) {
84508                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84509             }
84510             if (msg_utils.setMsg(_msg, msg) === false) {
84511                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
84512             }
84513             if (onSuccess && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
84514                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84515             }
84516             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
84517                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84518             }
84519             opt.id = Math.uuid(8, 16);
84520             opt.serviceId = _messages.id;
84521             if ((msg.inResponseTo !== null) &&
84522                 (_messages.msg[msg.inResponseTo] !== undefined)) {
84523                 opt.conversationId = _messages.msg[msg.inResponseTo].conversationId;
84524             } else {
84525                 opt.conversationId = opt.id;
84526             }
84527             opt.folderId = "DRAFTS";
84528             opt.type = _messages.type;
84529             opt.timestamp = new Date();
84530             opt.from = TIZEN_DEFAULT_MSG_FROM[_messages.type];
84531             if (msg.attachments.length === 0) {
84532                 opt.hasAttachment = false;
84533             } else {
84534                 opt.hasAttachment = true;
84535             }
84536             opt.messageStatus = "DRAFT";
84537
84538             m = new PrivMessage(msg, opt);
84539             _messages.msg[m.priv.id] = m;  // local
84540             msg_utils.saveMsg(_messages.msg[m.priv.id]);  // remote
84541             // trigger message add
84542             _processMessageChange([m], "add");
84543             if (onSuccess) {
84544                 setTimeout(function () {
84545                     onSuccess(new Message(m.priv.type, m));
84546                 }, 1);
84547             }
84548         },
84549
84550         removeMessages: function (messages, onSuccess, onError) {
84551             var i, c, na_msg = "", msgToDel = [], convToDel = {}, delConv = [], updateConv = [];
84552
84553             if (_security_check.write === false) {
84554                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84555             }
84556             if (tizen1_utils.isValidArray(messages) === false) {
84557                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
84558             }
84559             if (messages.length === 0) {
84560                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR));
84561             }
84562             if (onSuccess && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
84563                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84564             }
84565             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
84566                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84567             }
84568
84569             _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
84570             for (i = 0; i < messages.length; i++) {
84571                 if (_messages.msg[messages[i].id] === undefined) {
84572                     na_msg += messages[i].id + ", ";
84573                 } else {
84574                     msgToDel.push(utils.copy(_messages.msg[messages[i].id]));
84575                 }
84576                 if (_messages.conv[messages[i].conversationId] !== undefined) {
84577                     convToDel[messages[i].conversationId] = _messages.conv[messages[i].conversationId];
84578                 }
84579             }
84580             if (na_msg === "") {
84581                 for (i = 0; i < messages.length; i++) {
84582                     // conversation updated at remote when msg is deleted
84583                     msg_utils.delMsg(_messages.msg[messages[i].id]); // remote
84584                     delete _messages.msg[messages[i].id]; // local
84585                 }
84586                 // update conversation
84587                 _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
84588                 for (c in convToDel) {
84589                     if (_messages.conv[c] === undefined) {
84590                         delConv.push(convToDel[c]);
84591                     } else {
84592                         updateConv.push(convToDel[c]);
84593                     }
84594                 }
84595                 if (onSuccess) {
84596                     setTimeout(function () {
84597                         onSuccess();
84598                     }, 1);
84599                 }
84600                 // trigger messages remove
84601                 _processMessageChange(msgToDel, "remove");
84602                 if (delConv.length > 0) {
84603                     _processConversationChange(delConv, "remove");
84604                 }
84605                 if (updateConv.length > 0) {
84606                     _processConversationChange(updateConv, "update");
84607                 }
84608             } else {
84609                 if (onError) {
84610                     setTimeout(function () {
84611                         onError(new WebAPIError(errorcode.NOT_FOUND_ERR,
84612                                 na_msg + "not found !!"));
84613                     }, 1);
84614                 }
84615             }
84616         },
84617
84618         updateMessages: function (messages, onSuccess, onError) {
84619             var i, m, updateConv = {}, updateMsg = [], tmp,
84620                 na_msg = "", invalid_msg = "";
84621
84622             if (_security_check.write === false) {
84623                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84624             }
84625             if (onSuccess && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
84626                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84627             }
84628             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
84629                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84630             }
84631             if (tizen1_utils.isValidArray(messages) === false) {
84632                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
84633             }
84634             if (messages.length === 0) {
84635                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR));
84636             }
84637             // update conversation
84638             _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
84639             for (i = 0; i < messages.length; i++) {
84640                 m = _messages.msg[messages[i].id];
84641                 if (m === undefined) {
84642                     // msg not found
84643                     na_msg += messages[i].id + ", ";
84644                 } else {
84645                     if (m.priv.messageStatus === "DRAFT") {
84646                         tmp = {};
84647                         // allow update all writeable attr in draft
84648                         if (msg_utils.setMsg(messages[i], tmp) === false) {
84649                             invalid_msg += messages[i].id + ", ";
84650                         }
84651                     }
84652                 }
84653             }
84654             if (invalid_msg !== "") {
84655                 if (onError) {
84656                     setTimeout(function () {
84657                         onError(new WebAPIError(errorcode.INVALID_VALUES_ERR,
84658                                 invalid_msg + "invalid values"));
84659                     }, 1);
84660                 }
84661                 return;
84662             }
84663             if (na_msg !== "") {
84664                 if (onError) {
84665                     setTimeout(function () {
84666                         onError(new WebAPIError(errorcode.NOT_FOUND_ERR,
84667                                 na_msg + "not found !!"));
84668                     }, 1);
84669                 }
84670                 return;
84671             }
84672
84673             for (i = 0; i < messages.length; i++) {
84674                 m = _messages.msg[messages[i].id];
84675                 if (m.priv.messageStatus === "DRAFT") {
84676                     msg_utils.setMsg(messages[i], m);
84677                     updateMsg.push(m);
84678                 } else {
84679                     // only allow update isRead in other folders
84680                     if (typeof messages[i].isRead === 'boolean') {
84681                         m.isRead = messages[i].isRead;
84682                         updateMsg.push(m);
84683                         updateConv[m.priv.conversationId] = _messages.conv[m.priv.conversationId];
84684                     }
84685                 }
84686                 msg_utils.saveMsg(m);
84687             }
84688             if (onSuccess) {
84689                 setTimeout(function () {
84690                     onSuccess();
84691                 }, 1);
84692             }
84693
84694             // trigger Message update
84695             _processMessageChange(updateMsg, "update");
84696
84697             _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
84698             // trigger conversation update
84699             _processConversationChange(updateConv, "update");
84700         },
84701
84702         findMessages: function (filter, onSuccess, onError, sort, _limit, _offset) {
84703             var i, tmp, offset, limit, ret = [];
84704
84705             if (_security_check.read === false) {
84706                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84707             }
84708             if (!(new TypeCoerce(t.MessageArraySuccessCallback)).match(onSuccess)) {
84709                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84710             }
84711             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
84712                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84713             }
84714             if (sort && !(new TypeCoerce(t.SortMode)).match(sort)) {
84715                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84716             }
84717             if (_limit && !(new TypeCoerce(t.long)).match(_limit)) {
84718                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84719             }
84720             if (_offset && !(new TypeCoerce(t.long)).match(_offset)) {
84721                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84722             }
84723             tmp = _findMessage(_messages.msg, filter);
84724
84725             if (_offset) {
84726                 offset = _offset;
84727             } else {
84728                 offset = 0;
84729             }
84730             if (_limit) {
84731                 limit = Math.min(_limit + offset, tmp.length);
84732             } else {
84733                 limit = tmp.length;
84734             }
84735             for (i = offset; i < limit; i++) {
84736                 ret.push(new Message(tmp[i].priv.type, tmp[i]));
84737             }
84738             setTimeout(function () {
84739                 onSuccess(ret);
84740             }, 1);
84741         },
84742
84743         findConversations: function (filter, onSuccess, onError, sort, _limit, _offset) {
84744             var i, tmp, offset, limit, ret = [];
84745
84746             if (_security_check.read === false) {
84747                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84748             }
84749             if (!(new TypeCoerce(t.MessageConversationArraySuccessCallback)).match(onSuccess)) {
84750                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84751             }
84752             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
84753                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84754             }
84755             if (sort && !(new TypeCoerce(t.SortMode)).match(sort)) {
84756                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84757             }
84758             if (_limit && !(new TypeCoerce(t.long)).match(_limit)) {
84759                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84760             }
84761             if (_offset && !(new TypeCoerce(t.long)).match(_offset)) {
84762                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84763             }
84764             // download conversation
84765             _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
84766
84767             tmp = _findConversation(_messages.conv, filter);
84768
84769             if (_offset) {
84770                 offset = _offset;
84771             } else {
84772                 offset = 0;
84773             }
84774             if (_limit) {
84775                 limit = Math.min(_limit + offset, tmp.length);
84776             } else {
84777                 limit = tmp.length;
84778             }
84779             for (i = offset; i < limit; i++) {
84780                 ret.push(new Conversation(tmp[i]));
84781             }
84782             setTimeout(function () {
84783                 onSuccess(ret);
84784             }, 1);
84785         },
84786
84787         removeConversations: function (conversations, onSuccess, onError) {
84788             var i, m, na_msg = "", retConv = [], removeMsg = [];
84789
84790             if (_security_check.write === false) {
84791                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84792             }
84793             if (onSuccess && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
84794                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84795             }
84796             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
84797                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84798             }
84799             // download conversation
84800             _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
84801
84802             if (tizen1_utils.isValidArray(conversations) === false) {
84803                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
84804             }
84805             if (conversations.length === 0) {
84806                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR));
84807             }
84808             if ((onSuccess && typeof onSuccess !== "function") ||
84809                 (onError && typeof onError !== "function")) {
84810                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84811             }
84812
84813             for (i = 0; i < conversations.length; i++) {
84814                 if (_messages.conv[conversations[i].id] === undefined) {
84815                     na_msg += conversations[i].id + ", ";
84816                 } else {
84817                     retConv.push(_messages.conv[conversations[i].id]);
84818                     for (m in _messages.msg) {
84819                         if (_messages.msg[m].priv.conversationId === conversations[i].id) {
84820                             removeMsg.push(_messages.msg[m]);
84821                         }
84822                     }
84823                 }
84824             }
84825             if (na_msg === "") {
84826                 for (i = 0; i < removeMsg.length; i++) {
84827                     // conversation updated at remote
84828                     msg_utils.delMsg(removeMsg[i]);  // remote
84829                     delete _messages.msg[removeMsg[i].priv.id]; // local
84830                 }
84831                 // trigger msg(retMsg)/conv(retConv) delete update
84832                 _processMessageChange(removeMsg, "remove");
84833                 _processConversationChange(retConv, "remove");
84834                 if (onSuccess) {
84835                     setTimeout(function () {
84836                         onSuccess();
84837                     }, 1);
84838                 }
84839             } else {
84840                 if (onError) {
84841                     setTimeout(function () {
84842                         onError(new WebAPIError(errorcode.NOT_FOUND_ERR,
84843                                 na_msg + "not found !!"));
84844                     }, 1);
84845                 }
84846             }
84847         },
84848
84849         findFolders: function (filter, onSuccess, onError) {
84850             var ret = [], tmp, i;
84851
84852             if (_security_check.read === false) {
84853                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84854             }
84855             if (!(new TypeCoerce(t.MessageFolderArraySuccessCallback)).match(onSuccess)) {
84856                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84857             }
84858             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
84859                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84860             }
84861             switch (filter.attributeName) {
84862             case "id":
84863             case "serviceId":
84864             case "contentType":
84865             case "name":
84866             case "path":
84867             case "type":
84868                 tmp = tizen1_utils.matchAttributeFilter(_folders,
84869                           filter.attributeName, filter.matchFlag,
84870                           filter.matchValue);
84871                 break;
84872             case "synchronizable":
84873                 if (filter.matchFlag !== "EXACTLY" ||
84874                     typeof filter.matchValue !== "boolean") {
84875                     throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
84876                                   "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
84877                 }
84878                 tmp = tizen1_utils.matchAttributeBooleanFilter(_folders,
84879                           filter.attributeName, filter.matchValue);
84880                 break;
84881             case "parentId":
84882                 if (filter.matchValue === null) {
84883                     tmp = utils.filter(_folders, function (o) { return o.parentId === null; });
84884                 } else {
84885                     tmp = tizen1_utils.matchAttributeFilter(_folders,
84886                               filter.attributeName, filter.matchValue);
84887                 }
84888                 break;
84889             default:
84890                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
84891                                        "invalid attributeName"));
84892             }
84893             for (i = 0; i < tmp.length; i++) {
84894                 ret.push(new MessageFolder(tmp[i]));
84895             }
84896             setTimeout(function () {
84897                 onSuccess(ret);
84898             }, 1);
84899         },
84900
84901         addMessagesChangeListener: function (msgCallback, filter) {
84902             var watchId, msgListener = {};
84903
84904             if (_security_check.read === false) {
84905                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84906             }
84907             if (!(new TypeCoerce(t.MessagesChangeCallback)).match(msgCallback)) {
84908                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84909             }
84910             if (filter && !(new TypeCoerce(t.AbstractFilter)).match(filter)) {
84911                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84912             }
84913
84914             watchId = Number(Math.uuid(8, 10));
84915             msgListener.callback = msgCallback;
84916             msgListener.filter = filter || null;
84917             _msgListeners[watchId] = msgListener;
84918             return watchId;
84919         },
84920
84921         addConversationsChangeListener: function (convCallback, filter) {
84922             var watchId, convListener = {};
84923
84924             if (_security_check.read === false) {
84925                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84926             }
84927             if (!(new TypeCoerce(t.MessageConversationsChangeCallback)).match(convCallback)) {
84928                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84929             }
84930             if (filter && !(new TypeCoerce(t.AbstractFilter)).match(filter)) {
84931                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84932             }
84933
84934             watchId = Number(Math.uuid(8, 10));
84935             convListener.callback = convCallback;
84936             convListener.filter = filter || null;
84937             _convListeners[watchId] = convListener;
84938             return watchId;
84939         },
84940
84941         addFoldersChangeListener: function (callback, filter) {
84942             var watchId, folderListener = {};
84943
84944             if (_security_check.read === false) {
84945                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84946             }
84947             if (!(new TypeCoerce(t.MessageFoldersChangeCallback)).match(callback)) {
84948                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84949             }
84950             if (filter && !(new TypeCoerce(t.AbstractFilter)).match(filter)) {
84951                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84952             }
84953
84954             watchId = Number(Math.uuid(8, 10));
84955             folderListener.callback = callback;
84956             folderListener.filter = filter || null;
84957             _folderListeners[watchId] = folderListener;
84958             return watchId;
84959         },
84960
84961         removeChangeListener: function (watchid) {
84962             if (_security_check.read === false) {
84963                 throw (new WebAPIException(errorcode.SECURITY_ERR));
84964             }
84965             if (_msgListeners[watchid] !== undefined) {
84966                 delete _msgListeners[watchid];
84967                 return;
84968             }
84969             if (_convListeners[watchid] !== undefined) {
84970                 delete _convListeners[watchid];
84971                 return;
84972             }
84973             if (_folderListeners[watchid] !== undefined) {
84974                 delete _folderListeners[watchid];
84975                 return;
84976             }
84977         }
84978
84979     };
84980     return message_storage;
84981 };
84982
84983 module.exports = _self;
84984
84985 });
84986 define('ripple/platform/tizen/2.0/MessagingService', function (require, exports, module) {
84987 /*
84988  *  Copyright 2012 Intel Corporation.
84989  *
84990  * Licensed under the Apache License, Version 2.0 (the "License");
84991  * you may not use this file except in compliance with the License.
84992  * You may obtain a copy of the License at
84993  *
84994  * http://www.apache.org/licenses/LICENSE-2.0
84995  *
84996  * Unless required by applicable law or agreed to in writing, software
84997  * distributed under the License is distributed on an "AS IS" BASIS,
84998  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84999  * See the License for the specific language governing permissions and
85000  * limitations under the License.
85001  */
85002
85003 var event = require('ripple/event'),
85004     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
85005     deviceSettings = require('ripple/deviceSettings'),
85006     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
85007     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
85008     PrivMessage = require('ripple/platform/tizen/2.0/PrivMessage'),
85009     MessageStorage = require('ripple/platform/tizen/2.0/MessageStorage'),
85010     msg_utils = require('ripple/platform/tizen/2.0/msg_utils'),
85011     t = require('ripple/platform/tizen/2.0/typedef'),
85012     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
85013     _self,
85014     TIZEN_DEFAULT_MSG_FROM = {"messaging.sms": "13572468",
85015                               "messaging.mms": "13572468",
85016                               "messaging.email": "tizen.simulator@tizen.org"},
85017     INCOMING_TYPE = {"messaging.sms": "sms",
85018                      "messaging.mms": "mms",
85019                      "messaging.email": "email"};
85020
85021 _self = function (id, type, security_check) {
85022     var msg_service = {},
85023         pendingOperations = {},
85024         _msgSending = {},
85025         _receivedEmails = [],
85026         _id = id,
85027         _type = type,
85028         _security_check = security_check,
85029         _from = TIZEN_DEFAULT_MSG_FROM[_type],
85030         _incomingType = INCOMING_TYPE[_type],
85031         _messages = msg_utils.loadMsg(_type, _id),
85032         _messageStorage = new MessageStorage(_messages, _security_check);
85033
85034     event.on("MessageSent", function (rst) {
85035         var i, rsp_ok = [], rsp_fail = [];
85036         // rst.msg is the real msg in module
85037         if (rst.msg.priv.type !== _type ||
85038             rst.msg.priv.serviceId !== _id) {
85039             // not my msg
85040             return;
85041         }
85042         if (_msgSending[rst.id] !== undefined) {
85043             for (i in rst) {
85044                 if ((i !== "id") && (i !== "msg")) {
85045                     if (rst[i] === true) {
85046                         rsp_ok.push(i);
85047                     } else {
85048                         rsp_fail.push(i);
85049                     }
85050                 }
85051             }
85052             rst.msg.priv.folderId = "SENTBOX";
85053             if (rsp_fail.length === 0) {
85054                 rst.msg.priv.messageStatus = "SENT";
85055                 _msgSending[rst.id].onsuccess(rsp_ok);
85056             } else {
85057                 rst.msg.priv.messageStatus = "FAILED";
85058                 _msgSending[rst.id].onerror(rsp_fail);
85059             }
85060             msg_utils.saveMsg(rst.msg);  // sync to remote
85061             event.trigger("MsgSentRst", [rst.msg]);
85062             delete _msgSending[rst.id];
85063         }
85064     });
85065
85066     event.on("MessageReceived", function (rst) {
85067         var m, opt = {}, msgInit = {}, msg = {};
85068
85069         if (rst.type !== _incomingType) {
85070             // not my msg
85071             return;
85072         }
85073         msgInit.plainBody = rst.body;
85074         msgInit.to = [_from];
85075         // TODO: handle attachment
85076         if (msg_utils.setMsg(msgInit, msg) === false) {
85077             throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR, "received message error"));
85078         }
85079         opt.id = Math.uuid(8, 16);
85080         opt.serviceId = _id;
85081         opt.conversationId = opt.id;
85082         opt.folderId = "INBOX";
85083         opt.type = _type;
85084         opt.timestamp = new Date();
85085         opt.from = rst.from;
85086         if (msg.attachments.length === 0) {
85087             opt.hasAttachment = false;
85088         } else {
85089             opt.hasAttachment = true;
85090         }
85091         opt.messageStatus = "RECEIVED";
85092         m = new PrivMessage(msg, opt);
85093         msg_utils.saveMsg(m);   // save in server
85094         if (_type !== "messaging.email") {
85095             _messages.msg[m.priv.id] = m;  // sync to local
85096             event.trigger("MsgRecv", [m]);
85097         } else {
85098             _receivedEmails.push(m);  // don't sync to local yet
85099         }
85100     });
85101
85102     msg_service = {
85103         sendMessage: function (_msg, onSuccess, onError) {
85104             var m, msg = {}, opt = {}, shortMsg = {}, rst = {};
85105             if (_security_check.write === false) {
85106                 throw (new WebAPIException(errorcode.SECURITY_ERR));
85107             }
85108             if (_msg === null || _msg === undefined || _msg.id === undefined) {
85109                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
85110             }
85111
85112             if (msg_utils.setMsg(_msg, msg) === false) {
85113                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
85114             }
85115             if ((arguments.length > 1) && onSuccess !== null && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
85116                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85117             }
85118             if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
85119                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85120             }
85121             if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === false &&
85122                 (_incomingType === 'sms' || _incomingType === 'mms')) {
85123                 if (onError) {
85124                     setTimeout(function () {
85125                         onError(new WebAPIError(errorcode.NETWORK_ERR));
85126                     }, 1);
85127                 }
85128                 return;
85129             }
85130             if (deviceSettings.retrieve("WIFI_NETWORK.status") === false &&
85131                 _incomingType === 'email') {
85132                 if (onError) {
85133                     setTimeout(function () {
85134                         onError(new WebAPIError(errorcode.NETWORK_ERR));
85135                     }, 1);
85136                 }
85137                 return;
85138             }
85139             if (typeof _msg.id === 'string') {
85140                 if (_messages.msg[_msg.id] === undefined) {
85141                     if (onError) {
85142                         setTimeout(function () {
85143                             onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
85144                         }, 1);
85145                     }
85146                     return;
85147                 }
85148                 if (_messages.msg[_msg.id].priv.messageStatus === "DRAFT") {
85149                     msg_utils.delMsg(_messages.msg[_msg.id]);
85150                     delete _messages.msg[_msg.id];
85151                 } else {
85152                     // if msg found in storage, it can only be a draft.
85153                     if (onError) {
85154                         setTimeout(function () {
85155                             onError(new WebAPIError(errorcode.UNKNOWN_ERR));
85156                         }, 1);
85157                     }
85158                     return;
85159                 }
85160             }
85161             opt.id = Math.uuid(8, 16);
85162             opt.serviceId = _id;
85163             if ((msg.inResponseTo !== null) &&
85164                 (_messages.msg[msg.inResponseTo] !== undefined) &&
85165                 (_messages.msg[msg.inResponseTo].priv.messageStatus !== "DRAFT")) {
85166                 opt.conversationId = _messages.msg[msg.inResponseTo].priv.conversationId;
85167             } else {
85168                 opt.conversationId = opt.id;
85169             }
85170             opt.folderId = "OUTBOX";
85171             opt.type = _type;
85172             opt.timestamp = new Date();
85173             opt.from = _from;
85174             if (msg.attachments.length === 0) {
85175                 opt.hasAttachment = false;
85176             } else {
85177                 opt.hasAttachment = true;
85178             }
85179             opt.messageStatus = "SENDING";
85180
85181             m = new PrivMessage(msg, opt);
85182             _messages.msg[m.priv.id] = m;
85183             msg_utils.saveMsg(m);  // sync to remote
85184             shortMsg.msg = m;   // pass by ref
85185             shortMsg.id = m.priv.id;
85186             shortMsg.body = m.body.plainBody;
85187             shortMsg.to = m.to.slice(0);
85188             shortMsg.cc = m.cc.slice(0);
85189             shortMsg.bcc = m.bcc.slice(0);
85190             event.trigger("OutsideMessageReceived", [shortMsg]);
85191             rst.onsuccess = onSuccess;
85192             rst.onerror = onError;
85193             _msgSending[m.priv.id] = rst;
85194         },
85195
85196         loadMessageBody: function (msg, onSuccess, onError) {
85197             var pendingID;
85198             if (_security_check.write === false) {
85199                 throw (new WebAPIException(errorcode.SECURITY_ERR));
85200             }
85201             if (_messages.msg[msg.id] === undefined) {
85202                 throw (new WebAPIException(errorcode.NOT_FOUND_ERR));
85203             }
85204             if (!(new TypeCoerce(t.MessageBodySuccessCallback)).match(onSuccess)) {
85205                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85206             }
85207             if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
85208                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85209             }
85210             pendingID = setTimeout(function () {
85211                 if (pendingOperations.hasOwnProperty(pendingID) === false) {
85212                     // has been cancelled/expired
85213                     return;
85214                 }
85215                 delete pendingOperations[pendingID];
85216                 onSuccess(_messages.msg[msg.id].body);
85217             }, 1);
85218             pendingOperations[pendingID] = onError;
85219             return pendingID;
85220         },
85221         loadMessageAttachment: function (msg, onSuccess, onError) {
85222             var pendingID;
85223
85224             if (_security_check.write === false) {
85225                 throw (new WebAPIException(errorcode.SECURITY_ERR));
85226             }
85227             if (_messages.msg[msg.id] === undefined) {
85228                 throw (new WebAPIException(errorcode.NOT_FOUND_ERR));
85229             }
85230             if (!(new TypeCoerce(t.MessageAttachmentSuccessCallback)).match(onSuccess)) {
85231                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85232             }
85233             if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
85234                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85235             }
85236             pendingID = setTimeout(function () {
85237                 if (pendingOperations.hasOwnProperty(pendingID) === false) {
85238                     // has been cancelled/expired
85239                     return;
85240                 }
85241                 delete pendingOperations[pendingID];
85242                 onSuccess(_messages.msg[msg.id].attachments);
85243             }, 1);
85244             pendingOperations[pendingID] = onError;
85245             return pendingID;
85246         },
85247         sync: function (successCallback, errorCallback, limit) {
85248             var i, m, pendingID;
85249
85250             if (_security_check.write === false) {
85251                 throw (new WebAPIException(errorcode.SECURITY_ERR));
85252             }
85253             if ((arguments.length > 0) && successCallback !== null && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) {
85254                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85255             }
85256             if ((arguments.length > 1) && errorCallback !== null && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) {
85257                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85258             }
85259             if ((arguments.length > 2) && limit !== null && !(new TypeCoerce(t.long)).match(limit)) {
85260                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85261             }
85262             pendingID = setTimeout(function () {
85263                 if (pendingOperations.hasOwnProperty(pendingID) === false) {
85264                     // has been cancelled/expired
85265                     return;
85266                 }
85267                 delete pendingOperations[pendingID];
85268                 for (i = 0; i < _receivedEmails.length; i++) {
85269                     m = _receivedEmails[i];
85270                     _messages.msg[m.priv.id] = m;  // sync to local
85271                     event.trigger("MsgRecv", [m]);
85272                 }
85273                 _receivedEmails = [];
85274                 if (successCallback) {
85275                     successCallback();
85276                 }
85277             }, 1);
85278             pendingOperations[pendingID] = errorCallback;
85279             return pendingID;
85280         },
85281
85282         syncFolder: function (folder, onSuccess, onError, limit) {
85283             var i, m, pendingID;
85284
85285             if (_security_check.write === false) {
85286                 throw (new WebAPIException(errorcode.SECURITY_ERR));
85287             }
85288             if (!(new TypeCoerce(t.MessageFolder)).match(folder)) {
85289                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85290             }
85291             if ((arguments.length > 1) && onSuccess !== null && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
85292                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85293             }
85294             if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
85295                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85296             }
85297             if ((arguments.length > 3) && limit !== null && !(new TypeCoerce(t.long)).match(limit)) {
85298                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85299             }
85300             pendingID = setTimeout(function () {
85301                 if (pendingOperations.hasOwnProperty(pendingID) === false) {
85302                     // has been cancelled/expired
85303                     return;
85304                 }
85305                 delete pendingOperations[pendingID];
85306                 if (folder.id === "INBOX") {
85307                     for (i = 0; i < _receivedEmails.length; i++) {
85308                         m = _receivedEmails[i];
85309                         _messages.msg[m.priv.id] = m;  // sync to local
85310                         event.trigger("MsgRecv", [m]);
85311                     }
85312                     _receivedEmails = [];
85313                 }
85314                 onSuccess();
85315             }, 1);
85316             pendingOperations[pendingID] = onError;
85317             return pendingID;
85318         },
85319
85320         stopSync: function (pendingID) {
85321             if (!(new TypeCoerce(t.long)).match(pendingID)) {
85322                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
85323             }
85324             if (pendingOperations[pendingID] !== undefined) {
85325                 clearTimeout(pendingID);
85326                 pendingOperations[pendingID](new WebAPIError(errorcode.ABORT_ERR));
85327             }
85328             delete pendingOperations[pendingID];
85329         }
85330     };
85331     msg_service.__defineGetter__("type", function () {
85332         return _type;
85333     });
85334     msg_service.__defineGetter__("messageStorage", function () {
85335         return _messageStorage;
85336     });
85337     return msg_service;
85338 };
85339
85340 module.exports = _self;
85341
85342 });
85343 define('ripple/platform/tizen/2.0/NDEFMessage', function (require, exports, module) {
85344 /*
85345  *  Copyright 2013 Intel Corporation
85346  *
85347  * Licensed under the Apache License, Version 2.0 (the "License");
85348  * you may not use this file except in compliance with the License.
85349  * You may obtain a copy of the License at
85350  *
85351  * http://www.apache.org/licenses/LICENSE-2.0
85352  *
85353  * Unless required by applicable law or agreed to in writing, software
85354  * distributed under the License is distributed on an "AS IS" BASIS,
85355  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85356  * See the License for the specific language governing permissions and
85357  * limitations under the License.
85358  */
85359
85360 var t = require('ripple/platform/tizen/2.0/typecast'),
85361     NDEFRecord = require('ripple/platform/tizen/2.0/NDEFRecord'),
85362     NDEFRecordText = require('ripple/platform/tizen/2.0/NDEFRecordText'),
85363     NDEFRecordURI = require('ripple/platform/tizen/2.0/NDEFRecordURI'),
85364     NDEFRecordMedia = require('ripple/platform/tizen/2.0/NDEFRecordMedia'),
85365     NDEFRecordFactory,
85366     NDEFMessage;
85367
85368 NDEFRecordFactory = function (ndefRecord) {
85369     var record;
85370
85371     if (ndefRecord instanceof NDEFRecordText) {
85372         record = new NDEFRecordText(ndefRecord.text, ndefRecord.languageCode,
85373                 ndefRecord.encoding || null);
85374     } else if (ndefRecord instanceof NDEFRecordURI) {
85375         record = new NDEFRecordURI(ndefRecord.url);
85376     } else if (ndefRecord instanceof NDEFRecordMedia) {
85377         record = new NDEFRecordMedia(ndefRecord.mimeType, ndefRecord.payload);
85378     } else {
85379         record = new NDEFRecord(ndefRecord.tnf, ndefRecord.type,
85380                 ndefRecord.payload, ndefRecord.id || null);
85381     }
85382
85383     return record;
85384 };
85385
85386 NDEFMessage = function () {
85387     var voc, records = [];
85388
85389     // private
85390     function construct() {
85391         this.__defineGetter__("recordCount", function () {
85392             return this.records.length;
85393         });
85394
85395         this.__defineGetter__("records", function () {
85396             return records;
85397         });
85398
85399         this.__defineSetter__("records", function (val) {
85400             try {
85401                 t.NDEFRecord(val, "[]");
85402                 records = val;
85403             } catch (e) {
85404             }
85405         });
85406
85407         this.toByte = function () {
85408             var result = [], i, j, space = " ".charCodeAt(0);
85409
85410             for (i in this.records) {
85411                 for (j = 0; j < this.records[i].payload.length; j++) {
85412                     result.push(this.records[i].payload.charCodeAt(j));
85413                 }
85414                 if (i < this.records.length - 1) {
85415                     result.push(space);
85416                 }
85417             }
85418
85419             return result;
85420         };
85421     }
85422
85423     // constructor
85424     function NDEFMessage_NDEFRecords(ndefRecords) {
85425         var i;
85426
85427         construct.apply(this);
85428
85429         for (i = 0; i < ndefRecords.length; i++) {
85430             records[i] = new NDEFRecordFactory(ndefRecords[i]);
85431         }
85432     }
85433
85434     function NDEFMessage_bytes(rawData) {
85435         //TODO: NDEFMessage doesn't support rawData constructor
85436         construct.apply(this);
85437     }
85438
85439     function NDEFMessage_void() {
85440         construct.apply(this);
85441     }
85442
85443     voc = [NDEFMessage_NDEFRecords, NDEFMessage_bytes, NDEFMessage_void];
85444     t.NDEFMessage(arguments, this, voc);
85445 };
85446
85447 module.exports = NDEFMessage;
85448
85449 });
85450 define('ripple/platform/tizen/2.0/NDEFRecord', function (require, exports, module) {
85451 /*
85452  *  Copyright 2013 Intel Corporation
85453  *
85454  * Licensed under the Apache License, Version 2.0 (the "License");
85455  * you may not use this file except in compliance with the License.
85456  * You may obtain a copy of the License at
85457  *
85458  * http://www.apache.org/licenses/LICENSE-2.0
85459  *
85460  * Unless required by applicable law or agreed to in writing, software
85461  * distributed under the License is distributed on an "AS IS" BASIS,
85462  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85463  * See the License for the specific language governing permissions and
85464  * limitations under the License.
85465  */
85466
85467 var t = require('ripple/platform/tizen/2.0/typecast'),
85468     NDEFRecordInternal = require('ripple/platform/tizen/2.0/NDEFRecordInternal'),
85469     NDEFRecord;
85470
85471 NDEFRecord = function () {
85472     var voc = [
85473         function (tnf, type, payload, id) {
85474             NDEFRecordInternal.call(this, tnf, type, payload, id || []);
85475         },
85476         function (raw_data) {
85477             NDEFRecordInternal.call(this, 0, [], [], []);
85478         }
85479     ];
85480
85481     t.NDEFRecord(arguments, this, voc);
85482 };
85483
85484 module.exports = NDEFRecord;
85485
85486 });
85487 define('ripple/platform/tizen/2.0/NDEFRecordInternal', function (require, exports, module) {
85488 /*
85489  *  Copyright 2013 Intel Corporation
85490  *
85491  * Licensed under the Apache License, Version 2.0 (the "License");
85492  * you may not use this file except in compliance with the License.
85493  * You may obtain a copy of the License at
85494  *
85495  * http://www.apache.org/licenses/LICENSE-2.0
85496  *
85497  * Unless required by applicable law or agreed to in writing, software
85498  * distributed under the License is distributed on an "AS IS" BASIS,
85499  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85500  * See the License for the specific language governing permissions and
85501  * limitations under the License.
85502  */
85503
85504 module.exports = function (tnf, type, payload, id) {
85505     this.__defineGetter__("tnf", function () {
85506         return tnf;
85507     });
85508
85509     this.__defineGetter__("type", function () {
85510         return type;
85511     });
85512
85513     this.__defineGetter__("id", function () {
85514         return id;
85515     });
85516
85517     this.__defineGetter__("payload", function () {
85518         return payload;
85519     });
85520 };
85521
85522 });
85523 define('ripple/platform/tizen/2.0/NDEFRecordMedia', function (require, exports, module) {
85524 /*
85525  *  Copyright 2013 Intel Corporation
85526  *
85527  * Licensed under the Apache License, Version 2.0 (the "License");
85528  * you may not use this file except in compliance with the License.
85529  * You may obtain a copy of the License at
85530  *
85531  * http://www.apache.org/licenses/LICENSE-2.0
85532  *
85533  * Unless required by applicable law or agreed to in writing, software
85534  * distributed under the License is distributed on an "AS IS" BASIS,
85535  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85536  * See the License for the specific language governing permissions and
85537  * limitations under the License.
85538  */
85539
85540 var t = require('ripple/platform/tizen/2.0/typecast'),
85541     NDEFRecordInternal = require('ripple/platform/tizen/2.0/NDEFRecordInternal'),
85542     NDEFRecordMedia;
85543
85544 NDEFRecordMedia = function (mimeType, data) {
85545     var i, type = [], payload;
85546
85547     t.NDEFRecordMedia(arguments, this);
85548
85549     for (i = 0; i < mimeType.length; i++) {
85550         type[i] = mimeType.charCodeAt(i);
85551     }
85552     payload = t.byte(data, "[]");
85553
85554     // Normally, we can use prototype to inherit a class, for example:
85555     //     NDEFRecordMedia.prototype = new NDEFRecord(2, [...], [...], [...]);
85556     // But the test case thinks that all the inherited property should be
85557     // the object's own property. So, we can only change the "this" point
85558     // of NDEFRecord constructor here.
85559     NDEFRecordInternal.call(this, tizen.nfc.NFC_RECORD_TNF_MIME_MEDIA, type,
85560             payload, []);
85561
85562     this.__defineGetter__("mimeType", function () {
85563         return mimeType;
85564     });
85565 };
85566
85567 module.exports = NDEFRecordMedia;
85568
85569 });
85570 define('ripple/platform/tizen/2.0/NDEFRecordText', function (require, exports, module) {
85571 /*
85572  *  Copyright 2013 Intel Corporation
85573  *
85574  * Licensed under the Apache License, Version 2.0 (the "License");
85575  * you may not use this file except in compliance with the License.
85576  * You may obtain a copy of the License at
85577  *
85578  * http://www.apache.org/licenses/LICENSE-2.0
85579  *
85580  * Unless required by applicable law or agreed to in writing, software
85581  * distributed under the License is distributed on an "AS IS" BASIS,
85582  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85583  * See the License for the specific language governing permissions and
85584  * limitations under the License.
85585  */
85586
85587 var t = require('ripple/platform/tizen/2.0/typecast'),
85588     NDEFRecordInternal = require('ripple/platform/tizen/2.0/NDEFRecordInternal'),
85589     NDEFRecordText;
85590
85591 NDEFRecordText = function (text, languageCode, encoding) {
85592     var payload = [], i;
85593
85594     t.NDEFRecordText(arguments, this);
85595
85596     encoding = encoding || "UTF8";
85597
85598     // Store languageCode in payload
85599     payload.push(languageCode.length);
85600     for (i = 0; i < languageCode.length; i++) {
85601         payload.push(languageCode.charCodeAt(i));
85602     }
85603
85604     // Store text in payload
85605     for (i = 0; i < text.length; i++) {
85606         payload.push(text.charCodeAt(i));
85607     }
85608
85609     NDEFRecordInternal.call(this, tizen.nfc.NFC_RECORD_TNF_WELL_KNOWN,
85610             ["T".charCodeAt(0)], payload, []);
85611
85612     this.__defineGetter__("text", function () {
85613         return text;
85614     });
85615
85616     this.__defineGetter__("languageCode", function () {
85617         return languageCode;
85618     });
85619
85620     this.__defineGetter__("encoding", function () {
85621         return encoding;
85622     });
85623 };
85624
85625 module.exports = NDEFRecordText;
85626
85627 });
85628 define('ripple/platform/tizen/2.0/NDEFRecordURI', function (require, exports, module) {
85629 /*
85630  *  Copyright 2013 Intel Corporation
85631  *
85632  * Licensed under the Apache License, Version 2.0 (the "License");
85633  * you may not use this file except in compliance with the License.
85634  * You may obtain a copy of the License at
85635  *
85636  * http://www.apache.org/licenses/LICENSE-2.0
85637  *
85638  * Unless required by applicable law or agreed to in writing, software
85639  * distributed under the License is distributed on an "AS IS" BASIS,
85640  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85641  * See the License for the specific language governing permissions and
85642  * limitations under the License.
85643  */
85644
85645 var t = require('ripple/platform/tizen/2.0/typecast'),
85646     NDEFRecordInternal = require('ripple/platform/tizen/2.0/NDEFRecordInternal'),
85647     NDEFRecordURI;
85648
85649 NDEFRecordURI = function (uri) {
85650     var payload = [], i;
85651
85652     t.NDEFRecordURI(arguments, this);
85653
85654     // Store uri in payload
85655     payload.push(0);
85656     for (i = 0; i < uri.length; i++) {
85657         payload.push(uri.charCodeAt(i));
85658     }
85659
85660     NDEFRecordInternal.call(this, tizen.nfc.NFC_RECORD_TNF_WELL_KNOWN,
85661             ["U".charCodeAt(0)], payload, []);
85662
85663     this.__defineGetter__("uri", function () {
85664         return uri;
85665     });
85666 };
85667
85668 module.exports = NDEFRecordURI;
85669
85670 });
85671 define('ripple/platform/tizen/2.0/NotificationBase', function (require, exports, module) {
85672 /*
85673  *  Copyright 2013 Intel Corporation.
85674  *
85675  * Licensed under the Apache License, Version 2.0 (the "License");
85676  * you may not use this file except in compliance with the License.
85677  * You may obtain a copy of the License at
85678  *
85679  * http://www.apache.org/licenses/LICENSE-2.0
85680  *
85681  * Unless required by applicable law or agreed to in writing, software
85682  * distributed under the License is distributed on an "AS IS" BASIS,
85683  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85684  * See the License for the specific language governing permissions and
85685  * limitations under the License.
85686  */
85687
85688 var t = require('ripple/platform/tizen/2.0/typecast'),
85689     Notification;
85690
85691 Notification = function (title, content) {
85692     var notification = {};
85693
85694     notification.title = title;
85695     notification.content = content || null;
85696
85697     this.__defineGetter__("id", function () {
85698         return undefined;
85699     });
85700
85701     this.__defineGetter__("type", function () {
85702         return "STATUS";
85703     });
85704
85705     this.__defineGetter__("postedTime", function () {
85706         return undefined;
85707     });
85708
85709     this.__defineGetter__("title", function () {
85710         return notification.title;
85711     });
85712     this.__defineSetter__("title", function (val) {
85713         try {
85714             notification.title = t.DOMString(val);
85715         } catch (e) {
85716         }
85717     });
85718
85719     this.__defineGetter__("content", function () {
85720         return notification.content;
85721     });
85722     this.__defineSetter__("content", function (val) {
85723         try {
85724             notification.content = t.DOMString(val, "?");
85725         } catch (e) {
85726         }
85727     });
85728 };
85729
85730 module.exports = Notification;
85731
85732 });
85733 define('ripple/platform/tizen/2.0/NotificationDetailInfo', function (require, exports, module) {
85734 /*
85735  *  Copyright 2013 Intel Corporation.
85736  *
85737  * Licensed under the Apache License, Version 2.0 (the "License");
85738  * you may not use this file except in compliance with the License.
85739  * You may obtain a copy of the License at
85740  *
85741  * http://www.apache.org/licenses/LICENSE-2.0
85742  *
85743  * Unless required by applicable law or agreed to in writing, software
85744  * distributed under the License is distributed on an "AS IS" BASIS,
85745  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85746  * See the License for the specific language governing permissions and
85747  * limitations under the License.
85748  */
85749
85750 var t = require('ripple/platform/tizen/2.0/typecast'),
85751     NotificationDetailInfo;
85752
85753 NotificationDetailInfo = function (mainText, subText) {
85754     var notificationDetailInfo = {};
85755
85756     t.NotificationDetailInfo(arguments, this);
85757
85758     notificationDetailInfo.mainText = mainText;
85759     notificationDetailInfo.subText  = subText || null;
85760
85761     this.__defineGetter__("mainText", function () {
85762         return notificationDetailInfo.mainText;
85763     });
85764     this.__defineSetter__("mainText", function (val) {
85765         try {
85766             notificationDetailInfo.mainText = t.DOMString(val);
85767         } catch (e) {
85768         }
85769     });
85770
85771     this.__defineGetter__("subText", function () {
85772         return notificationDetailInfo.subText;
85773     });
85774     this.__defineSetter__("subText", function (val) {
85775         try {
85776             notificationDetailInfo.subText = t.DOMString(val, "?");
85777         } catch (e) {
85778         }
85779     });
85780 };
85781
85782 module.exports = NotificationDetailInfo;
85783
85784 });
85785 define('ripple/platform/tizen/2.0/POIBase', function (require, exports, module) {
85786 /*
85787  *  Copyright 2012 Intel Corporation.
85788  *
85789  * Licensed under the Apache License, Version 2.0 (the "License");
85790  * you may not use this file except in compliance with the License.
85791  * You may obtain a copy of the License at
85792  *
85793  * http://www.apache.org/licenses/LICENSE-2.0
85794  *
85795  * Unless required by applicable law or agreed to in writing, software
85796  * distributed under the License is distributed on an "AS IS" BASIS,
85797  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85798  * See the License for the specific language governing permissions and
85799  * limitations under the License.
85800  */
85801
85802 var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
85803     POIGeometry = require('ripple/platform/tizen/2.0/POIGeometry'),
85804     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
85805     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError');
85806
85807
85808 module.exports = function (prop) {
85809     var _self, i, copy, attr;
85810     _self = {
85811         name : null,
85812         categories : [],
85813         address : null,
85814         phoneNumbers : [],
85815         geometry : null,
85816         urls : [],
85817         rating : null,
85818         tags : null,
85819         toGeoJSON : function () {
85820             throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
85821         }
85822     };
85823
85824     _self.__defineGetter__("id", function () {
85825         return null;
85826     });
85827
85828     _self.__defineGetter__("providerName", function () {
85829         return null;
85830     });
85831
85832     if (prop) {
85833         if (prop.name) {
85834             _self.name = String(prop.name);
85835         }
85836         if (tizen1_utils.isValidArray(prop.categories)) {
85837             _self.categories = [];
85838             for (i in prop.categories) {
85839                 _self.categories.push(String(prop.categories[i]));
85840             }
85841         }
85842         if (prop.address) {
85843             if (typeof prop.address === "string") {
85844                 _self.address = String(prop.address);
85845             } else if (Object.prototype.toString.call(prop.address) === "[object Object]") {
85846                 copy = prop.address.constructor();
85847                 for (attr in prop.address) {
85848                     if (prop.address.hasOwnProperty(attr)) {
85849                         copy[attr] = prop.address[attr];
85850                     }
85851                 }
85852                 _self.address = copy;
85853             }
85854         }
85855         if (tizen1_utils.isValidArray(prop.phoneNumbers)) {
85856             _self.phoneNumbers = [];
85857             for (i in prop.phoneNumbers) {
85858                 _self.phoneNumbers.push(String(prop.phoneNumbers[i]));
85859             }
85860         }
85861         if (prop.geometry) {
85862             _self.geometry = new POIGeometry(prop.geometry.position, prop.geometry.viewport, prop.geometry.wkt);
85863         }
85864         if (tizen1_utils.isValidArray(prop.urls)) {
85865             _self.urls = [];
85866             for (i in prop.urls) {
85867                 _self.urls.push(String(prop.urls[i]));
85868             }
85869         }
85870         if (typeof prop.rating === "number") {
85871             _self.rating = prop.rating;
85872         }
85873         if (Object.prototype.toString.call(prop.tags) === "[object Object]") {
85874             copy = prop.tags.constructor();
85875             for (attr in prop.tags) {
85876                 if (prop.tags.hasOwnProperty(attr)) {
85877                     copy[attr] = prop.tags[attr];
85878                 }
85879             }
85880             _self.tags = copy;
85881         }
85882     }
85883
85884     return _self;
85885 };
85886
85887 });
85888 define('ripple/platform/tizen/2.0/POIFilter', function (require, exports, module) {
85889 /*
85890  *  Copyright 2012 Intel Corporation.
85891  *
85892  * Licensed under the Apache License, Version 2.0 (the "License");
85893  * you may not use this file except in compliance with the License.
85894  * You may obtain a copy of the License at
85895  *
85896  * http://www.apache.org/licenses/LICENSE-2.0
85897  *
85898  * Unless required by applicable law or agreed to in writing, software
85899  * distributed under the License is distributed on an "AS IS" BASIS,
85900  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85901  * See the License for the specific language governing permissions and
85902  * limitations under the License.
85903  */
85904
85905 module.exports = function (attributeName, value) {
85906     var _self;
85907
85908     _self = {
85909         attributeName: attributeName,
85910         value: value
85911     };
85912
85913     return _self;
85914 };
85915
85916 });
85917 define('ripple/platform/tizen/2.0/POIGeometry', function (require, exports, module) {
85918 /*
85919  *  Copyright 2012 Intel Corporation.
85920  *
85921  * Licensed under the Apache License, Version 2.0 (the "License");
85922  * you may not use this file except in compliance with the License.
85923  * You may obtain a copy of the License at
85924  *
85925  * http://www.apache.org/licenses/LICENSE-2.0
85926  *
85927  * Unless required by applicable law or agreed to in writing, software
85928  * distributed under the License is distributed on an "AS IS" BASIS,
85929  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85930  * See the License for the specific language governing permissions and
85931  * limitations under the License.
85932  */
85933
85934 var SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
85935     GeoRectBounds = require('ripple/platform/tizen/2.0/GeoRectBounds');
85936
85937 module.exports = function (position, viewport, wkt) {
85938     var _self, _position = null, _viewport = null, _wkt = "";
85939
85940     if (position) {
85941         _position = new SimpleCoordinates(position.latitude, position.longitude);
85942     }
85943
85944     if (viewport) {
85945         _viewport = new GeoRectBounds(viewport.southWest, viewport.northEast);
85946     }
85947
85948     if (wkt) {
85949         _wkt = String(wkt);
85950     }
85951
85952     _self = {
85953         position : _position,
85954         viewport: _viewport,
85955         wkt: _wkt
85956     };
85957
85958     return _self;
85959 };
85960
85961 });
85962 define('ripple/platform/tizen/2.0/PackageInformation', function (require, exports, module) {
85963 /*
85964  *  Copyright 2013 Intel Corporation.
85965  *
85966  * Licensed under the Apache License, Version 2.0 (the "License");
85967  * you may not use this file except in compliance with the License.
85968  * You may obtain a copy of the License at
85969  *
85970  * http://www.apache.org/licenses/LICENSE-2.0
85971  *
85972  * Unless required by applicable law or agreed to in writing, software
85973  * distributed under the License is distributed on an "AS IS" BASIS,
85974  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85975  * See the License for the specific language governing permissions and
85976  * limitations under the License.
85977  */
85978 module.exports = function (id, name, iconPath, version, totalSize,
85979         dataSize, lastModified, author, description, appIds) {
85980     var packageInformation = {}, _date = new Date(lastModified);
85981
85982     packageInformation.__defineGetter__("id", function () {
85983         return id;
85984     });
85985     packageInformation.__defineGetter__("name", function () {
85986         return name;
85987     });
85988     packageInformation.__defineGetter__("iconPath", function () {
85989         return iconPath;
85990     });
85991     packageInformation.__defineGetter__("version", function () {
85992         return version;
85993     });
85994     packageInformation.__defineGetter__("totalSize", function () {
85995         return totalSize;
85996     });
85997     packageInformation.__defineGetter__("dataSize", function () {
85998         return dataSize;
85999     });
86000     packageInformation.__defineGetter__("lastModified", function () {
86001         return _date;
86002     });
86003     packageInformation.__defineGetter__("author", function () {
86004         return author;
86005     });
86006     packageInformation.__defineGetter__("description", function () {
86007         return description;
86008     });
86009     packageInformation.__defineGetter__("appIds", function () {
86010         return appIds;
86011     });
86012
86013     return packageInformation;
86014 };
86015
86016 });
86017 define('ripple/platform/tizen/2.0/PrivMessage', function (require, exports, module) {
86018 /*
86019  *  Copyright 2012 Intel Corporation.
86020  *
86021  * Licensed under the Apache License, Version 2.0 (the "License"),
86022  * you may not use this file except in compliance with the License.
86023  * You may obtain a copy of the License at
86024  *
86025  * http://www.apache.org/licenses/LICENSE-2.0
86026  *
86027  * Unless required by applicable law or agreed to in writing, software
86028  * distributed under the License is distributed on an "AS IS" BASIS,
86029  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86030  * See the License for the specific language governing permissions and
86031  * limitations under the License.
86032  */
86033 var utils = require('ripple/utils');
86034
86035 module.exports = function (m, opt) {
86036     return {
86037 // readonly begin
86038         priv: {id: opt.id,
86039                serviceId: opt.serviceId,
86040                conversationId: opt.conversationId,
86041                folderId: opt.folderId,
86042                type: opt.type,
86043                timestamp: new Date(opt.timestamp),
86044                from: opt.from,
86045                hasAttachment: opt.hasAttachment,
86046                messageStatus: opt.messageStatus
86047         },
86048 // readonly end
86049         to: m.to.slice(0),
86050         cc: m.cc.slice(0),
86051         bcc: m.bcc.slice(0),
86052         body: utils.copy(m.body),
86053         isRead: m.isRead,
86054         isHighPriority: m.isHighPriority,
86055         subject: m.subject,
86056         inResponseTo: m.inResponseTo,
86057         attachments: utils.copy(m.attachments)
86058     };
86059 };
86060
86061 });
86062 define('ripple/platform/tizen/2.0/ReverseGeocodeOptions', function (require, exports, module) {
86063 /*      
86064  *  Copyright 2012 Intel Corporation.
86065  *  
86066  * Licensed under the Apache License, Version 2.0 (the "License");
86067  * you may not use this file except in compliance with the License.
86068  * You may obtain a copy of the License at
86069  *  
86070  * http://www.apache.org/licenses/LICENSE-2.0
86071  *  
86072  * Unless required by applicable law or agreed to in writing, software
86073  * distributed under the License is distributed on an "AS IS" BASIS,
86074  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86075  * See the License for the specific language governing permissions and
86076  * limitations under the License.
86077  */
86078 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
86079     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
86080     SortMode = require('ripple/platform/tizen/2.0/SortMode');
86081
86082 module.exports = function (_sortMode, _resultType, _maxResults) {
86083     var _self;
86084     if (_sortMode !== null && _sortMode !== undefined) {
86085         if (typeof _sortMode !== "object") {
86086             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
86087         }
86088         try {
86089             new SortMode(_sortMode.attributeName, _sortMode.order);
86090         } catch (e) {
86091             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
86092         }
86093     }
86094     if (_resultType !== null && _resultType !== undefined) {
86095         if (_resultType !== "FORMATTED" && _resultType !== "STRUCTURED") {
86096             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
86097         }
86098     }
86099     if (_maxResults !== null && _maxResults !== undefined) {
86100         if (typeof _maxResults !== "number") {
86101             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
86102         }
86103     }
86104     _self = {
86105         sortMode : _sortMode,
86106         resultType : _resultType || "FORMATTED",
86107         maxResults : _maxResults || 0
86108     };
86109
86110     return _self;
86111 };
86112
86113
86114 });
86115 define('ripple/platform/tizen/2.0/SimpleCoordinates', function (require, exports, module) {
86116 /*
86117  *  Copyright 2013 Intel Corporation.
86118  *
86119  * Licensed under the Apache License, Version 2.0 (the "License");
86120  * you may not use this file except in compliance with the License.
86121  * You may obtain a copy of the License at
86122  *
86123  * http://www.apache.org/licenses/LICENSE-2.0
86124  *
86125  * Unless required by applicable law or agreed to in writing, software
86126  * distributed under the License is distributed on an "AS IS" BASIS,
86127  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86128  * See the License for the specific language governing permissions and
86129  * limitations under the License.
86130  */
86131
86132 var t = require('ripple/platform/tizen/2.0/typecast'),
86133     SimpleCoordinates;
86134
86135 SimpleCoordinates = function (latitude, longitude) {
86136     var simpleCoordinates = {};
86137
86138     t.SimpleCoordinates(arguments, this);
86139
86140     this.__defineGetter__("latitude", function () {
86141         return simpleCoordinates.latitude;
86142     });
86143     this.__defineSetter__("latitude", function (val) {
86144         try {
86145             simpleCoordinates.latitude = t.double(val);
86146         } catch (e) {
86147         }
86148     });
86149
86150     this.__defineGetter__("longitude", function () {
86151         return simpleCoordinates.longitude;
86152     });
86153     this.__defineSetter__("longitude", function (val) {
86154         try {
86155             simpleCoordinates.longitude = t.double(val);
86156         } catch (e) {
86157         }
86158     });
86159
86160     simpleCoordinates.latitude  = latitude;
86161     simpleCoordinates.longitude = longitude;
86162 };
86163
86164 module.exports = SimpleCoordinates;
86165
86166 });
86167 define('ripple/platform/tizen/2.0/SortMode', function (require, exports, module) {
86168 /*
86169  *  Copyright 2013 Intel Corporation.
86170  *
86171  * Licensed under the Apache License, Version 2.0 (the "License");
86172  * you may not use this file except in compliance with the License.
86173  * You may obtain a copy of the License at
86174  *
86175  * http://www.apache.org/licenses/LICENSE-2.0
86176  *
86177  * Unless required by applicable law or agreed to in writing, software
86178  * distributed under the License is distributed on an "AS IS" BASIS,
86179  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86180  * See the License for the specific language governing permissions and
86181  * limitations under the License.
86182  */
86183
86184 var t = require('ripple/platform/tizen/2.0/typecast'),
86185     SortMode;
86186
86187 SortMode = function (attributeName, order) {
86188     var sortMode = {};
86189
86190     t.SortMode(arguments, this);
86191
86192     this.__defineGetter__("attributeName", function () {
86193         return sortMode.attributeName;
86194     });
86195     this.__defineSetter__("attributeName", function (val) {
86196         try {
86197             sortMode.attributeName = t.DOMString(val);
86198         } catch (e) {
86199         }
86200     });
86201
86202     this.__defineGetter__("order", function () {
86203         return sortMode.order;
86204     });
86205     this.__defineSetter__("order", function (val) {
86206         try {
86207             sortMode.order = t.SortModeOrder(val);
86208         } catch (e) {
86209         }
86210     });
86211
86212     sortMode.attributeName = attributeName;
86213     sortMode.order         = order || "ASC";
86214 };
86215
86216 module.exports = SortMode;
86217
86218 });
86219 define('ripple/platform/tizen/2.0/StatusNotification', function (require, exports, module) {
86220 /*
86221  *  Copyright 2013 Intel Corporation.
86222  *
86223  * Licensed under the Apache License, Version 2.0 (the "License");
86224  * you may not use this file except in compliance with the License.
86225  * You may obtain a copy of the License at
86226  *
86227  * http://www.apache.org/licenses/LICENSE-2.0
86228  *
86229  * Unless required by applicable law or agreed to in writing, software
86230  * distributed under the License is distributed on an "AS IS" BASIS,
86231  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86232  * See the License for the specific language governing permissions and
86233  * limitations under the License.
86234  */
86235
86236 var t = require('ripple/platform/tizen/2.0/typecast'),
86237     ApplicationControl = require('ripple/platform/tizen/2.0/ApplicationControl'),
86238     Notification = require('ripple/platform/tizen/2.0/NotificationBase'),
86239     NotificationDetailInfo = require('ripple/platform/tizen/2.0/NotificationDetailInfo'),
86240     StatusNotification;
86241
86242 StatusNotification = function (statusType, title, notificationInitDict) {
86243     var statusNotification = {}, attr, i, info;
86244
86245     t.StatusNotification(arguments, this);
86246
86247     Notification.call(this, title, notificationInitDict ?
86248             notificationInitDict.content : null);
86249
86250     statusNotification.statusType          = statusType;
86251     statusNotification.iconPath            = null;
86252     statusNotification.subIconPath         = null;
86253     statusNotification.number              = null;
86254     statusNotification.detailInfo          = [];
86255     statusNotification.ledColor            = null;
86256     statusNotification.ledOnPeriod         = 0;
86257     statusNotification.ledOffPeriod        = 0;
86258     statusNotification.backgroundImagePath = null;
86259     statusNotification.thumbnails          = [];
86260     statusNotification.soundPath           = null;
86261     statusNotification.vibration           = false;
86262     statusNotification.appControl          = null;
86263     statusNotification.appId               = null;
86264     statusNotification.progressType        = "PERCENTAGE";
86265     statusNotification.progressValue       = null;
86266
86267     for (attr in notificationInitDict) {
86268         switch (attr) {
86269         case "appControl":
86270             statusNotification.appControl = new ApplicationControl(
86271                     notificationInitDict.appControl.operation,
86272                     notificationInitDict.appControl.uri || null,
86273                     notificationInitDict.appControl.mime || null,
86274                     notificationInitDict.appControl.category || null,
86275                     notificationInitDict.appControl.data || null);
86276             break;
86277
86278         case "detailInfo":
86279             for (i in notificationInitDict.detailInfo) {
86280                 info = notificationInitDict.detailInfo[i];
86281                 info = new NotificationDetailInfo(info.mainText,
86282                         info.subText);
86283
86284                 statusNotification.detailInfo.push(info);
86285             }
86286             break;
86287
86288         default:
86289             statusNotification[attr] = notificationInitDict[attr];
86290             break;
86291         }
86292     }
86293
86294     this.__defineGetter__("statusType", function () {
86295         return statusNotification.statusType;
86296     });
86297
86298     this.__defineGetter__("iconPath", function () {
86299         return statusNotification.iconPath;
86300     });
86301     this.__defineSetter__("iconPath", function (val) {
86302         try {
86303             statusNotification.iconPath = t.DOMString(val, "?");
86304         } catch (e) {
86305         }
86306     });
86307
86308     this.__defineGetter__("subIconPath", function () {
86309         return statusNotification.subIconPath;
86310     });
86311     this.__defineSetter__("subIconPath", function (val) {
86312         try {
86313             statusNotification.subIconPath = t.DOMString(val, "?");
86314         } catch (e) {
86315         }
86316     });
86317
86318     this.__defineGetter__("number", function () {
86319         return statusNotification.number;
86320     });
86321     this.__defineSetter__("number", function (val) {
86322         try {
86323             statusNotification.number = t.long(val, "?");
86324         } catch (e) {
86325         }
86326     });
86327
86328     this.__defineGetter__("detailInfo", function () {
86329         return statusNotification.detailInfo;
86330     });
86331     this.__defineSetter__("detailInfo", function (val) {
86332         try {
86333             statusNotification.detailInfo = t.NotificationDetailInfo(val, "[]?");
86334         } catch (e) {
86335         }
86336     });
86337
86338     this.__defineGetter__("ledColor", function () {
86339         return statusNotification.ledColor;
86340     });
86341     this.__defineSetter__("ledColor", function (val) {
86342         try {
86343             statusNotification.ledColor = t.DOMString(val, "?");
86344         } catch (e) {
86345         }
86346     });
86347
86348     this.__defineGetter__("ledOnPeriod", function () {
86349         return statusNotification.ledOnPeriod;
86350     });
86351     this.__defineSetter__("ledOnPeriod", function (val) {
86352         try {
86353             statusNotification.ledOnPeriod = t.unsigned_long(val);
86354         } catch (e) {
86355         }
86356     });
86357
86358     this.__defineGetter__("ledOffPeriod", function () {
86359         return statusNotification.ledOffPeriod;
86360     });
86361     this.__defineSetter__("ledOffPeriod", function (val) {
86362         try {
86363             statusNotification.ledOffPeriod = t.unsigned_long(val);
86364         } catch (e) {
86365         }
86366     });
86367
86368     this.__defineGetter__("backgroundImagePath", function () {
86369         return statusNotification.backgroundImagePath;
86370     });
86371     this.__defineSetter__("backgroundImagePath", function (val) {
86372         try {
86373             statusNotification.backgroundImagePath = t.DOMString(val, "?");
86374         } catch (e) {
86375         }
86376     });
86377
86378     this.__defineGetter__("thumbnails", function () {
86379         return statusNotification.thumbnails;
86380     });
86381     this.__defineSetter__("thumbnails", function (val) {
86382         try {
86383             statusNotification.thumbnails = t.DOMString(val, "[]?");
86384         } catch (e) {
86385         }
86386     });
86387
86388     this.__defineGetter__("soundPath", function () {
86389         return statusNotification.soundPath;
86390     });
86391     this.__defineSetter__("soundPath", function (val) {
86392         try {
86393             statusNotification.soundPath = t.DOMString(val, "?");
86394         } catch (e) {
86395         }
86396     });
86397
86398     this.__defineGetter__("vibration", function () {
86399         return statusNotification.vibration;
86400     });
86401     this.__defineSetter__("vibration", function (val) {
86402         try {
86403             statusNotification.vibration = t.boolean(val);
86404         } catch (e) {
86405         }
86406     });
86407
86408     this.__defineGetter__("appControl", function () {
86409         return statusNotification.appControl;
86410     });
86411     this.__defineSetter__("appControl", function (val) {
86412         try {
86413             statusNotification.appControl = t.ApplicationControl(val, "?");
86414         } catch (e) {
86415         }
86416     });
86417
86418     this.__defineGetter__("appId", function () {
86419         return statusNotification.appId;
86420     });
86421     this.__defineSetter__("appId", function (val) {
86422         try {
86423             statusNotification.appId = t.ApplicationId(val, "?");
86424         } catch (e) {
86425         }
86426     });
86427
86428     this.__defineGetter__("progressType", function () {
86429         return statusNotification.progressType;
86430     });
86431     this.__defineSetter__("progressType", function (val) {
86432         try {
86433             statusNotification.progressType = t.NotificationProgressType(val);
86434         } catch (e) {
86435         }
86436     });
86437
86438     this.__defineGetter__("progressValue", function () {
86439         return statusNotification.progressValue;
86440     });
86441     this.__defineSetter__("progressValue", function (val) {
86442         try {
86443             val = t.unsigned_long(val, '?');
86444
86445             if ((statusNotification.progressType === "PERCENTAGE") &&
86446                     (val > 100))
86447                 return;
86448
86449             statusNotification.progressValue = val;
86450         } catch (e) {
86451         }
86452     });
86453 };
86454
86455 module.exports = StatusNotification;
86456
86457 });
86458 define('ripple/platform/tizen/2.0/SyncInfo', function (require, exports, module) {
86459 /*
86460  *  Copyright 2013 Intel Corporation.
86461  *
86462  * Licensed under the Apache License, Version 2.0 (the "License");
86463  * you may not use this file except in compliance with the License.
86464  * You may obtain a copy of the License at
86465  *
86466  * http://www.apache.org/licenses/LICENSE-2.0
86467  *
86468  * Unless required by applicable law or agreed to in writing, software
86469  * distributed under the License is distributed on an "AS IS" BASIS,
86470  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86471  * See the License for the specific language governing permissions and
86472  * limitations under the License.
86473  */
86474
86475 var db = require('ripple/db'),
86476     t = require('ripple/platform/tizen/2.0/typecast'),
86477     SyncInfo,
86478     _accounts = {},
86479     _counter = 0;
86480
86481 SyncInfo = function () {
86482     var voc, syncInfo = {}, index;
86483
86484     function save() {
86485         _accounts[index] = {
86486             id:       syncInfo.id,
86487             password: syncInfo.password
86488         };
86489         db.saveObject("save-syncinfo", _accounts);
86490     }
86491
86492     function construct(url, id, password, mode) {
86493         syncInfo.url      = url;
86494         syncInfo.id       = id;
86495         syncInfo.password = password;
86496         syncInfo.mode     = mode;
86497         syncInfo.type     = null;
86498         syncInfo.interval = null;
86499
86500         this.__defineGetter__("url", function () {
86501             return syncInfo.url;
86502         });
86503         this.__defineSetter__("url", function (url) {
86504             try {
86505                 syncInfo.url = t.DOMString(url);
86506             } catch (e) {
86507             }
86508         });
86509
86510         this.__defineGetter__("id", function () {
86511             return null;
86512         });
86513         this.__defineSetter__("id", function (id) {
86514             try {
86515                 syncInfo.id = t.DOMString(id);
86516                 save();
86517             } catch (e) {
86518             }
86519         });
86520
86521         this.__defineGetter__("password", function () {
86522             return null;
86523         });
86524         this.__defineSetter__("password", function (password) {
86525             try {
86526                 syncInfo.password = t.DOMString(password);
86527                 save();
86528             } catch (e) {
86529             }
86530         });
86531
86532         this.__defineGetter__("mode", function () {
86533             return syncInfo.mode;
86534         });
86535         this.__defineSetter__("mode", function (mode) {
86536             try {
86537                 syncInfo.mode = t.SyncMode(mode);
86538             } catch (e) {
86539             }
86540         });
86541
86542         this.__defineGetter__("type", function () {
86543             return syncInfo.type;
86544         });
86545         this.__defineSetter__("type", function (type) {
86546             if (mode !== "MANUAL") {
86547                 return;
86548             }
86549             try {
86550                 syncInfo.type = t.SyncType(type);
86551             } catch (e) {
86552             }
86553         });
86554
86555         this.__defineGetter__("interval", function () {
86556             return syncInfo.interval;
86557         });
86558         this.__defineSetter__("interval", function (interval) {
86559             if (mode !== "PERIODIC") {
86560                 return;
86561             }
86562             try {
86563                 syncInfo.interval = t.SyncInterval(interval);
86564             } catch (e) {
86565             }
86566         });
86567     }
86568
86569     voc = [
86570         function (url, id, password, mode, type) {
86571             construct.apply(this, arguments);
86572
86573             if (mode === "MANUAL") {
86574                 syncInfo.type = type;
86575             }
86576         },
86577         function (url, id, password, mode, interval) {
86578             construct.apply(this, arguments);
86579
86580             if (mode === "PERIODIC") {
86581                 syncInfo.interval = interval;
86582             }
86583         },
86584         function (url, id, password, mode) {
86585             construct.apply(this, arguments);
86586         }
86587     ];
86588
86589     t.SyncInfo(arguments, this, voc);
86590
86591     index = _counter++;
86592     Object.defineProperty(this, "__syncInfoID__", {
86593         "configurable": false,
86594         "enumerable":   false,
86595         "get": (function (_id_) {
86596             return function () { return _id_; };
86597         })(index)
86598     });
86599     save();
86600 };
86601
86602 module.exports = SyncInfo;
86603
86604 });
86605 define('ripple/platform/tizen/2.0/SyncProfileInfo', function (require, exports, module) {
86606 /*
86607  *  Copyright 2013 Intel Corporation.
86608  *
86609  * Licensed under the Apache License, Version 2.0 (the "License");
86610  * you may not use this file except in compliance with the License.
86611  * You may obtain a copy of the License at
86612  *
86613  * http://www.apache.org/licenses/LICENSE-2.0
86614  *
86615  * Unless required by applicable law or agreed to in writing, software
86616  * distributed under the License is distributed on an "AS IS" BASIS,
86617  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86618  * See the License for the specific language governing permissions and
86619  * limitations under the License.
86620  */
86621
86622 var t = require('ripple/platform/tizen/2.0/typecast'),
86623     SyncProfileInfo;
86624
86625 SyncProfileInfo = function (profileName, syncInfo, serviceInfo) {
86626     var syncProfileInfo = {};
86627
86628     t.SyncProfileInfo(arguments, this);
86629
86630     syncProfileInfo.profileName = profileName;
86631     syncProfileInfo.syncInfo    = syncInfo;
86632     syncProfileInfo.serviceInfo = serviceInfo;
86633
86634     this.__defineGetter__("profileId", function () {
86635         return null;
86636     });
86637
86638     this.__defineGetter__("profileName", function () {
86639         return syncProfileInfo.profileName;
86640     });
86641     this.__defineSetter__("profileName", function (profileName) {
86642         try {
86643             syncProfileInfo.profileName = t.DOMString(profileName);
86644         } catch (e) {
86645         }
86646     });
86647
86648     this.__defineGetter__("syncInfo", function () {
86649         return syncProfileInfo.syncInfo;
86650     });
86651     this.__defineSetter__("syncInfo", function (syncInfo) {
86652         try {
86653             t.SyncInfo(syncInfo);
86654             syncProfileInfo.syncInfo = syncInfo;
86655         } catch (e) {
86656         }
86657     });
86658
86659     this.__defineGetter__("serviceInfo", function () {
86660         return syncProfileInfo.serviceInfo;
86661     });
86662     this.__defineSetter__("serviceInfo", function (serviceInfo) {
86663         try {
86664             t.SyncServiceInfo(serviceInfo, "[]?");
86665             syncProfileInfo.serviceInfo = serviceInfo;
86666         } catch (e) {
86667         }
86668     });
86669 };
86670
86671 module.exports = SyncProfileInfo;
86672
86673 });
86674 define('ripple/platform/tizen/2.0/SyncServiceInfo', function (require, exports, module) {
86675 /*
86676  *  Copyright 2013 Intel Corporation.
86677  *
86678  * Licensed under the Apache License, Version 2.0 (the "License");
86679  * you may not use this file except in compliance with the License.
86680  * You may obtain a copy of the License at
86681  *
86682  * http://www.apache.org/licenses/LICENSE-2.0
86683  *
86684  * Unless required by applicable law or agreed to in writing, software
86685  * distributed under the License is distributed on an "AS IS" BASIS,
86686  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86687  * See the License for the specific language governing permissions and
86688  * limitations under the License.
86689  */
86690
86691 var db = require('ripple/db'),
86692     t = require('ripple/platform/tizen/2.0/typecast'),
86693     SyncServiceInfo,
86694     _accounts = {},
86695     _counter = 0;
86696
86697 SyncServiceInfo = function (enable, serviceType, serverDatabaseUri, id,
86698         password) {
86699     var syncServiceInfo = {}, index;
86700
86701     function save() {
86702         _accounts[index] = {
86703             id: syncServiceInfo.id,
86704             password: syncServiceInfo.password
86705         };
86706         db.saveObject("save-syncserviceinfo", _accounts);
86707     }
86708
86709     t.SyncServiceInfo(arguments, this);
86710
86711     syncServiceInfo.enable            = enable;
86712     syncServiceInfo.serviceType       = serviceType;
86713     syncServiceInfo.serverDatabaseUri = serverDatabaseUri;
86714     syncServiceInfo.id                = id || null;
86715     syncServiceInfo.password          = password || null;
86716
86717     this.__defineGetter__("enable", function () {
86718         return syncServiceInfo.enable;
86719     });
86720     this.__defineSetter__("enable", function (enable) {
86721         try {
86722             syncServiceInfo.enable = t.boolean(enable);
86723         } catch (e) {
86724         }
86725     });
86726
86727     this.__defineGetter__("serviceType", function () {
86728         return syncServiceInfo.serviceType;
86729     });
86730     this.__defineSetter__("serviceType", function (serviceType) {
86731         try {
86732             syncServiceInfo.serviceType = t.SyncServiceType(serviceType);
86733         } catch (e) {
86734         }
86735     });
86736
86737     this.__defineGetter__("serverDatabaseUri", function () {
86738         return syncServiceInfo.serverDatabaseUri;
86739     });
86740     this.__defineSetter__("serverDatabaseUri", function (serverDatabaseUri) {
86741         try {
86742             syncServiceInfo.serverDatabaseUri = t.DOMString(serverDatabaseUri);
86743         } catch (e) {
86744         }
86745     });
86746
86747     this.__defineGetter__("id", function () {
86748         return null;
86749     });
86750     this.__defineSetter__("id", function (id) {
86751         try {
86752             syncServiceInfo.id = t.DOMString(id);
86753             save();
86754         } catch (e) {
86755         }
86756     });
86757
86758     this.__defineGetter__("password", function () {
86759         return null;
86760     });
86761     this.__defineSetter__("password", function (password) {
86762         try {
86763             syncServiceInfo.password = t.DOMString(password);
86764             save();
86765         } catch (e) {
86766         }
86767     });
86768
86769     index = _counter++;
86770     Object.defineProperty(this, "__syncServiceInfoID__", {
86771         "configurable": false,
86772         "enumerable":   false,
86773         "get": (function (_id_) {
86774             return function () { return _id_; };
86775         })(index)
86776     });
86777     save();
86778 };
86779
86780 module.exports = SyncServiceInfo;
86781
86782 });
86783 define('ripple/platform/tizen/2.0/SyncStatistics', function (require, exports, module) {
86784 /*
86785  *  Copyright 2013 Intel Corporation.
86786  *
86787  * Licensed under the Apache License, Version 2.0 (the "License");
86788  * you may not use this file except in compliance with the License.
86789  * You may obtain a copy of the License at
86790  *
86791  * http://www.apache.org/licenses/LICENSE-2.0
86792  *
86793  * Unless required by applicable law or agreed to in writing, software
86794  * distributed under the License is distributed on an "AS IS" BASIS,
86795  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86796  * See the License for the specific language governing permissions and
86797  * limitations under the License.
86798  */
86799
86800 var SyncStatistics = function (syncStatus, serviceType, lastSyncTime,
86801         serverToClientTotal, serverToClientAdded, serverToClientUpdated,
86802         serverToClientRemoved, clientToServerTotal, clientToServerAdded,
86803         clientToServerUpdated, clientToServerRemoved) {
86804     this.__defineGetter__("syncStatus", function () {
86805         return syncStatus;
86806     });
86807
86808     this.__defineGetter__("serviceType", function () {
86809         return serviceType;
86810     });
86811
86812     this.__defineGetter__("lastSyncTime", function () {
86813         return lastSyncTime;
86814     });
86815
86816     this.__defineGetter__("serverToClientTotal", function () {
86817         return serverToClientTotal;
86818     });
86819
86820     this.__defineGetter__("serverToClientAdded", function () {
86821         return serverToClientAdded;
86822     });
86823
86824     this.__defineGetter__("serverToClientUpdated", function () {
86825         return serverToClientUpdated;
86826     });
86827
86828     this.__defineGetter__("serverToClientRemoved", function () {
86829         return serverToClientRemoved;
86830     });
86831
86832     this.__defineGetter__("clientToServerTotal", function () {
86833         return clientToServerTotal;
86834     });
86835
86836     this.__defineGetter__("clientToServerAdded", function () {
86837         return clientToServerAdded;
86838     });
86839
86840     this.__defineGetter__("clientToServerUpdated", function () {
86841         return clientToServerUpdated;
86842     });
86843
86844     this.__defineGetter__("clientToServerRemoved", function () {
86845         return clientToServerRemoved;
86846     });
86847 };
86848
86849 module.exports = SyncStatistics;
86850
86851 });
86852 define('ripple/platform/tizen/2.0/TZDate', function (require, exports, module) {
86853 /*
86854  *  Copyright 2012 Intel Corporation.
86855  *
86856  * Licensed under the Apache License, Version 2.0 (the "License");
86857  * you may not use this file except in compliance with the License.
86858  * You may obtain a copy of the License at
86859  *
86860  * http://www.apache.org/licenses/LICENSE-2.0
86861  *
86862  * Unless required by applicable law or agreed to in writing, software
86863  * distributed under the License is distributed on an "AS IS" BASIS,
86864  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86865  * See the License for the specific language governing permissions and
86866  * limitations under the License.
86867  */
86868
86869 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
86870     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
86871     tz = require('ripple/platform/tizen/2.0/timezone_info'),
86872     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
86873     _Month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
86874     _Day = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
86875
86876 function TZDate (dt) {
86877     var d, UTCd, UTC_diff, tzid = "", target_diff, temp_date, localeTime_fmt = 'h:m:s', localeDate_fmt = 'D, d M y',
86878     time = require('ripple/platform/tizen/2.0/time'),
86879         hour = arguments[3] || 0, min = arguments[4] || 0,
86880         sec = arguments[5] || 0, msec = arguments[6] || 0,
86881
86882     _checkTZDate = function (dat) {
86883         var Tzdate = require('ripple/platform/tizen/2.0/TZDate'),
86884             i, tzd;
86885         if (typeof dat !== 'object' || dat === undefined || dat === null) {
86886             return false;
86887         }
86888         tzd = new Tzdate();
86889         for (i in tzd) {
86890             if (dat.hasOwnProperty(i) === false) {
86891                 return false;
86892             }
86893         }
86894         return true;
86895     },
86896     _d2UTCd_sync = function () {
86897         UTCd = new Date(d.valueOf() - (UTC_diff * 1000 * 60 * 60));
86898     },
86899     _UTCd2d_sync = function () {
86900         d = new Date(UTCd.valueOf() + (UTC_diff * 1000 * 60 * 60));
86901     },
86902     _getValue = function (o) {
86903         var other;
86904         other = new Date(o.getUTCFullYear(), o.getUTCMonth(), o.getUTCDate(),
86905                     o.getUTCHours(), o.getUTCMinutes(), o.getUTCSeconds(), o.getUTCMilliseconds());
86906         return other.valueOf();
86907     },
86908     _formatDateString = function (fmt) {
86909         var i, ret = '';
86910         for (i = 0; i < fmt.length; i++) {
86911             switch (fmt.charAt(i)) {
86912             case 'd':
86913                 ret = ret + d.getDate();
86914                 break;
86915             case 'y':
86916                 ret = ret + d.getFullYear();
86917                 break;
86918             case 'm':
86919                 ret = ret + (d.getMonth() + 1);
86920                 break;
86921             case 'M':
86922                 ret = ret + _Month[d.getMonth()];
86923                 break;
86924             case 'D':
86925                 ret = ret + _Day[d.getDay()];
86926                 break;
86927             default:
86928                 ret = ret + fmt.charAt(i);
86929             }
86930         }
86931         return ret;
86932     },
86933     _formatTimeString = function (fmt) {
86934         var i, hh, mm, ss, AP, ret = "";
86935         if (fmt.search(/ap/) === -1) {
86936             AP = false;
86937         } else {
86938             AP = true;
86939             if (d.getHours() > 11) {
86940                 fmt = fmt.replace("ap", "PM");
86941             } else {
86942                 fmt = fmt.replace("ap", "AM");
86943             }
86944         }
86945         for (i = 0; i < fmt.length; i++) {
86946             switch (fmt.charAt(i)) {
86947             case 'h':
86948                 hh = d.getHours();
86949                 if (AP) {
86950                     hh = (hh > 12) ? hh - 12 : hh;
86951                 }
86952                 ret = ret + hh;
86953                 break;
86954             case 'm':
86955                 mm = d.getMinutes();
86956                 mm = (mm < 10 ? "0" : "") + mm;
86957                 ret = ret + mm;
86958                 break;
86959             case 's':
86960                 ss = d.getSeconds();
86961                 ss = (ss < 10 ? "0" : "") + ss;
86962                 ret = ret + ss;
86963                 break;
86964             default:
86965                 ret = ret + fmt.charAt(i);
86966             }
86967         }
86968         return ret;
86969     };
86970
86971     if (arguments[7] !== undefined) {
86972         tzid = arguments[7];
86973     }
86974
86975     if (dt === null || dt === undefined) {
86976         temp_date = new Date();
86977         if (arguments[1] !== undefined) {
86978             if (typeof arguments[1] !== 'string') {
86979                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
86980             }
86981             if (tz.isValidTimezone(arguments[1]) === false) {
86982                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
86983             }
86984             tzid = arguments[1];
86985         } else {
86986             tzid = time.getLocalTimezone();
86987         }
86988         target_diff = tz.getTimezoneDiff(tzid);
86989         d = new Date(temp_date.valueOf() + (target_diff + temp_date.getTimezoneOffset() / 60) * 1000 * 60 * 60);
86990     } else {
86991         if (tizen1_utils.isValidDate(dt)) {
86992             d = new Date(dt);
86993             if (arguments[1] !== undefined) {
86994                 tzid = arguments[1];
86995             } else {
86996                 tzid = time.getLocalTimezone();
86997             }
86998         } else {
86999             if (arguments.length === 1) {
87000                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
87001             } else {
87002                 d = new Date(arguments[0], arguments[1], arguments[2], hour, min, sec, msec);
87003             }
87004         }
87005     }
87006
87007     if (tz.isValidTimezone(tzid) === false) {
87008         tzid = 'UTC';
87009     }
87010     UTC_diff = tz.getTimezoneDiff(tzid);
87011     _d2UTCd_sync();
87012
87013     this.getDate = function () {
87014         return d.getDate();
87015     };
87016     this.setDate = function (dt) {
87017         d.setDate(dt);
87018         _d2UTCd_sync();
87019     };
87020     this.getDay = function () {
87021         return d.getDay();
87022     };
87023     this.getFullYear = function () {
87024         return d.getFullYear();
87025     };
87026     this.setFullYear = function (yr) {
87027         d.setFullYear(yr);
87028         _d2UTCd_sync();
87029     };
87030     this.getHours = function () {
87031         return d.getHours();
87032     };
87033     this.setHours = function (hr) {
87034         d.setHours(hr);
87035         _d2UTCd_sync();
87036     };
87037     this.getMilliseconds = function () {
87038         return d.getMilliseconds();
87039     };
87040     this.setMilliseconds = function (msec) {
87041         d.setMilliseconds(msec);
87042         _d2UTCd_sync();
87043     };
87044     this.getMinutes = function () {
87045         return d.getMinutes();
87046     };
87047     this.setMinutes = function (min) {
87048         d.setMinutes(min);
87049         _d2UTCd_sync();
87050     };
87051     this.getMonth = function () {
87052         return d.getMonth();
87053     };
87054     this.setMonth = function (m) {
87055         d.setMonth(m);
87056         _d2UTCd_sync();
87057     };
87058     this.getSeconds = function () {
87059         return d.getSeconds();
87060     };
87061     this.setSeconds = function (s) {
87062         d.setSeconds(s);
87063         _d2UTCd_sync();
87064     };
87065     this.getUTCDate = function () {
87066         return UTCd.getDate();
87067     };
87068     this.setUTCDate = function (dt) {
87069         UTCd.setDate(dt);
87070         _UTCd2d_sync();
87071     };
87072     this.getUTCDay = function () {
87073         return UTCd.getDay();
87074     };
87075     this.getUTCFullYear = function () {
87076         return UTCd.getFullYear();
87077     };
87078     this.setUTCFullYear = function (yr) {
87079         UTCd.setFullYear(yr);
87080         _UTCd2d_sync();
87081     };
87082     this.getUTCHours = function () {
87083         return UTCd.getHours();
87084     };
87085     this.setUTCHours = function (hr) {
87086         UTCd.setHours(hr);
87087         _UTCd2d_sync();
87088     };
87089     this.getUTCMilliseconds = function () {
87090         return UTCd.getMilliseconds();
87091     };
87092     this.setUTCMilliseconds = function (msec) {
87093         UTCd.setMilliseconds(msec);
87094         _UTCd2d_sync();
87095     };
87096     this.getUTCMinutes = function () {
87097         return UTCd.getMinutes();
87098     };
87099     this.setUTCMinutes = function (min) {
87100         UTCd.setMinutes(min);
87101         _UTCd2d_sync();
87102     };
87103     this.getUTCMonth = function () {
87104         return UTCd.getMonth();
87105     };
87106     this.setUTCMonth = function (m) {
87107         UTCd.setMonth(m);
87108         _UTCd2d_sync();
87109     };
87110     this.getUTCSeconds = function () {
87111         return UTCd.getSeconds();
87112     };
87113     this.setUTCSeconds = function (s) {
87114         UTCd.setSeconds(s);
87115         _UTCd2d_sync();
87116     };
87117     this.getTimezone = function () {
87118         return tzid;
87119     };
87120     this.toTimezone = function (new_tzid) {
87121         var diff,
87122             Tzdate = require('ripple/platform/tizen/2.0/TZDate');
87123         if (tz.isValidTimezone(String(new_tzid)) === true) {
87124             diff = tz.getTimezoneDiff(new_tzid) - UTC_diff;
87125             return new Tzdate(new Date(d.valueOf() + (diff * 1000 * 60 * 60)), new_tzid);
87126         } else {
87127             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
87128         }
87129     };
87130     this.toLocalTimezone = function () {
87131         var diff,
87132             localTzid,
87133             Tzdate = require('ripple/platform/tizen/2.0/TZDate');
87134         localTzid = time.getLocalTimezone();
87135
87136         diff = tz.getTimezoneDiff(localTzid) - UTC_diff;
87137         return new Tzdate(new Date(d.valueOf() + (diff * 1000 * 60 * 60)), localTzid);
87138     };
87139     this.toUTC = function () {
87140         var Tzdate = require('ripple/platform/tizen/2.0/TZDate');
87141         return new Tzdate(UTCd, "UTC");
87142     };
87143     this.difference = function (other) {
87144         var diff,
87145             TDur = require('ripple/platform/tizen/2.0/TimeDuration');
87146         if (_checkTZDate(other) === false) {
87147             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
87148         }
87149         diff = (UTCd.valueOf() - _getValue(other));
87150         if (diff % 86400000 === 0) {
87151             return new TDur(diff/86400000, 'DAYS');
87152         } else {
87153             return new TDur(diff);
87154         }
87155     };
87156     this.equalsTo = function (other) {
87157         if (_checkTZDate(other) === false) {
87158             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
87159         }
87160         return (UTCd.valueOf() === _getValue(other));
87161     };
87162     this.earlierThan = function (other) {
87163         if (_checkTZDate(other) === false) {
87164             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
87165         }
87166         return (UTCd.valueOf() < _getValue(other));
87167     };
87168     this.laterThan = function (other) {
87169         if (_checkTZDate(other) === false) {
87170             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
87171         }
87172         return (UTCd.valueOf() > _getValue(other));
87173     };
87174     this.addDuration = function (dur) {
87175         var Tzdate = require('ripple/platform/tizen/2.0/TZDate'),
87176             Tunit = {"MSECS": 1,
87177                 "SECS": 1000,
87178                 "MINS": 60 * 1000,
87179                 "HOURS": 60 * 60 * 1000,
87180                 "DAYS": 24 * 60 * 60 * 1000
87181             };
87182         if (typeof dur !== 'object' || dur === undefined || dur === null) {
87183             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
87184         }
87185         if (dur.length === undefined || dur.length === null ||
87186                 dur.unit === undefined || dur.unit === null) {
87187             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
87188         }
87189         if ((typeof dur.length) !== 'number') {
87190             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
87191         }
87192         if (Tunit[dur.unit] === undefined) {
87193             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
87194         }
87195         return new Tzdate(new Date(d.valueOf() + (parseInt(dur.length, 10) * Tunit[dur.unit])), tzid);
87196     };
87197     this.toLocaleDateString = function () {
87198         if (d.toString() === "Invalid Date") {
87199             return d.toString();
87200         } else {
87201             return _formatDateString(localeDate_fmt);
87202         }
87203     };
87204     this.toLocaleTimeString = function () {
87205         if (d.toString() === "Invalid Date") {
87206             return d.toString();
87207         } else {
87208             return _formatTimeString(localeTime_fmt);
87209         }
87210     };
87211     this.toLocaleString = function () {
87212         if (d.toString() === "Invalid Date") {
87213             return d.toString();
87214         } else {
87215             return (this.toLocaleDateString() + " " + this.toLocaleTimeString());
87216         }
87217     };
87218     this.toDateString = function () {
87219         var ret = "", fmt = time.getDateFormat();
87220         if (d.toString() === "Invalid Date") {
87221             return d.toString();
87222         }
87223         ret = _formatDateString(fmt);
87224         return ret;
87225     };
87226     this.toTimeString = function () {
87227         var ret, fmt = time.getTimeFormat();
87228
87229         if (d.toString() === "Invalid Date") {
87230             return d.toString();
87231         }
87232
87233         ret = _formatTimeString(fmt);
87234         if (tz.getTimezoneDesc(tzid) !== null) {
87235             return ret + " " + tz.getTimezoneDesc(tzid);
87236         } else {
87237             return ret + " " + tz.getTimezoneAbbr(tzid);
87238         }
87239         return ret;
87240     };
87241     this.toString = function () {
87242         if (d.toString() === "Invalid Date") {
87243             return d.toString();
87244         } else {
87245             return (this.toDateString() + " " + this.toTimeString());
87246         }
87247     };
87248     this.getTimezoneAbbreviation = function () {
87249         return tz.getTimezoneAbbr(tzid);
87250     };
87251     this.secondsFromUTC = function () {
87252         return (-1 * UTC_diff * 60 * 60);
87253     };
87254     this.isDST = function () {
87255         throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR));
87256     };
87257     this.getPreviousDSTTransition = function () {
87258         throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR));
87259     };
87260     this.getNextDSTTransition = function () {
87261         throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR));
87262     };
87263     return this;
87264 }
87265
87266 module.exports = TZDate;
87267
87268 });
87269 define('ripple/platform/tizen/2.0/TimeDuration', function (require, exports, module) {
87270 /*
87271  *  Copyright 2012 Intel Corporation.
87272  *
87273  * Licensed under the Apache License, Version 2.0 (the "License");
87274  * you may not use this file except in compliance with the License.
87275  * You may obtain a copy of the License at
87276  *
87277  * http://www.apache.org/licenses/LICENSE-2.0
87278  *
87279  * Unless required by applicable law or agreed to in writing, software
87280  * distributed under the License is distributed on an "AS IS" BASIS,
87281  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87282  * See the License for the specific language governing permissions and
87283  * limitations under the License.
87284  */
87285
87286 var t = require('ripple/platform/tizen/2.0/typecast'),
87287     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
87288     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
87289     TimeDuration;
87290
87291 TimeDuration = function (_length, _unit) {
87292     var timeDuration = {},
87293         TimeDurationUnit = {"MSECS": 1,
87294                             "SECS": 1000,
87295                             "MINS": 60 * 1000,
87296                             "HOURS": 60 * 60 * 1000,
87297                             "DAYS": 24 * 60 * 60 * 1000
87298                            },
87299         _simplifyDuration = function (ms) {
87300             var TDur = require('ripple/platform/tizen/2.0/TimeDuration'),
87301                 uni = "MSECS";
87302             if ((ms % 1000) === 0) {
87303                 ms = ms / 1000;
87304                 uni = "SECS";
87305                 if ((ms % 60) === 0) {
87306                     ms = ms / 60;
87307                     uni = "MINS";
87308                     if ((ms % 60) === 0) {
87309                         ms = ms / 60;
87310                         uni = "HOURS";
87311                         if ((ms % 24) === 0) {
87312                             ms = ms / 24;
87313                             uni = "DAYS";
87314                         }
87315                     }
87316                 }
87317             }
87318             return (new TDur(ms, uni));
87319         },
87320         _toMSECS = function (unit) {
87321             if (TimeDurationUnit[unit] === undefined) {
87322                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
87323             } else {
87324                 return TimeDurationUnit[unit];
87325             }
87326         };
87327
87328     t.TimeDuration(arguments, this);
87329
87330     this.__defineGetter__("length", function () {
87331         return timeDuration.length;
87332     });
87333     this.__defineSetter__("length", function (val) {
87334         try {
87335             timeDuration.length = t.double(val);
87336         } catch (e) {
87337         }
87338     });
87339
87340     this.__defineGetter__("unit", function () {
87341         return timeDuration.unit;
87342     });
87343     this.__defineSetter__("unit", function (val) {
87344         try {
87345             timeDuration.unit = t.TimeDurationUnit(val);
87346         } catch (e) {
87347         }
87348     });
87349
87350     timeDuration.length = _length;
87351     timeDuration.unit = _unit || "MSECS";
87352
87353     this.difference = function (o) {
87354
87355         t.TimeDuration("difference", arguments);
87356
87357         var thisMS = timeDuration.length * _toMSECS(timeDuration.unit),
87358             otherMS = o.length * _toMSECS(o.unit);
87359         return _simplifyDuration(thisMS - otherMS);
87360     };
87361     this.equalsTo = function (o) {
87362
87363         t.TimeDuration("equalsTo", arguments);
87364
87365         var thisMS = timeDuration.length * _toMSECS(timeDuration.unit),
87366             otherMS = o.length * _toMSECS(o.unit);
87367         return (thisMS === otherMS);
87368     };
87369     this.lessThan = function (o) {
87370
87371         t.TimeDuration("lessThan", arguments);
87372
87373         var thisMS = timeDuration.length * _toMSECS(timeDuration.unit),
87374             otherMS = o.length * _toMSECS(o.unit);
87375         return (thisMS < otherMS);
87376     };
87377     this.greaterThan = function (o) {
87378
87379         t.TimeDuration("greaterThan", arguments);
87380
87381         var thisMS = timeDuration.length * _toMSECS(timeDuration.unit),
87382             otherMS = o.length * _toMSECS(o.unit);
87383         return (thisMS > otherMS);
87384     };
87385 };
87386
87387 module.exports = TimeDuration;
87388
87389 });
87390 define('ripple/platform/tizen/2.0/WebAPIError', function (require, exports, module) {
87391 /*
87392  *  Copyright 2012 Intel Corporation.
87393  *
87394  * Licensed under the Apache License, Version 2.0 (the "License");
87395  * you may not use this file except in compliance with the License.
87396  * You may obtain a copy of the License at
87397  *
87398  * http://www.apache.org/licenses/LICENSE-2.0
87399  *
87400  * Unless required by applicable law or agreed to in writing, software
87401  * distributed under the License is distributed on an "AS IS" BASIS,
87402  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87403  * See the License for the specific language governing permissions and
87404  * limitations under the License.
87405  */
87406
87407 var errorcode = require('ripple/platform/tizen/2.0/errorcode');
87408
87409 var msg = {
87410     0: "Generic Error",
87411     1: "Index or size is negative, or greater than the allowed value.",
87412     2: "Specified range of text does not fit into a DOMString.",
87413     3: "Node is inserted somewhere it doesn't belong.",
87414     4: "Node is used in a different document than the one that created it (that doesn't support it).",
87415     5: "An invalid or illegal character is specified.",
87416     6: "Data is specified for a Node which does not support data.",
87417     7: "An attempt is made to modify an object where modifications are not allowed.",
87418     8: "An attempt is made to reference a Node in a context where it does not exist.",
87419     9: "The implementation does not support the requested type of object or operation.",
87420     10: "An attempt is made to add an attribute that is already in use elsewhere.",
87421     11: "An attempt is made to use an object that is not, or is no longer, usable.",
87422     12: "An invalid or illegal string is specified.",
87423     13: "An attempt is made to modify the type of the underlying object.",
87424     14: "An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.",
87425     15: "A parameter or an operation is not supported by the underlying object.",
87426     16: "A call to a method such as insertBefore or removeChild would make the Node invalid with respect to \"partial validity\", this exception would be raised and the operation would not be done.",
87427     17: "The type of an object is incompatible with the expected type of the parameter associated to the object.",
87428     18: "An attempt is made to perform an operation or access some data in a way that would be a security risk or a violation of the user agent's security policy.",
87429     19: "A network error occurs in synchronous requests.",
87430     20: "The abort error occurs in asynchronous requests by user prompt.",
87431     21: "The operation could not be completed because the URL does not match.",
87432     22: "The quota has been exceeded.",
87433     23: "The operation timed out.",
87434     24: "The supplied node is incorrect or has an incorrect ancestor for this operation.",
87435     25: "The object can not be cloned.",
87436     99: "The content of an object does not include valid values.",
87437     100: "Error occurred in communication with the underlying implementation that meant the requested method could not complete.",
87438     111: "Requested service is not available."
87439 },
87440     errType = {
87441     0: "UnknownError",
87442     1: "IndexSizeError",
87443     2: "DOMStringSizeError",
87444     3: "HierarchyRequestError",
87445     4: "WrongDocumentError",
87446     5: "InvalidCharacterError",
87447     6: "NoDataAllowedError",
87448     7: "NoModificationAllowedError",
87449     8: "NotFoundError",
87450     9: "NotSupportedError",
87451     10: "InuseAttributeError",
87452     11: "InvalidStateError",
87453     12: "SyntaxError",
87454     13: "InvalidModificationError",
87455     14: "NamespaceError",
87456     15: "InvalidAccessError",
87457     16: "ValidationError",
87458     17: "TypeMismatchError",
87459     18: "SecurityError",
87460     19: "NetworkError",
87461     20: "AbortError",
87462     21: "URLMismatchError",
87463     22: "QuotaExceededError",
87464     23: "TimeoutError",
87465     24: "InvalidNodeTypeError",
87466     25: "DataCloneError",
87467     99: "InvalidValuesError",
87468     100: "IOError",
87469     111: "ServiceNotAvailableError"
87470 };
87471
87472 /*
87473   support 3 types of error:
87474   - WebAPIError()
87475       code = errorcode.UNKNOWN_ERR
87476       message = errorcode.message[UNKNOWN_ERR]
87477   - WebAPIError(errorcode."TYPE_MISMATCH_ERR")
87478       code = 17
87479       message = errorcode.message[17]
87480   - WebAPIError(my_own_error_code, "This is my error message.")
87481       code = my_own_error_code(number)
87482       message = "This is my error message."
87483 */
87484
87485 module.exports = function (code, message, name) {
87486     var _code, _message, _name;
87487
87488     if (typeof code !== 'number') {
87489         _code = errorcode.UNKNOWN_ERR;
87490         _message = msg[_code];
87491         _name = errType[_code];
87492     } else {
87493         _code = code;
87494         if (typeof message === 'string') {
87495             _message = message;
87496         } else {
87497             _message = msg[_code];
87498         }
87499         if (typeof name === 'string') {
87500             _name = name;
87501         } else {
87502             _name = errType[_code];
87503         }
87504     }
87505
87506     this.__defineGetter__("code", function () {
87507         return _code;
87508     });
87509     this.__defineGetter__("message", function () {
87510         return _message;
87511     });
87512     this.__defineGetter__("name", function () {
87513         return _name;
87514     });
87515 };
87516
87517 });
87518 define('ripple/platform/tizen/2.0/WebAPIException', function (require, exports, module) {
87519 /*
87520  *  Copyright 2012 Intel Corporation.
87521  *
87522  * Licensed under the Apache License, Version 2.0 (the "License");
87523  * you may not use this file except in compliance with the License.
87524  * You may obtain a copy of the License at
87525  *
87526  * http://www.apache.org/licenses/LICENSE-2.0
87527  *
87528  * Unless required by applicable law or agreed to in writing, software
87529  * distributed under the License is distributed on an "AS IS" BASIS,
87530  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87531  * See the License for the specific language governing permissions and
87532  * limitations under the License.
87533  */
87534
87535 var errorcode = require('ripple/platform/tizen/2.0/errorcode');
87536
87537 var msg = {
87538     0: "Generic Error",
87539     1: "Index or size is negative, or greater than the allowed value.",
87540     2: "Specified range of text does not fit into a DOMString.",
87541     3: "Node is inserted somewhere it doesn't belong.",
87542     4: "Node is used in a different document than the one that created it (that doesn't support it).",
87543     5: "An invalid or illegal character is specified.",
87544     6: "Data is specified for a Node which does not support data.",
87545     7: "An attempt is made to modify an object where modifications are not allowed.",
87546     8: "An attempt is made to reference a Node in a context where it does not exist.",
87547     9: "The implementation does not support the requested type of object or operation.",
87548     10: "An attempt is made to add an attribute that is already in use elsewhere.",
87549     11: "An attempt is made to use an object that is not, or is no longer, usable.",
87550     12: "An invalid or illegal string is specified.",
87551     13: "An attempt is made to modify the type of the underlying object.",
87552     14: "An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.",
87553     15: "A parameter or an operation is not supported by the underlying object.",
87554     16: "A call to a method such as insertBefore or removeChild would make the Node invalid with respect to \"partial validity\", this exception would be raised and the operation would not be done.",
87555     17: "The type of an object is incompatible with the expected type of the parameter associated to the object.",
87556     18: "An attempt is made to perform an operation or access some data in a way that would be a security risk or a violation of the user agent's security policy.",
87557     19: "A network error occurs in synchronous requests.",
87558     20: "The abort error occurs in asynchronous requests by user prompt.",
87559     21: "The operation could not be completed because the URL does not match.",
87560     22: "The quota has been exceeded.",
87561     23: "The operation timed out.",
87562     24: "The supplied node is incorrect or has an incorrect ancestor for this operation.",
87563     25: "The object can not be cloned.",
87564     99: "The content of an object does not include valid values.",
87565     100: "Error occurred in communication with the underlying implementation that meant the requested method could not complete.",
87566     111: "Requested service is not available."
87567 },
87568     errType = {
87569     0: "UnknownError",
87570     1: "IndexSizeError",
87571     2: "DOMStringSizeError",
87572     3: "HierarchyRequestError",
87573     4: "WrongDocumentError",
87574     5: "InvalidCharacterError",
87575     6: "NoDataAllowedError",
87576     7: "NoModificationAllowedError",
87577     8: "NotFoundError",
87578     9: "NotSupportedError",
87579     10: "InuseAttributeError",
87580     11: "InvalidStateError",
87581     12: "SyntaxError",
87582     13: "InvalidModificationError",
87583     14: "NamespaceError",
87584     15: "InvalidAccessError",
87585     16: "ValidationError",
87586     17: "TypeMismatchError",
87587     18: "SecurityError",
87588     19: "NetworkError",
87589     20: "AbortError",
87590     21: "URLMismatchError",
87591     22: "QuotaExceededError",
87592     23: "TimeoutError",
87593     24: "InvalidNodeTypeError",
87594     25: "DataCloneError",
87595     99: "InvalidValuesError",
87596     100: "IOError",
87597     111: "ServiceNotAvailableError"
87598 };
87599
87600 /*
87601   support 3 types of error:
87602   - WebAPIError()
87603       code = errorcode.UNKNOWN_ERR
87604       message = errorcode.message[UNKNOWN_ERR]
87605   - WebAPIError(errorcode."TYPE_MISMATCH_ERR")
87606       code = 17
87607       message = errorcode.message[17]
87608   - WebAPIError(my_own_error_code, "This is my error message.")
87609       code = my_own_error_code(number)
87610       message = "This is my error message."
87611 */
87612
87613 module.exports = function (code, message, name) {
87614     var g, c, _code, _message, _name;
87615
87616     for (c in errorcode) {
87617         g = errorcode.__lookupGetter__(c);
87618         if (g) {
87619             this.__defineGetter__(c, g);
87620         }
87621     }
87622
87623     if (typeof code !== 'number') {
87624         _code = errorcode.UNKNOWN_ERR;
87625         _message = msg[_code];
87626         _name = errType[_code];
87627     } else {
87628         _code = code;
87629         if (typeof message === 'string') {
87630             _message = message;
87631         } else {
87632             _message = msg[_code];
87633         }
87634         if (typeof name === 'string') {
87635             _name = name;
87636         } else {
87637             _name = errType[_code];
87638         }
87639     }
87640
87641     this.__defineGetter__("code", function () {
87642         return _code;
87643     });
87644     this.__defineGetter__("message", function () {
87645         return _message;
87646     });
87647     this.__defineGetter__("name", function () {
87648         return _name;
87649     });
87650 };
87651
87652 });
87653 define('ripple/platform/tizen/2.0/account', function (require, exports, module) {
87654 /*
87655  *  Copyright 2012 Intel Corporation.
87656  *
87657  * Licensed under the Apache License, Version 2.0 (the "License");
87658  * you may not use this file except in compliance with the License.
87659  * You may obtain a copy of the License at
87660  *
87661  * http://www.apache.org/licenses/LICENSE-2.0
87662  *
87663  * Unless required by applicable law or agreed to in writing, software
87664  * distributed under the License is distributed on an "AS IS" BASIS,
87665  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87666  * See the License for the specific language governing permissions and
87667  * limitations under the License.
87668  */
87669
87670 var db = require('ripple/db'),
87671     utils = require('ripple/utils'),
87672     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
87673     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
87674     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
87675     _data = {
87676         DB_ACCOUNT_KEY : "tizen1-db-accounts",
87677         accounts : {}
87678     },
87679     _self;
87680
87681 function _checkAccount(account) {
87682     if (typeof account !== "object" ||
87683         typeof account.id !== "string" ||
87684         typeof account.appid !== "string" ||
87685         typeof account.userName !== "string" ||
87686         typeof account.displayName !== "string" ||
87687         typeof account.service !== "object") {
87688         return false;
87689     }
87690
87691     return true;
87692 }
87693
87694 function _checkCallback(successCallback, errorCallback) {
87695     tizen1_utils.validateArgumentType(successCallback, "function",
87696                                         new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
87697     if (errorCallback) {
87698         tizen1_utils.validateArgumentType(errorCallback, "function",
87699                                             new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
87700     }
87701 }
87702
87703 _self = {
87704     getAccounts : function () {
87705         var results = [];
87706         utils.forEach(_data.accounts, function (account) {
87707             results.push(utils.copy(account));
87708         });
87709
87710         return results;
87711     },
87712
87713     getAccountById : function (id) {
87714         var acccount = null;
87715
87716         if (typeof id !== "string") {
87717             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
87718         }
87719
87720         if (_data.accounts[id]) {
87721             account = utils.copy(_data.accounts[id]);
87722         }
87723
87724         return account;
87725     },
87726
87727     getAccountByUserName : function (userName) {
87728         var result = null;
87729
87730         if (typeof userName !== "string") {
87731             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
87732         }
87733
87734         utils.forEach(_data.accounts, function (account) {
87735             if (userName === account.userName) {
87736                 result = utils.copy(account);
87737             }
87738         });
87739
87740         return result;
87741     },
87742
87743     getAccountByappId : function (appId) {
87744         var result = null;
87745
87746         if (typeof appId !== "string") {
87747             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
87748         }
87749
87750         utils.forEach(_data.accounts, function (account) {
87751             if (appId === account.appId) {
87752                 result = utils.copy(account);
87753             }
87754         });
87755
87756         return result;
87757     },
87758
87759     getAccountByServiceId : function (serviceId) {
87760         var result = null;
87761
87762         if (typeof serviceId !== "string") {
87763             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
87764         }
87765
87766         utils.forEach(_data.accounts, function (account) {
87767             if (serviceId === account.service.id) {
87768                 result = utils.copy(account);
87769             }
87770         });
87771
87772         return result;
87773     },
87774
87775     getAccountByTag : function (tag) {
87776         var results = [], i;
87777
87778         if (typeof tag !== "string") {
87779             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
87780         }
87781
87782         utils.forEach(_data.accounts, function (account) {
87783             for (i in account.service.tag) {
87784                 if (tag === account.service.tag[i]) {
87785                     results.push(utils.copy(account));
87786                     break;
87787                 }
87788             }
87789         });
87790
87791         return results;
87792     },
87793
87794     add : function (account, successCallback, errorCallback) {
87795         if (!_checkAccount(account)) {
87796             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
87797         }
87798
87799         _checkCallback(successCallback, errorCallback);
87800
87801         if (!_data.accounts[account.id]) {
87802             _data.accounts[account.id] = utils.copy(account);
87803         }
87804
87805         successCallback();
87806     },
87807
87808     update : function (account, successCallback, errorCallback) {
87809         if (!_checkAccount(account)) {
87810             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
87811         }
87812
87813         _checkCallback(successCallback, errorCallback);
87814
87815         if (!_data.accounts[account.id]) {
87816             errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
87817             return;
87818         }
87819
87820         _data.accounts[account.id] = utils.copy(account);
87821         successCallback();
87822     },
87823
87824     remove : function (id, successCallback, errorCallback) {
87825         if (typeof id !== "string") {
87826             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
87827         }
87828
87829         _checkCallback(successCallback, errorCallback);
87830
87831         if (!_data.accounts[id]) {
87832             errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
87833             return;
87834         }
87835
87836         delete _data.accounts[id];
87837         successCallback();
87838     },
87839
87840     getAccountApplications : function () {
87841         var results = [];
87842         /* FIXME: wait for API update */
87843         return results;
87844     }
87845 };
87846
87847 function _initialize() {
87848     _data.accounts = db.retrieveObject(_data.DB_ACCOUNT_KEY) || {};
87849 }
87850
87851 _initialize();
87852
87853 module.exports = _self;
87854
87855 });
87856 define('ripple/platform/tizen/2.0/alarm', function (require, exports, module) {
87857 /*
87858  *  Copyright 2012 Intel Corporation.
87859  *
87860  * Licensed under the Apache License, Version 2.0 (the "License");
87861  * you may not use this file except in compliance with the License.
87862  * You may obtain a copy of the License at
87863  *
87864  * http://www.apache.org/licenses/LICENSE-2.0
87865  *
87866  * Unless required by applicable law or agreed to in writing, software
87867  * distributed under the License is distributed on an "AS IS" BASIS,
87868  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87869  * See the License for the specific language governing permissions and
87870  * limitations under the License.
87871  */
87872
87873 var db = require('ripple/db'),
87874     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
87875     event = require('ripple/event'),
87876     utils = require('ripple/utils'),
87877     t = require('ripple/platform/tizen/2.0/typecast'),
87878     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
87879     AlarmRelative = require('ripple/platform/tizen/2.0/AlarmRelative'),
87880     AlarmAbsolute = require('ripple/platform/tizen/2.0/AlarmAbsolute'),
87881     AlarmStore,
87882     _DB_ALARMS_KEY = "tizen1.0-db-alarms",
87883     PERIOD_MINUTE = 60,
87884     PERIOD_HOUR   = 60 * PERIOD_MINUTE,
87885     PERIOD_DAY    = 24 * PERIOD_HOUR,
87886     PERIOD_WEEK   = 7 * PERIOD_DAY,
87887     _alarms = {}, _alarmStack = [],
87888     _security = {
87889         "http://tizen.org/privilege/alarm": ["add", "remove", "removeAll"]
87890     },
87891     _isInitialized = false, _self;
87892
87893 function _initialize() {
87894     _alarms = db.retrieveObject(_DB_ALARMS_KEY);
87895     utils.forEach(_alarms, function (alarmStore) {
87896         alarmStore.date = new Date(alarmStore.date);
87897         _alarmStack.push(alarmStore);
87898     });
87899     _isInitialized = true;
87900 }
87901
87902 function _get() {
87903     if (!_isInitialized) {
87904         _initialize();
87905     }
87906 }
87907
87908 function _save() {
87909     db.saveObject(_DB_ALARMS_KEY, _alarmStack);
87910 }
87911
87912 function _updateDB(alarmStore) {
87913     _alarmStack.push(alarmStore);
87914     _save();
87915 }
87916
87917 function _getCurrentAppId() {
87918     return db.retrieve("current-url");
87919 }
87920
87921 function _checkTriggerAlarm(alarm) {
87922     var remainingTime, nextTriggerDate;
87923
87924     if (alarm.delay !== undefined) { // Alarm is relative
87925         if (alarm.period !== null)
87926             return false;
87927
87928         remainingTime = alarm.getRemainingSeconds();
87929         if (remainingTime === null)
87930             return true; // This alarm is triggered, remove it
87931     } else if (alarm.period !== undefined) { // Alarm is absolute,no repeat
87932         nextTriggerDate = alarm.getNextScheduledDate();
87933         if (nextTriggerDate === null)
87934             return true; // Already triggered
87935     }
87936
87937     return false; // Alarm is repeat, not expired
87938 }
87939
87940 function _convertToAlarm(alarmStore) {
87941     var alarm, frequency;
87942
87943     if (alarmStore.delay !== null) { // AlarmRelative
87944         alarm = new AlarmRelative(alarmStore.delay, alarmStore.period);
87945         alarm.date = alarmStore.date;
87946     } else { // AlarmAbsolute
87947         if (alarmStore.period !== null && alarmStore.period !== PERIOD_WEEK) {
87948             frequency = alarmStore.period;
87949         } else if (alarmStore.period === PERIOD_WEEK) {
87950             frequency = alarmStore.daysOfTheWeek;
87951         }
87952         alarm = new AlarmAbsolute(alarmStore.date, frequency);
87953     }
87954
87955     alarm.__defineGetter__("id", function () {
87956         return alarmStore.id;
87957     });
87958
87959     return alarm;
87960 }
87961
87962 function _eventCheckAlarm(id) {
87963     var alarm, diff;
87964
87965     _get();
87966     utils.forEach(_alarmStack, function (alarmStore) {
87967         if (alarmStore.id !== id)
87968             return;
87969
87970         alarm = _convertToAlarm(alarmStore);
87971         if (alarm.delay !== undefined) {
87972             diff = alarm.getRemainingSeconds();
87973             if (0 < diff && diff < 2) {
87974                 event.trigger("SendTriggerAppId", [alarmStore.applicationId]);
87975             }
87976         } else {
87977             diff = (new Date()) - alarm.getNextScheduledDate();
87978             if (-2000 < diff && diff < 2000) {
87979                 event.trigger("SendTriggerAppId", [alarmStore.applicationId]);
87980             }
87981         }
87982     });
87983 }
87984
87985
87986 _self = function () {
87987     var currentAppId, alarm;
87988
87989     alarm = {
87990         add: function (alarm, applicationId, appControl) {
87991             var id, alarmStore;
87992
87993             if (!_security.add) {
87994                 throw new WebAPIException(errorcode.SECURITY_ERR);
87995             }
87996
87997             t.AlarmManager("add", arguments);
87998
87999             alarm.__defineGetter__("id", function () {
88000                 return id;
88001             });
88002
88003             id = Math.uuid(null, 16);
88004             currentAppId = _getCurrentAppId(); // Update The Current URL.
88005             alarmStore = new AlarmStore(alarm, applicationId, currentAppId, appControl);
88006             _updateDB(alarmStore);
88007         },
88008
88009         remove: function (id) {
88010             var isFound = false, i;
88011
88012             if (!_security.remove) {
88013                 throw new WebAPIException(errorcode.SECURITY_ERR);
88014             }
88015
88016             t.AlarmManager("remove", arguments);
88017
88018             for (i in _alarmStack) {
88019                 if (_alarmStack[i].id !== id)
88020                     continue;
88021
88022                 _alarmStack.splice(i, 1);
88023                 _save();
88024                 isFound = true;
88025             }
88026
88027             if (!isFound) {
88028                 throw new WebAPIException(errorcode.NOT_FOUND_ERR);
88029             }
88030         },
88031
88032         removeAll: function () {
88033             var availableStack = [], i;
88034
88035             if (!_security.removeAll)
88036                 throw new WebAPIException(errorcode.SECURITY_ERR);
88037
88038             t.AlarmManager("removeAll", arguments);
88039
88040             for (i in _alarmStack) {
88041                 if (_alarmStack[i].currentAppId === currentAppId)
88042                     continue;
88043
88044                 availableStack.push(_alarmStack[i]);
88045             }
88046             _alarmStack = availableStack;
88047             _save();
88048         },
88049
88050         get: function (id) {
88051             var isFound = false, item, isExpired, alarm;
88052
88053             t.AlarmManager("get", arguments);
88054
88055             for (item in _alarmStack) {
88056                 if (_alarmStack[item].id === id) {
88057                     alarm = _convertToAlarm(_alarmStack[item]);
88058                     isExpired = _checkTriggerAlarm(alarm);
88059                     if (isExpired) {
88060                         _alarmStack.splice(item, 1);
88061                         _save();
88062                     } else {
88063                         isFound = true;
88064                     }
88065                     break;
88066                 }
88067             }
88068             if (!isFound) {
88069                 throw new WebAPIException(errorcode.NOT_FOUND_ERR);
88070             }
88071
88072             return alarm;
88073         },
88074
88075         getAll: function () {
88076             var availableStack = [], backAlarms = [], isExpired, alarm, i;
88077
88078             t.AlarmManager("getAll", arguments);
88079
88080             for (i in _alarmStack) {
88081                 alarm = _convertToAlarm(_alarmStack[i]); // alarmStore --> alarm
88082                 isExpired = _checkTriggerAlarm(alarm); // Check if the alarm is expired
88083                 if (isExpired)
88084                     continue;
88085
88086                 availableStack.push(_alarmStack[i]);
88087                 if (_alarmStack[i].currentAppId === currentAppId)
88088                     backAlarms.push(alarm);
88089             }
88090             _alarmStack = availableStack;
88091             _save();
88092             return backAlarms;
88093         },
88094
88095         handleSubFeatures: function (subFeatures) {
88096             var i, subFeature;
88097
88098             for (subFeature in subFeatures) {
88099                 for (i in _security[subFeature]) {
88100                     _security[_security[subFeature][i]] = true;
88101                 }
88102             }
88103         }
88104     };
88105
88106     currentAppId = _getCurrentAppId();
88107     _get();
88108
88109     alarm.__defineGetter__("PERIOD_MINUTE", function () {
88110         return PERIOD_MINUTE;
88111     });
88112
88113     alarm.__defineGetter__("PERIOD_HOUR", function () {
88114         return PERIOD_HOUR;
88115     });
88116
88117     alarm.__defineGetter__("PERIOD_DAY", function () {
88118         return PERIOD_DAY;
88119     });
88120
88121     alarm.__defineGetter__("PERIOD_WEEK", function () {
88122         return PERIOD_WEEK;
88123     });
88124
88125     return alarm;
88126 };
88127
88128 AlarmStore = function (alarmObject, applicationId, currentAppId, appControl) {
88129     var _self;
88130     _self = {
88131         id: alarmObject.id,
88132         delay: alarmObject.delay || null,
88133         date: alarmObject.date || null,
88134         period: alarmObject.period || null,
88135         daysOfTheWeek: alarmObject.daysOfTheWeek || null,
88136         applicationId: applicationId,
88137         currentAppId: currentAppId,
88138         appControl: appControl || null
88139     };
88140     return _self;
88141 };
88142
88143 event.on("CheckAlarm", function (id) {
88144     _eventCheckAlarm(id);
88145 });
88146
88147 module.exports = _self;
88148
88149 });
88150 define('ripple/platform/tizen/2.0/application', function (require, exports, module) {
88151 /*
88152  *  Copyright 2013 Intel Corporation.
88153  *
88154  * Licensed under the Apache License, Version 2.0 (the "License");
88155  * you may not use this file except in compliance with the License.
88156  * You may obtain a copy of the License at
88157  *
88158  * http://www.apache.org/licenses/LICENSE-2.0
88159  *
88160  * Unless required by applicable law or agreed to in writing, software
88161  * distributed under the License is distributed on an "AS IS" BASIS,
88162  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88163  * See the License for the specific language governing permissions and
88164  * limitations under the License.
88165  */
88166
88167 var utils = require('ripple/utils'),
88168     event = require('ripple/event'),
88169     app = require('ripple/app'),
88170     db = require('ripple/db'),
88171     t = require('ripple/platform/tizen/2.0/typecast'),
88172     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
88173     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
88174     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
88175     ApplicationControl = require('ripple/platform/tizen/2.0/ApplicationControl'),
88176     Application,
88177     ApplicationInformation,
88178     ApplicationContext,
88179     ApplicationCertificate,
88180     RequestedApplicationControl,
88181     _DB_APPLICATION_KEY = "tizen1-db-application",
88182     PSEUDO_PACKAGE_ID = "pseudopack00",
88183     PSEUDO_APP_ID = "pseudoapp00",
88184     _security = {
88185         "http://tizen.org/privilege/application.launch": ["launch", "launchAppControl"],
88186         "http://tizen.org/privilege/appmanager.kill": ["kill"],
88187         "http://tizen.org/privilege/appmanager.certificate": ["getAppCerts"]
88188     },
88189     _data = {
88190         applications : {},
88191         applicationContexts : {},
88192         activeApp : null,
88193         listeners : {}
88194     },
88195     _appDialogTemplate = jQuery("#app-dialog-template").html(),
88196     _appDialogTemplate_short = jQuery("#app-dialog2-template").html(),
88197     _appDialogTemplate_exit_hide = jQuery("#app-dialog3-template").html(),
88198     reasonable_mimetype = {
88199         "application"   : true,
88200         "text"          : true,
88201         "video"         : true,
88202         "audio"         : true,
88203         "image"         : true
88204     },
88205     _self;
88206
88207 function _setupCurrentApp() {
88208     var info, contextId, packageId, appId;
88209     info = app.getInfo();
88210     packageId = info.tizenPackageId || PSEUDO_PACKAGE_ID;
88211     appId = info.tizenAppId || PSEUDO_APP_ID;
88212     contextId = Math.uuid(null, 16);
88213     _data.applications[appId] = {
88214         id: appId,
88215         name: info.name,
88216         iconPath: info.icon,
88217         version: info.version,
88218         show: true,
88219         categories: [],
88220         installDate: new Date(),
88221         size: 1024,
88222         packageId: packageId,
88223         sharedURI: "/usr/local/share/",
88224         operation: "",
88225         appControl: {
88226             uri: "",
88227             mime: "",
88228             category: "",
88229             data: []
88230         },
88231         type: "AUTHOR_ROOT",
88232         value: ""
88233     };
88234     event.trigger("install-current-app", [_data.applications[appId]]);
88235     _data.applicationContexts[contextId] = {id: contextId, appId: appId};
88236     _data.activeApp = _data.applicationContexts[contextId];
88237 }
88238
88239 function _translate(apps) {
88240     // translate string to Date after retrieving from DB,
88241     // it is a temporary sulusion
88242     var i;
88243     for (i in apps) {
88244         if (typeof apps[i].installDate === 'string') {
88245             apps[i].installDate = new Date(apps[i].installDate);
88246         }
88247     }
88248     return apps;
88249 }
88250
88251 function _initialize() {
88252     _data = {
88253         applications : {},
88254         applicationContexts : {},
88255         activeApp : null,
88256         listeners : {}
88257     };
88258
88259     if (!db.retrieveObject(_DB_APPLICATION_KEY))
88260         return;
88261
88262     _data.applications = _translate(db.retrieveObject(_DB_APPLICATION_KEY).installedAppList);
88263     _setupCurrentApp();
88264     $("#app-dialog").dialog({
88265         resizable: false,
88266         draggable: false,
88267         modal: true,
88268         autoOpen: false,
88269         position: 'center',
88270         minWidth: '500',
88271         minHeight: '262',
88272         open: function () { $(".ui-dialog-titlebar-close", $(this).parent()).hide(); }
88273     });
88274 }
88275
88276 _self = function () {
88277     // private
88278     function getHandle() {
88279         var handle;
88280         do {
88281             handle = Math.uuid(8, 10);
88282         } while (handle.toString().indexOf('0') === 0);
88283
88284         return parseInt(handle, 10);
88285     }
88286
88287     // public
88288     function getCurrentApplication() {
88289         var application, innerApp;
88290
88291         t.ApplicationManager("getCurrentApplication", arguments);
88292
88293         /* activeApp update (by WidgetInformationUpdate event) sometime will late after user calling getCurrentApplication()
88294            for example: load other application by omnibar */
88295         if (app.getInfo().id !== _data.activeApp.appId) {
88296             _data.applications = db.retrieveObject(_DB_APPLICATION_KEY).installedAppList;
88297             utils.forEach(_data.applications, function(item) {
88298                 item.installDate = new Date(item.installDate);
88299             });
88300             _setupCurrentApp();
88301         }
88302         innerApp = _data.applications[_data.activeApp.appId];
88303         application = new Application(
88304                 new ApplicationInformation(
88305                     innerApp.id,
88306                     innerApp.name,
88307                     innerApp.iconPath,
88308                     innerApp.version,
88309                     innerApp.show,
88310                     innerApp.categories,
88311                     innerApp.installDate,
88312                     innerApp.size,
88313                     innerApp.packageId),
88314                 _data.activeApp.id, innerApp);
88315         return application;
88316     }
88317
88318     function kill(contextId, successCallback, errorCallback) {
88319         if (!_security.kill) {
88320             throw new WebAPIException(errorcode.SECURITY_ERR);
88321         }
88322
88323         t.ApplicationManager("kill", arguments);
88324
88325         window.setTimeout(function () {
88326             if (!_data.applicationContexts[contextId]) {
88327                 if (errorCallback) {
88328                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
88329                 }
88330                 return;
88331             }
88332
88333             if (_data.activeApp && (_data.activeApp.id === contextId)) {
88334                 if (errorCallback) {
88335                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
88336                 }
88337                 return;
88338             }
88339
88340             delete _data.applicationContexts[contextId];
88341             if (successCallback) {
88342                 successCallback();
88343             }
88344         }, 1);
88345     }
88346
88347     function launch(id, successCallback, errorCallback) {
88348         if (!_security.launch) {
88349             throw new WebAPIException(errorcode.SECURITY_ERR);
88350         }
88351
88352         t.ApplicationManager("launch", arguments);
88353
88354         window.setTimeout(function () {
88355             var htmlContent;
88356
88357             if (!_data.applications[id]) {
88358                 if (errorCallback) {
88359                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
88360                 }
88361                 return;
88362             }
88363
88364             htmlContent = _appDialogTemplate_short.replace(/#application-name/, _data.applications[id].name)
88365                 .replace(/#application-id/, id);
88366             jQuery("#app-dialog-box").html(htmlContent);
88367             $("#app-dialog").dialog("open");
88368
88369             if (successCallback) {
88370                 successCallback();
88371             }
88372         }, 1);
88373     }
88374
88375     function launchAppControl(appControl, id, successCallback, errorCallback, replyCallback) {
88376         if (!_security.launchAppControl) {
88377             throw new WebAPIException(errorcode.SECURITY_ERR);
88378         }
88379
88380         t.ApplicationManager("launchAppControl", arguments, true);
88381
88382         window.setTimeout(function () {
88383             var isFound = false, appId, htmlContent;
88384
88385             if (id) {
88386                 if (!_data.applications[id]) {
88387                     if (errorCallback) {
88388                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
88389                     }
88390                     return;
88391                 }
88392                 htmlContent = _appDialogTemplate.replace(/#application-name/, _data.applications[appId].name)
88393                     .replace(/#appControl-operation/, _data.applications[appId].operation)
88394                     .replace(/#appControl-uri/, _data.applications[appId].appControl.uri)
88395                     .replace(/#appControl-mime/, _data.applications[appId].appControl.mime)
88396                     .replace(/#appControl-category/, _data.applications[appId].appControl.category)
88397                     .replace(/#appControl-data/, JSON.stringify(_data.applications[appId].appControl.data));
88398                 jQuery("#app-dialog-box").html(htmlContent);
88399                 $("#app-dialog").dialog("open");
88400
88401                 _data.activeApp.replyCallback = replyCallback;
88402
88403                 if (successCallback) {
88404                     successCallback();
88405                 }
88406             } else {
88407                 utils.forEach(_data.applications, function (application) {
88408                     if (application.operation === appControl.operation) {
88409                         if (appControl.mime && (typeof appControl.mime === "string")) {
88410                             if (!reasonable_mimetype[appControl.mime.split("/")[0]]) {
88411                                 return;
88412                             }
88413                         }
88414                         appId = application.id;
88415                         isFound = true;
88416                     }
88417                 });
88418
88419                 if (!isFound) {
88420                     if (errorCallback) {
88421                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
88422                     }
88423                     return;
88424                 }
88425
88426                 htmlContent = _appDialogTemplate.replace(/#application-name/,
88427                         _data.applications[appId].name)
88428                     .replace(/#appControl-operation/, _data.applications[appId].operation)
88429                     .replace(/#appControl-uri/, _data.applications[appId].appControl.uri)
88430                     .replace(/#appControl-mime/, _data.applications[appId].appControl.mime)
88431                     .replace(/#appControl-category/, _data.applications[appId].appControl.category)
88432                     .replace(/#appControl-data/, JSON.stringify(_data.applications[appId].appControl.data));
88433                 jQuery("#app-dialog-box").html(htmlContent);
88434                 $("#app-dialog").dialog("open");
88435
88436                 _data.activeApp.replyCallback = replyCallback;
88437
88438                 if (successCallback) {
88439                     successCallback();
88440                 }
88441             }
88442         }, 1);
88443     }
88444
88445     function findAppControl(appControl, successCallback, errorCallback) {
88446         var appControlExternal = appControl;
88447
88448         t.ApplicationManager("findAppControl", arguments, true);
88449
88450         window.setTimeout(function () {
88451             var informationArray = [];
88452
88453             utils.forEach(_data.applications, function (application) {
88454                 if (application.operation === appControl.operation) {
88455                     informationArray.push(new ApplicationInformation(
88456                             application.id,
88457                             application.name,
88458                             application.iconPath,
88459                             application.version,
88460                             application.show,
88461                             application.categories,
88462                             application.installDate,
88463                             application.size,
88464                             application.packageId));
88465                 }
88466             });
88467
88468             successCallback(informationArray, appControlExternal);
88469         }, 1);
88470     }
88471
88472     function getAppsContext(successCallback, errorCallback) {
88473         t.ApplicationManager("getAppsContext", arguments);
88474
88475         window.setTimeout(function () {
88476             var contexts = [];
88477
88478             utils.forEach(_data.applicationContexts, function (context) {
88479                 contexts.push(new ApplicationContext(context.id, context.appId));
88480             });
88481
88482             successCallback(contexts);
88483         }, 1);
88484     }
88485
88486     function getAppContext(contextId) {
88487         var appContext;
88488
88489         if (contextId === null || contextId === undefined) {
88490             appContext = new ApplicationContext(_data.activeApp.id, _data.activeApp.appId);
88491             return (appContext);
88492         }
88493
88494         t.ApplicationManager("getAppContext", arguments);
88495
88496         if (_data.applicationContexts[contextId]) {
88497             appContext = new ApplicationContext(contextId, _data.applicationContexts[contextId].appId);
88498             return (appContext);
88499         }
88500         throw new WebAPIException(errorcode.NOT_FOUND_ERR);
88501     }
88502
88503     function getAppsInfo(successCallback, errorCallback) {
88504         t.ApplicationManager("getAppsInfo", arguments);
88505
88506         window.setTimeout(function () {
88507             var applications = [];
88508
88509             utils.forEach(_data.applications, function (application) {
88510                 applications.push(new ApplicationInformation(
88511                         application.id,
88512                         application.name,
88513                         application.iconPath,
88514                         application.version,
88515                         application.show,
88516                         application.categories,
88517                         application.installDate,
88518                         application.size,
88519                         application.packageId));
88520             });
88521
88522             successCallback(applications);
88523         }, 1);
88524     }
88525
88526     function getAppInfo(id) {
88527         var appId, appInfo, theApp;
88528
88529         t.ApplicationManager("getAppInfo", arguments);
88530
88531         if (arguments.length === 0) {
88532             appId = _data.activeApp.appId;
88533             theApp = _data.applications[appId];
88534
88535             appInfo = new ApplicationInformation(
88536                     theApp.id,
88537                     theApp.name,
88538                     theApp.iconPath,
88539                     theApp.version,
88540                     theApp.show,
88541                     theApp.categories,
88542                     theApp.installDate,
88543                     theApp.size,
88544                     theApp.packageId);
88545             return appInfo;
88546         }
88547
88548         if (!_data.applications[id]) {
88549             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
88550         }
88551
88552         theApp = _data.applications[id];
88553         appInfo = new ApplicationInformation(
88554                     theApp.id,
88555                     theApp.name,
88556                     theApp.iconPath,
88557                     theApp.version,
88558                     theApp.show,
88559                     theApp.categories,
88560                     theApp.installDate,
88561                     theApp.size,
88562                     theApp.packageId);
88563         return appInfo;
88564     }
88565
88566     function getAppCerts(id) {
88567         var certs = [];
88568
88569         if (!_security.getAppCerts) {
88570             throw new WebAPIException(errorcode.SECURITY_ERR);
88571         }
88572
88573         t.ApplicationManager("getAppCerts", arguments);
88574
88575         if (arguments.length === 0) {
88576             id = _data.activeApp.appId;
88577             certs.push(new ApplicationCertificate(_data.applications[id].type, _data.applications[id].value));
88578             return certs;
88579         }
88580
88581         if (!_data.applications[id]) {
88582             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
88583         }
88584         certs.push(new ApplicationCertificate(_data.applications[id].type, _data.applications[id].value));
88585         return certs;
88586     }
88587
88588     function getAppSharedURI(id) {
88589         var appId;
88590
88591         t.ApplicationManager("getAppSharedURI", arguments);
88592
88593         if (id === null || id === undefined) {
88594             appId = _data.activeApp.appId;
88595             return _data.applications[appId].sharedURI;
88596         }
88597
88598         if (!_data.applications[id]) {
88599             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
88600         }
88601
88602         return _data.applications[id].sharedURI;
88603     }
88604
88605     function addAppInfoEventListener(eventCallback) {
88606         var handle;
88607
88608         t.ApplicationManager("addAppInfoEventListener", arguments);
88609
88610         handle = getHandle();
88611         _data.listeners[handle] = eventCallback;
88612
88613         return handle;
88614     }
88615
88616     function removeAppInfoEventListener(listenerID) {
88617         if (!_data.listeners[listenerID])
88618             return;
88619
88620         delete _data.listeners[listenerID];
88621     }
88622
88623     function handleSubFeatures(subFeatures) {
88624         var i, subFeature;
88625
88626         for (subFeature in subFeatures) {
88627             for (i in _security[subFeature]) {
88628                 _security[_security[subFeature][i]] = true;
88629             }
88630         }
88631     }
88632
88633     var application = {
88634         getCurrentApplication : getCurrentApplication,
88635         kill : kill,
88636         launch : launch,
88637         launchAppControl : launchAppControl,
88638         findAppControl : findAppControl,
88639         getAppsContext : getAppsContext,
88640         getAppContext : getAppContext,
88641         getAppsInfo : getAppsInfo,
88642         getAppInfo : getAppInfo,
88643         getAppCerts : getAppCerts,
88644         getAppSharedURI: getAppSharedURI,
88645         addAppInfoEventListener : addAppInfoEventListener,
88646         removeAppInfoEventListener : removeAppInfoEventListener,
88647         handleSubFeatures : handleSubFeatures
88648     };
88649
88650     return application;
88651 };
88652
88653 Application = function (appInfo, contextId, metaData) {
88654     var application = {}, requestedAppControl;
88655
88656     application.appInfo   = appInfo;
88657     application.contextId = contextId;
88658
88659     requestedAppControl = new RequestedApplicationControl(
88660             new ApplicationControl(metaData.operation, metaData.appControl.uri,
88661                     metaData.appControl.mime, metaData.appControl.category,
88662                     metaData.appControl.data), application.appInfo.id);
88663
88664     this.__defineGetter__("appInfo", function () {
88665         return application.appInfo;
88666     });
88667
88668     this.__defineGetter__("contextId", function () {
88669         return application.contextId;
88670     });
88671
88672     this.exit = function () {
88673         event.trigger("tizen-application-exit", [contextId]);
88674     };
88675
88676     this.hide = function () {
88677         event.trigger("tizen-application-hide", [contextId]);
88678     };
88679
88680     this.getRequestedAppControl = function () {
88681         return requestedAppControl;
88682     };
88683 };
88684
88685 ApplicationInformation = function (id, name, iconPath, version, show,
88686         categories, installDate, size, packageId) {
88687     this.__defineGetter__("id", function () {
88688         return id;
88689     });
88690
88691     this.__defineGetter__("name", function () {
88692         return name;
88693     });
88694
88695     this.__defineGetter__("iconPath", function () {
88696         return iconPath;
88697     });
88698
88699     this.__defineGetter__("version", function () {
88700         return version;
88701     });
88702
88703     this.__defineGetter__("show", function () {
88704         return show;
88705     });
88706
88707     this.__defineGetter__("categories", function () {
88708         return categories;
88709     });
88710
88711     this.__defineGetter__("installDate", function () {
88712         return installDate;
88713     });
88714
88715     this.__defineGetter__("size", function () {
88716         return size;
88717     });
88718
88719     this.__defineGetter__("packageId", function () {
88720         return packageId;
88721     });
88722 };
88723
88724 ApplicationContext = function (id, appId) {
88725     this.__defineGetter__("id", function () {
88726         return id;
88727     });
88728
88729     this.__defineGetter__("appId", function () {
88730         return appId;
88731     });
88732 };
88733
88734 RequestedApplicationControl = function (appControl, callerAppId) {
88735     this.__defineGetter__("appControl", function () {
88736         return appControl;
88737     });
88738
88739     this.__defineGetter__("callerAppId", function () {
88740         return callerAppId;
88741     });
88742
88743     this.replyResult = function (data) {
88744         t.RequestedApplicationControl("replyResult", arguments);
88745
88746         event.trigger("appServiceReplied", "Result: " + data);
88747     };
88748
88749     this.replyFailure = function () {
88750         event.trigger("appServiceReplied", "Failure");
88751     };
88752 };
88753
88754 ApplicationCertificate = function (type, value) {
88755     this.__defineGetter__("type", function () {
88756         return type;
88757     });
88758
88759     this.__defineGetter__("value", function () {
88760         return value;
88761     });
88762 };
88763
88764 jQuery("#app-dialog-return-btn").live("click", function () {
88765     $("#app-dialog").dialog("close");
88766 });
88767
88768 jQuery("#app-dialog-reload-btn").live("click", function () {
88769     $("#app-dialog").dialog("close");
88770     window.tinyHipposReload = true;
88771     location.reload();
88772 });
88773
88774 jQuery("#app-dialog-generate-reply").live("click", function () {
88775     var type, data, ret = [];
88776     type = jQuery('input:radio[name="app-dialog-reply-type"]:checked').val();
88777     data = jQuery("#app-dialog-reply-json").val();
88778     $("#app-dialog").dialog("close");
88779     if (_data.activeApp.replyCallback) {
88780         switch (type) {
88781         case "replyResult":
88782             if (_data.activeApp.replyCallback.onsuccess) {
88783                 if (data === "") {
88784                     _data.activeApp.replyCallback.onsuccess();
88785                 } else {
88786                     try {
88787                         ret = JSON.parse(data);
88788                         _data.activeApp.replyCallback.onsuccess(ret);
88789                     } catch (e) {
88790                         console.log("replyResult: JSON parsing error: " + e.message);
88791                         _data.activeApp.replyCallback.onsuccess();
88792                     }
88793                 }
88794             }
88795             break;
88796         case "replyFailure":
88797             if (_data.activeApp.replyCallback.onfailure) {
88798                 _data.activeApp.replyCallback.onfailure();
88799             }
88800             break;
88801         }
88802     }
88803 });
88804
88805 event.on("ApplicationLoad", function () {
88806     _initialize();
88807 });
88808
88809 event.on("tizen-application-exit", function () {
88810     var htmlContent;
88811     htmlContent = _appDialogTemplate_exit_hide.replace(/#application-name/, _data.applications[_data.activeApp.appId].name)
88812         .replace(/#application-id/, _data.applications[_data.activeApp.appId].id)
88813         .replace(/#application-operation/g, "exit")
88814         .replace(/#application-verb/, "launch")
88815         .replace(/#next-command/g, "Launch")
88816         .replace(/#application-btn/, "app-dialog-reload-btn");
88817     jQuery("#app-dialog-box").html(htmlContent);
88818     $("#app-dialog").dialog("open");
88819 });
88820
88821 event.on("tizen-application-hide", function () {
88822     var htmlContent;
88823     htmlContent = _appDialogTemplate_exit_hide.replace(/#application-name/, _data.applications[_data.activeApp.appId].name)
88824         .replace(/#application-id/, _data.applications[_data.activeApp.appId].id)
88825         .replace(/#application-operation/g, "hide")
88826         .replace(/#application-verb/, "show")
88827         .replace(/#next-command/g, "Show")
88828         .replace(/#application-btn/, "app-dialog-return-btn");
88829     jQuery("#app-dialog-box").html(htmlContent);
88830     $("#app-dialog").dialog("open");
88831 });
88832
88833 event.on("programChanged", function (status, id) {
88834     var callback, data, innerApp;
88835     _data.applications = db.retrieveObject(_DB_APPLICATION_KEY).installedAppList;
88836     utils.forEach(_data.applications, function(item) {
88837         item.installDate = new Date(item.installDate);
88838     });
88839     _setupCurrentApp();
88840     switch (status) {
88841     case "installed":
88842     case "updated":
88843         innerApp = _data.applications[id];
88844         data = new ApplicationInformation(
88845                         innerApp.id,
88846                         innerApp.name,
88847                         innerApp.iconPath,
88848                         innerApp.version,
88849                         innerApp.show,
88850                         innerApp.categories,
88851                         innerApp.installDate,
88852                         innerApp.size,
88853                         innerApp.packageId);
88854         break;
88855     case "uninstalled":
88856         data = id;
88857         break;
88858
88859     default:
88860         return;
88861     }
88862     callback = "on" + status;
88863     utils.forEach(_data.listeners, function (listener) {
88864         listener[callback](data);
88865     });
88866 });
88867
88868 _initialize();
88869
88870 module.exports = _self;
88871
88872 });
88873 define('ripple/platform/tizen/2.0/battery', function (require, exports, module) {
88874 /*
88875  *  Copyright 2012 Intel Corporation
88876  *
88877  * Licensed under the Apache License, Version 2.0 (the "License");
88878  * you may not use this file except in compliance with the License.
88879  * You may obtain a copy of the License at
88880  *
88881  * http://www.apache.org/licenses/LICENSE-2.0
88882  *
88883  * Unless required by applicable law or agreed to in writing, software
88884  * distributed under the License is distributed on an "AS IS" BASIS,
88885  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88886  * See the License for the specific language governing permissions and
88887  * limitations under the License.
88888  */
88889
88890 var event = require('ripple/event'),
88891     utils = require('ripple/utils'),
88892     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
88893     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
88894     _data = {
88895         charging: true,
88896         chargingTime: 0,
88897         level: 1.0,
88898         dischargingTime: Infinity,
88899         chargingchange: {},
88900         chargingtimechange: {},
88901         levelchange: {},
88902         dischargingtimechange: {}
88903     },
88904     _self;
88905
88906 _self = {
88907     addEventListener: function (event, callback, capture) {
88908         if (typeof callback !== "function" || event === undefined) {
88909             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
88910         }
88911         switch (event) {
88912         case "chargingchange":
88913         case "chargingtimechange":
88914         case "levelchange":
88915         case "dischargingtimechange":
88916             var isExist = false, item;
88917             for (item in _data[event]) {
88918                 if (callback === item) {
88919                     isExist = true;
88920                     break;
88921                 }
88922             }
88923             if (!isExist) {
88924                 _data[event].add(callback);
88925             }
88926             break;
88927
88928         default:
88929             break;
88930         }
88931     },
88932
88933     removeEventListener: function (event, callback, capture) {
88934         if (typeof callback !== "function" || event === undefined) {
88935             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
88936         }
88937         _data[event].unbind(callback);
88938     },
88939
88940     dispatchEvent: function (event) {
88941         if (event === undefined) {
88942             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
88943         }
88944         return _data[event].exec(event);
88945     }
88946 };
88947
88948 _self.__defineGetter__("charging", function () {
88949     return _data.charging;
88950 });
88951
88952 _self.__defineGetter__("chargingTime", function () {
88953     return _data.chargingTime;
88954 });
88955
88956 _self.__defineGetter__("level", function () {
88957     return _data.level;
88958 });
88959
88960 _self.__defineGetter__("dischargingTime", function () {
88961     return _data.dischargingTime;
88962 });
88963
88964 function _initialize() {
88965     var callback = [];
88966
88967     function bind(name) {
88968         _self.__defineGetter__(name, function () {
88969             return callback;
88970         });
88971
88972         _self.__defineSetter__(name, function (cb) {
88973             callback = cb;
88974         });
88975
88976         return {
88977             get: function () {
88978                 return callback;
88979             },
88980
88981             set: function (value) {
88982                 callback = value;
88983             },
88984
88985             add: function (value) {
88986                 callback.push(value);
88987             },
88988
88989             exec: function (arg) {
88990                 callback.forEach(function (callback) {
88991                     return !callback || callback(arg);
88992                 });
88993             },
88994
88995             unbind: function (value) {
88996                 if (value === undefined) {
88997                     callback = [];
88998                 } else {
88999                     utils.forEach(callback, function (callback, index) {
89000                         if (callback === value) {
89001                             callback.splice(index, 1);
89002                         }
89003                     });
89004                 }
89005             }
89006         };
89007     }
89008
89009     _data.chargingchange        = bind("onchargingchange");
89010     _data.chargingtimechange    = bind("onchargingtimechange");
89011     _data.levelchange           = bind("onlevelchange");
89012     _data.dischargingtimechange = bind("ondischargingtimechange");
89013
89014     event.on("BatteryEvent", function (status) {
89015         for (var ev in status) {
89016             if ((status[ev] !== undefined) && (status[ev] !== _data[ev])) {
89017                 _data[ev] = status[ev];
89018             }
89019         }
89020         _data[status.type].exec();
89021     });
89022 }
89023
89024 _initialize();
89025
89026 module.exports = _self;
89027
89028 });
89029 define('ripple/platform/tizen/2.0/bluetooth', function (require, exports, module) {
89030 /*
89031  *  Copyright 2013 Intel Corporation.
89032  *
89033  * Licensed under the Apache License, Version 2.0 (the "License");
89034  * you may not use this file except in compliance with the License.
89035  * You may obtain a copy of the License at
89036  *
89037  * http://www.apache.org/licenses/LICENSE-2.0
89038  *
89039  * Unless required by applicable law or agreed to in writing, software
89040  * distributed under the License is distributed on an "AS IS" BASIS,
89041  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
89042  * See the License for the specific language governing permissions and
89043  * limitations under the License.
89044  */
89045
89046 var utils = require('ripple/utils'),
89047     db = require('ripple/db'),
89048     event = require('ripple/event'),
89049     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
89050     t = require('ripple/platform/tizen/2.0/typecast'),
89051     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
89052     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
89053     BluetoothDevice = require('ripple/platform/tizen/2.0/BluetoothDevice'),
89054     BluetoothClassDeviceMajor = require('ripple/platform/tizen/2.0/BluetoothClassDeviceMajor'),
89055     BluetoothClassDeviceMinor = require('ripple/platform/tizen/2.0/BluetoothClassDeviceMinor'),
89056     BluetoothClassDeviceService = require('ripple/platform/tizen/2.0/BluetoothClassDeviceService'),
89057     BluetoothServiceHandler = require('ripple/platform/tizen/2.0/BluetoothServiceHandler'),
89058     BluetoothAdapter,
89059     _data = {
89060         DB_BLUETOOTH_KEY: "tizen1-db-bluetooth_adapter-name",
89061         DEFAULT_ADAPTER_NAME: "Tizen BT Adapter",
89062         DEFAULT_ADAPTER_ADDRESS: "12:34:56:78:90:AB",
89063         availableDevsChanging: false,
89064         DEFAULT_VISIBLE_TIME: 180000,
89065         DISCOVER_TIME: 10000,
89066         DISCOVER_INTERVAL: 1000,
89067         bluetoothClassDeviceMajor: {},
89068         bluetoothClassDeviceMinor: {},
89069         bluetoothClassDeviceService: {},
89070         adapter: {},
89071         historyDevs: {},
89072         availableDevs: {},
89073         localServices: {}
89074     },
89075     _security = {
89076         "http://tizen.org/privilege/bluetoothmanager": ["setVisible"],
89077         "http://tizen.org/privilege/bluetooth.admin": ["setName", "setPowered"],
89078         "http://tizen.org/privilege/bluetooth.gap": ["getDefaultAdapter",
89079                 "discoverDevices", "stopDiscovery", "getKnownDevices",
89080                 "getDevice", "createBonding", "destroyBonding", "hasService"],
89081         "http://tizen.org/privilege/bluetooth.spp":
89082                 ["registerRFCOMMServiceByUUID", "connectToServiceByUUID",
89083                 "writeData", "readData", "close", "unregister"]
89084     },
89085     _self;
89086
89087 function _initialize() {
89088     var adapterName, devs;
89089
89090     _data.bluetoothClassDeviceMajor = new BluetoothClassDeviceMajor();
89091     _data.bluetoothClassDeviceMinor = new BluetoothClassDeviceMinor();
89092     _data.bluetoothClassDeviceService = new BluetoothClassDeviceService();
89093     adapterName = db.retrieveObject(_data.DB_BLUETOOTH_KEY) ||
89094             _data.DEFAULT_ADAPTER_NAME;
89095     _data.adapter = new BluetoothAdapter(adapterName,
89096             _data.DEFAULT_ADAPTER_ADDRESS);
89097
89098     // get defalt nearby devices
89099     devs = db.retrieveObject("bt-simulated-devices");
89100     utils.forEach(devs, function (item) {
89101         if (!_data.availableDevs[item.address]) {
89102             _data.availableDevs[item.address] = new BluetoothDevice({
89103                 name: item.name,
89104                 address: item.address,
89105                 deviceClass: item.deviceClass,
89106                 isBonded: false,
89107                 isTrusted: item.isTrusted,
89108                 isConnected: false,
89109                 services: item.services,
89110                 metaData: _security
89111             });
89112         }
89113     });
89114 }
89115
89116 BluetoothAdapter = function (devName, devAddress) {
89117     var adapter,
89118         timeoutVar,
89119         _devName = devName,
89120         _devAddress = devAddress,
89121         _devPowered = false,
89122         _devVisible = false,
89123         _isDiscovering = false,
89124         discoverInterval;
89125
89126     // private
89127     function updateVisibleStatus(status, time) {
89128         if (!_devPowered)
89129             return;
89130
89131         _devVisible = status;
89132         event.trigger("bt-adapter-visible-changed", [_devVisible]);
89133         if (_devVisible) {
89134             if (time > 0) {
89135                 timeoutVar = window.setTimeout(function () {
89136                     _devVisible = false;
89137                     event.trigger("bt-adapter-visible-changed", [_devVisible]);
89138                 }, time);
89139             }
89140         } else {
89141             window.clearTimeout(timeoutVar);
89142         }
89143     }
89144
89145     function updatePowerStatus(status) {
89146         if (_devPowered === status) {
89147             return;
89148         }
89149         if (!status) {
89150             updateVisibleStatus(false);
89151             utils.forEach(_data.historyDevs, function (dev) {
89152                 event.trigger("bt-service-state-update", [dev.address, false]);
89153                 dev.__defineGetter__("isBonded", function () {
89154                     return false;
89155                 });
89156                 event.trigger("bt-device-bonded-changed", [dev.address, false]);
89157                 jQuery("#service-transfer-textarea-" + dev.address.replace(/:/g, "")).val("");
89158                 jQuery("#service-receive-textarea-" + dev.address.replace(/:/g, "")).html("");
89159             });
89160         }
89161         _devPowered = status;
89162         event.trigger("bt-adapter-power-changed", [_devPowered]);
89163     }
89164
89165     // public
89166     function setName(name, successCallback, errorCallback) {
89167         if (!_security.setName) {
89168             throw new WebAPIException(errorcode.SECURITY_ERR);
89169         }
89170
89171         t.BluetoothAdapter("setName", arguments);
89172
89173         window.setTimeout(function () {
89174             if (!_devPowered) {
89175                 if (errorCallback) {
89176                     errorCallback(new WebAPIError(
89177                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
89178                 }
89179                 return;
89180             }
89181
89182             _devName = name;
89183             db.saveObject(_data.DB_BLUETOOTH_KEY, _devName);
89184             event.trigger("bt-adapter-name-changed", [_devName]);
89185             if (successCallback) {
89186                 successCallback();
89187             }
89188         }, 1);
89189     }
89190
89191     function setPowered(state, successCallback, errorCallback) {
89192         if (!_security.setPowered) {
89193             throw new WebAPIException(errorcode.SECURITY_ERR);
89194         }
89195
89196         t.BluetoothAdapter("setPowered", arguments);
89197
89198         window.setTimeout(function () {
89199             updatePowerStatus(state);
89200             if (successCallback) {
89201                 successCallback();
89202             }
89203         }, 1);
89204     }
89205
89206     function setVisible(mode, successCallback, errorCallback, timeout) {
89207         if (!_security.setVisible) {
89208             throw new WebAPIException(errorcode.SECURITY_ERR);
89209         }
89210
89211         t.BluetoothAdapter("setVisible", arguments);
89212
89213         window.setTimeout(function () {
89214             var time;
89215
89216             if (!_devPowered) {
89217                 if (errorCallback) {
89218                     errorCallback(new WebAPIError(
89219                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
89220                 }
89221                 return;
89222             }
89223
89224             if (typeof timeout === "number") {
89225                 if (timeout < 0) {
89226                     time = _data.DEFAULT_VISIBLE_TIME;
89227                 } else {
89228                     time = timeout * 1000;
89229                 }
89230             } else {
89231                 time = _data.DEFAULT_VISIBLE_TIME;
89232             }
89233             updateVisibleStatus(mode, time);
89234
89235             if (successCallback) {
89236                 successCallback();
89237             }
89238         }, 1);
89239     }
89240
89241     function discoverDevices(successCallback, errorCallback) {
89242         if (!_security.discoverDevices) {
89243             throw new WebAPIException(errorcode.SECURITY_ERR);
89244         }
89245
89246         t.BluetoothAdapter("discoverDevices", arguments);
89247
89248         window.setTimeout(function () {
89249             var interval;
89250
89251             if (!_devPowered) {
89252                 if (errorCallback) {
89253                     errorCallback(new WebAPIError(
89254                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
89255                 }
89256                 return;
89257             }
89258
89259             // already discovering
89260             if (_isDiscovering) {
89261                 return;
89262             }
89263
89264             _isDiscovering = true;
89265             _data.historyDevs = {};
89266
89267             successCallback.onstarted();
89268
89269             _data.availableDevsChanging = false;
89270             utils.forEach(_data.availableDevs, function (item) {
89271                 _data.historyDevs[item.address] = item;
89272                 successCallback.ondevicefound(item);
89273             });
89274
89275             discoverInterval = window.setTimeout(function () {
89276                 var devs = [];
89277
89278                 window.clearInterval(interval);
89279                 utils.forEach(_data.historyDevs, function (item) {
89280                     devs.push(item);
89281                 });
89282                 successCallback.onfinished(devs);
89283                 _isDiscovering = false;
89284             }, _data.DISCOVER_TIME);
89285
89286             interval = window.setInterval(function () {
89287                 var removeList = [], i;
89288
89289                 if (!_isDiscovering) {
89290                     window.clearInterval(interval);
89291                     return;
89292                 }
89293
89294                 if (_data.availableDevsChanging) {
89295                     _data.availableDevsChanging = false;
89296                     utils.forEach(_data.historyDevs, function (item) {
89297                         if (!_data.availableDevs[item.address]) {
89298                             removeList.push(item.address);
89299                         }
89300                     });
89301                     for (i in removeList) {
89302                         successCallback.ondevicedisappeared(removeList[i]);
89303                         delete _data.historyDevs[removeList[i]];
89304                     }
89305                     utils.forEach(_data.availableDevs, function (item) {
89306                         if (!_data.historyDevs[item.address]) {
89307                             _data.historyDevs[item.address] = item;
89308                             successCallback.ondevicefound(item);
89309                         }
89310                     });
89311                 }
89312             }, _data.DISCOVER_INTERVAL);
89313         }, 1);
89314     }
89315
89316     function stopDiscovery(successCallback, errorCallback) {
89317         if (!_security.stopDiscovery) {
89318             throw new WebAPIException(errorcode.SECURITY_ERR);
89319         }
89320
89321         t.BluetoothAdapter("stopDiscovery", arguments);
89322
89323         window.setTimeout(function () {
89324             if (!_devPowered) {
89325                 if (errorCallback) {
89326                     errorCallback(new WebAPIError(
89327                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
89328                 }
89329                 return;
89330             }
89331
89332             if (_isDiscovering) {
89333                 window.clearTimeout(discoverInterval);
89334             }
89335             _isDiscovering = false;
89336             if (successCallback) {
89337                 successCallback();
89338             }
89339         }, 1);
89340     }
89341
89342     function getKnownDevices(successCallback, errorCallback) {
89343         if (!_security.getKnownDevices) {
89344             throw new WebAPIException(errorcode.SECURITY_ERR);
89345         }
89346
89347         t.BluetoothAdapter("getKnownDevices", arguments);
89348
89349         window.setTimeout(function () {
89350             var devs = [];
89351
89352             if (!_devPowered) {
89353                 if (errorCallback) {
89354                     errorCallback(new WebAPIError(
89355                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
89356                 }
89357                 return;
89358             }
89359             utils.forEach(_data.historyDevs, function (item) {
89360                 devs.push(new BluetoothDevice({
89361                     name: item.name,
89362                     address: item.address,
89363                     deviceClass: item.deviceClass,
89364                     isBonded: false,
89365                     isTrusted: item.isTrusted,
89366                     isConnected: false,
89367                     services: item.services,
89368                     metaData: _security
89369                 }));
89370             });
89371             successCallback(devs);
89372         }, 1);
89373     }
89374
89375     function getDevice(address, successCallback, errorCallback) {
89376         if (!_security.getDevice) {
89377             throw new WebAPIException(errorcode.SECURITY_ERR);
89378         }
89379
89380         t.BluetoothAdapter("getDevice", arguments);
89381
89382         window.setTimeout(function () {
89383             if (!_devPowered) {
89384                 if (errorCallback) {
89385                     errorCallback(new WebAPIError(
89386                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
89387                 }
89388                 return;
89389             }
89390
89391             if (!_data.historyDevs[address]) {
89392                 if (!_data.availableDevs[address]) {
89393                     if (errorCallback) {
89394                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
89395                     }
89396                     return;
89397                 }
89398                 _data.historyDevs[address] = _data.availableDevs[address];
89399             }
89400
89401             successCallback(_data.historyDevs[address]);
89402         }, 1);
89403     }
89404
89405     function createBonding(address, successCallback, errorCallback) {
89406         if (!_security.createBonding) {
89407             throw new WebAPIException(errorcode.SECURITY_ERR);
89408         }
89409
89410         t.BluetoothAdapter("createBonding", arguments);
89411
89412         window.setTimeout(function () {
89413             if (!_devPowered) {
89414                 if (errorCallback) {
89415                     errorCallback(new WebAPIError(
89416                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
89417                 }
89418                 return;
89419             }
89420
89421             if (!_data.historyDevs[address]) {
89422                 if (!_data.availableDevs[address]) {
89423                     if (errorCallback) {
89424                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
89425                     }
89426                     return;
89427                 }
89428                 _data.historyDevs[address] = _data.availableDevs[address];
89429             }
89430
89431             _data.historyDevs[address].__defineGetter__("isBonded", function () {
89432                 return true;
89433             });
89434             event.trigger("bt-device-bonded-changed", [address, true]);
89435             successCallback(_data.historyDevs[address]);
89436         }, 1);
89437     }
89438
89439     function destroyBonding(address, successCallback, errorCallback) {
89440         if (!_security.destroyBonding) {
89441             throw new WebAPIException(errorcode.SECURITY_ERR);
89442         }
89443
89444         t.BluetoothAdapter("destroyBonding", arguments);
89445
89446         window.setTimeout(function () {
89447             if (!_devPowered) {
89448                 if (errorCallback) {
89449                     errorCallback(new WebAPIError(
89450                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
89451                 }
89452                 return;
89453             }
89454
89455             if (!_data.historyDevs[address]) {
89456                 if (!_data.availableDevs[address]) {
89457                     if (errorCallback) {
89458                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
89459                     }
89460                     return;
89461                 }
89462                 _data.historyDevs[address] = _data.availableDevs[address];
89463             }
89464
89465             event.trigger("bt-service-state-update", [address, false]);
89466             _data.historyDevs[address].__defineGetter__("isBonded", function () {
89467                 return false;
89468             });
89469             event.trigger("bt-device-bonded-changed", [address, false]);
89470             if (successCallback) {
89471                 successCallback();
89472             }
89473         }, 1);
89474     }
89475
89476     function registerRFCOMMServiceByUUID(uuid, name, successCallback,
89477             errorCallback, securityLevel) {
89478         if (!_security.registerRFCOMMServiceByUUID) {
89479             throw new WebAPIException(errorcode.SECURITY_ERR);
89480         }
89481
89482         t.BluetoothAdapter("registerRFCOMMServiceByUUID", arguments);
89483
89484         window.setTimeout(function () {
89485             if (!_devPowered) {
89486                 if (errorCallback) {
89487                     errorCallback(new WebAPIError(
89488                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
89489                 }
89490                 return;
89491             }
89492
89493             _data.localServices[uuid] = new BluetoothServiceHandler({
89494                 uuid: uuid,
89495                 name: name,
89496                 isConnected: false,
89497                 metaData: _security
89498             });
89499             successCallback(_data.localServices[uuid]);
89500         }, 1);
89501     }
89502
89503     event.on("bt-simulated-devices-changed", function () {
89504         var devs = db.retrieveObject("bt-simulated-devices");
89505         utils.forEach(_data.availableDevs, function (item) {
89506             if (!devs[item.address]) {
89507                 delete _data.availableDevs[item.address];
89508             }
89509         });
89510         utils.forEach(devs, function (item) {
89511             if (!_data.availableDevs[item.address]) {
89512                 _data.availableDevs[item.address] = new BluetoothDevice({
89513                     name: item.name,
89514                     address: item.address,
89515                     deviceClass: item.deviceClass,
89516                     isBonded: false,
89517                     isTrusted: item.isTrusted,
89518                     isConnected: false,
89519                     services: item.services,
89520                     metaData: _security
89521                 });
89522             }
89523         });
89524         _data.availableDevsChanging = true;
89525     });
89526
89527     event.on("bt-unregister-service", function (uuid, successCallback, errorCallback) {
89528         if (!_data.localServices[uuid]) {
89529             if (errorCallback) {
89530                 errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
89531             }
89532             return;
89533         }
89534         delete _data.localServices[uuid];
89535         if (successCallback) {
89536             successCallback();
89537         }
89538     });
89539
89540     event.on("bt-power-setting", function (status) {
89541         updatePowerStatus(status);
89542     });
89543
89544     adapter = {
89545         setName:                     setName,
89546         setPowered:                  setPowered,
89547         setVisible:                  setVisible,
89548         discoverDevices:             discoverDevices,
89549         stopDiscovery:               stopDiscovery,
89550         getKnownDevices:             getKnownDevices,
89551         getDevice:                   getDevice,
89552         createBonding:               createBonding,
89553         destroyBonding:              destroyBonding,
89554         registerRFCOMMServiceByUUID: registerRFCOMMServiceByUUID
89555     };
89556
89557     adapter.__defineGetter__("name", function () {
89558         return _devName;
89559     });
89560
89561     adapter.__defineGetter__("address", function () {
89562         return _devAddress;
89563     });
89564
89565     adapter.__defineGetter__("powered", function () {
89566         return _devPowered;
89567     });
89568
89569     adapter.__defineGetter__("visible", function () {
89570         return _devVisible;
89571     });
89572
89573     return adapter;
89574 };
89575
89576 _self = function () {
89577     var bluetooth;
89578
89579     function getDefaultAdapter() {
89580         if (!_security.getDefaultAdapter) {
89581             throw new WebAPIException(errorcode.SECURITY_ERR);
89582         }
89583
89584         if (!_data.adapter) {
89585             throw new WebAPIException(errorcode.UNKNOWN_ERR);
89586         }
89587
89588         return _data.adapter;
89589     }
89590
89591     function handleSubFeatures(subFeatures) {
89592         var i, subFeature;
89593
89594         for (subFeature in subFeatures) {
89595             for (i in _security[subFeature]) {
89596                 _security[_security[subFeature][i]] = true;
89597             }
89598         }
89599     }
89600
89601     bluetooth = {
89602         getDefaultAdapter: getDefaultAdapter,
89603         handleSubFeatures: handleSubFeatures
89604     };
89605
89606     bluetooth.__defineGetter__("deviceMajor", function () {
89607         return _data.bluetoothClassDeviceMajor;
89608     });
89609
89610     bluetooth.__defineGetter__("deviceMinor", function () {
89611         return _data.bluetoothClassDeviceMinor;
89612     });
89613
89614     bluetooth.__defineGetter__("deviceService", function () {
89615         return _data.bluetoothClassDeviceService;
89616     });
89617
89618     return bluetooth;
89619 };
89620
89621 _initialize();
89622
89623 module.exports = _self;
89624
89625 });
89626 define('ripple/platform/tizen/2.0/bookmark', function (require, exports, module) {
89627 /*
89628  *  Copyright 2013 Intel Corporation.
89629  *
89630  * Licensed under the Apache License, Version 2.0 (the "License");
89631  * you may not use this file except in compliance with the License.
89632  * You may obtain a copy of the License at
89633  *
89634  * http://www.apache.org/licenses/LICENSE-2.0
89635  *
89636  * Unless required by applicable law or agreed to in writing, software
89637  * distributed under the License is distributed on an "AS IS" BASIS,
89638  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
89639  * See the License for the specific language governing permissions and
89640  * limitations under the License.
89641  */
89642
89643 var db = require('ripple/db'),
89644     utils = require('ripple/utils'),
89645     t = require('ripple/platform/tizen/2.0/typecast'),
89646     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
89647     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
89648     BookmarkFolder = require('ripple/platform/tizen/2.0/BookmarkFolder'),
89649     BookmarkItem = require('ripple/platform/tizen/2.0/BookmarkItem'),
89650     BookmarkExternal,
89651     BookmarkInternal,
89652     BookmarkStorage,
89653     _data = {
89654         DB_BOOKMARK_KEY: "tizen1-bookmark",
89655         bookmarks:       [],
89656         dbStorage:       []
89657     },
89658     _security = {
89659         "http://tizen.org/privilege/bookmark.read": ["get"],
89660         "http://tizen.org/privilege/bookmark.write": ["add", "remove"]
89661     },
89662     _self;
89663
89664 function _get() {
89665     _data.dbStorage = db.retrieveObject(_data.DB_BOOKMARK_KEY) || [];
89666 }
89667
89668 function _save() {
89669     db.saveObject(_data.DB_BOOKMARK_KEY, _data.dbStorage);
89670 }
89671
89672 function _initialize() {
89673     _get();
89674
89675     utils.forEach(_data.dbStorage, function (bookmark) {
89676         _data.bookmarks.push(new BookmarkInternal(bookmark, null));
89677     });
89678 }
89679
89680 function _persist() {
89681     _data.dbStorage = [];
89682
89683     utils.forEach(_data.bookmarks, function (bookmark) {
89684         _data.dbStorage.push(new BookmarkStorage(bookmark));
89685     });
89686
89687     _save();
89688 }
89689
89690 function _isFolder(bookmark) {
89691     return !bookmark.url;
89692 }
89693
89694 function _isExternal(bookmark) {
89695     return !("children" in bookmark);
89696 }
89697
89698 function _getChildren(bookmark, BookmarkType, parent) {
89699     var i, children = [];
89700
89701     if (!_isExternal(bookmark)) {
89702         for (i in bookmark.children) {
89703             children.push(new BookmarkType(bookmark.children[i], parent));
89704         }
89705     }
89706
89707     return children;
89708 }
89709
89710 _self = function () {
89711     var bookmark;
89712
89713     // private
89714     /*
89715      * map
89716      *    Map the external bookmark to the internal one in the tree
89717      *
89718      * bookmarkExternal
89719      *    External bookmark Object
89720      *
89721      * callback
89722      *    callback(index, peers). Optional.
89723      *
89724      *          Root    Bookmark        Not Found
89725      * ------------------------------------------
89726      *  index   0       index           -1
89727      *  peers   null    peers           null
89728      *
89729      * Return   null    peers[index]    undefined
89730      */
89731
89732     function map(bookmarkExternal, callback) {
89733         var trace = [], it, i, peers = null;
89734
89735         if (!bookmarkExternal) {
89736             if (callback) {
89737                 callback(0, null);
89738             }
89739             return null;
89740         }
89741
89742         for (it = bookmarkExternal; it; it = it.parent) {
89743             trace.push(it);
89744         }
89745
89746         for (it = _data.bookmarks; trace.length !== 0; it = it[i].children) {
89747             bookmarkExternal = trace.pop();
89748             peers = null;
89749
89750             if (it.length === 0)
89751                 break;
89752
89753             for (i in it) {
89754                 if (it[i].external === bookmarkExternal) {
89755                     peers = it;
89756                     break;
89757                 }
89758             }
89759         }
89760
89761         if (callback) {
89762             return callback((peers !== null) ? i : -1, peers);
89763         }
89764
89765         return (peers !== null) ? peers[i] : undefined;
89766     }
89767
89768     function traverse(bookmarks, trace, level) {
89769         for (var i in bookmarks) {
89770             trace.push(bookmarks[i].external);
89771             if ((level !== 0) && bookmarks[i].children) {
89772                 traverse(bookmarks[i].children, trace, --level);
89773             }
89774         }
89775     }
89776
89777     function findUrl(bookmarks, url) {
89778         var i, isFound = false;
89779
89780         for (i in bookmarks) {
89781             if (_isFolder(bookmarks[i])) {
89782                 isFound = findUrl(bookmarks[i].children, url);
89783             } else {
89784                 isFound = (bookmarks[i].url === url);
89785             }
89786
89787             if (isFound)
89788                 break;
89789         }
89790
89791         return isFound;
89792     }
89793
89794     function isExisting(bookmark, peers) {
89795         var i;
89796
89797         if (!_isFolder(bookmark)) {
89798             return findUrl(_data.bookmarks, bookmark.url);
89799         }
89800
89801         for (i in peers) {
89802             if (_isFolder(peers[i]) && (peers[i].title === bookmark.title)) {
89803                 return true;
89804             }
89805         }
89806
89807         return false;
89808     }
89809
89810     // public
89811     function get(parentFolder, recursive) {
89812         var bookmarks = [], parent, peers;
89813
89814         if (!_security.get) {
89815             throw new WebAPIException(errorcode.SECURITY_ERR);
89816         }
89817
89818         t.BookmarkManager("get", arguments);
89819
89820         parent = map(parentFolder);
89821         if ((parent === undefined) || (parent && !_isFolder(parent))) {
89822             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
89823         }
89824         peers = parent ? parent.children : _data.bookmarks;
89825         traverse(peers, bookmarks, recursive ? -1 : 0);
89826
89827         return bookmarks;
89828     }
89829
89830     function add(bookmark, parentFolder) {
89831         var parent, peers;
89832
89833         if (!_security.add) {
89834             throw new WebAPIException(errorcode.SECURITY_ERR);
89835         }
89836
89837         t.BookmarkManager("add", arguments);
89838
89839         parent = map(parentFolder);
89840         if ((parent === undefined) || (parent && !_isFolder(parent))) {
89841             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
89842         }
89843         peers = parent ? parent.children : _data.bookmarks;
89844         if (isExisting(bookmark, peers)) {
89845             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
89846         }
89847
89848         peers.push(new BookmarkInternal(bookmark));
89849
89850         _persist();
89851
89852         bookmark.__defineGetter__("parent", function () {
89853             return parent ? parent.external : null;
89854         });
89855     }
89856
89857     function remove(bookmark) {
89858         if (!_security.remove) {
89859             throw new WebAPIException(errorcode.SECURITY_ERR);
89860         }
89861
89862         t.BookmarkManager("remove", arguments);
89863
89864         if (!bookmark) {
89865             _data.bookmarks = [];
89866         } else {
89867             map(bookmark, function (index, peers) {
89868                 if (index === -1) {
89869                     throw new WebAPIException(errorcode.NOT_FOUND_ERR);
89870                 }
89871                 peers.splice(index, 1);
89872             });
89873
89874             bookmark.__defineGetter__("parent", function () {
89875                 return undefined;
89876             });
89877         }
89878
89879         _persist();
89880     }
89881
89882     function handleSubFeatures(subFeatures) {
89883         var i, subFeature;
89884
89885         for (subFeature in subFeatures) {
89886             for (i in _security[subFeature]) {
89887                 _security[_security[subFeature][i]] = true;
89888             }
89889         }
89890     }
89891
89892     bookmark = {
89893         get:               get,
89894         add:               add,
89895         remove:            remove,
89896         handleSubFeatures: handleSubFeatures
89897     };
89898
89899     return bookmark;
89900 };
89901
89902 /*
89903  * BookmarkInternal     BookmarkStorage     BookmarkExternal
89904  * ---------------------------------------------------------
89905  * title                title               title
89906  * url                  url                 url/-
89907  * children             children            -
89908  * external             -                   -
89909  * -                    -                   parent
89910  */
89911
89912 BookmarkInternal = function (bookmark, parent) {
89913     this.title    = bookmark.title;
89914     this.url      = _isFolder(bookmark) ? null : bookmark.url;
89915     this.children = _isFolder(bookmark) ?
89916         _getChildren(bookmark, BookmarkInternal, this) : null;
89917     this.external = _isExternal(bookmark) ? bookmark :
89918         new BookmarkExternal(bookmark, parent);
89919 };
89920
89921 BookmarkStorage = function (bookmark) {
89922     this.title    = bookmark.title;
89923     this.url      = _isFolder(bookmark) ? null : bookmark.url;
89924     this.children = _isFolder(bookmark) ?
89925         _getChildren(bookmark, BookmarkStorage) : null;
89926 };
89927
89928 BookmarkExternal = function (bookmark, parent) {
89929     var self;
89930
89931     if (_isFolder(bookmark)) {
89932         self = new BookmarkFolder(bookmark.title);
89933     } else {
89934         self = new BookmarkItem(bookmark.title, bookmark.url);
89935     }
89936
89937     self.__defineGetter__("parent", function () {
89938         return parent ? parent.external : null;
89939     });
89940
89941     return self;
89942 };
89943
89944 _initialize();
89945
89946 module.exports = _self;
89947
89948 });
89949 define('ripple/platform/tizen/2.0/calendar', function (require, exports, module) {
89950 /*
89951  *  Copyright 2013 Intel Corporation.
89952  *
89953  * Licensed under the Apache License, Version 2.0 (the "License");
89954  * you may not use this file except in compliance with the License.
89955  * You may obtain a copy of the License at
89956  *
89957  * http://www.apache.org/licenses/LICENSE-2.0
89958  *
89959  * Unless required by applicable law or agreed to in writing, software
89960  * distributed under the License is distributed on an "AS IS" BASIS,
89961  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
89962  * See the License for the specific language governing permissions and
89963  * limitations under the License.
89964  */
89965
89966 var utils = require('ripple/utils'),
89967     db = require('ripple/db'),
89968     t = require('ripple/platform/tizen/2.0/typecast'),
89969     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
89970     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
89971     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
89972     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
89973     TZDate = require('ripple/platform/tizen/2.0/TZDate'),
89974     TDur = require('ripple/platform/tizen/2.0/TimeDuration'),
89975     CalendarItem = require('ripple/platform/tizen/2.0/CalendarItem'),
89976     CalendarEvent = require('ripple/platform/tizen/2.0/CalendarEvent'),
89977     CalendarEventId = require('ripple/platform/tizen/2.0/CalendarEventId'),
89978     CalendarTask = require('ripple/platform/tizen/2.0/CalendarTask'),
89979     Calendar,
89980     CalendarStorage,
89981     CalendarItemsStorage,
89982     _DB_CALENDARS_KEY = "tizen1-db-calendars",
89983     _watchers = [],
89984     _calendars = {
89985         EVENT: {},
89986         TASK: {}
89987     },
89988     _calendarsStorage,
89989     _security = {
89990         "http://tizen.org/privilege/calendar.read": ["getCalendars",
89991                 "getUnifiedCalendar", "getDefaultCalendar", "getCalendar",
89992                 "get", "find", "addChangeListener", "removeChangeListener",
89993                 "expandRecurrence", "convertToString", "clone"],
89994         "http://tizen.org/privilege/calendar.write": ["add", "addBatch",
89995                 "update", "updateBatch", "remove", "removeBatch"]
89996     },
89997     _self;
89998
89999 function _isValidId(id) {
90000     return (/[a-z]|[A-Z]|[0-9]|[\-]/).test(id);
90001 }
90002
90003 function retrieveCalendars() {
90004     _calendarsStorage = db.retrieveObject(_DB_CALENDARS_KEY) || {EVENT: {}, TASK: {}};
90005 }
90006
90007 function saveCalendars() {
90008     db.saveObject(_DB_CALENDARS_KEY, _calendarsStorage);
90009 }
90010
90011 _self = function () {
90012     var calendarManager;
90013
90014     // private
90015     function loadCalendars(type) {
90016         var calsStorage, defCalendar, id, i, item;
90017
90018         retrieveCalendars();
90019         calsStorage = _calendarsStorage[type];
90020
90021         if (tizen1_utils.isEmptyObject(calsStorage)) {
90022             defCalendar = new Calendar(type, "Default " + type.toLowerCase() + " calendar");
90023
90024             _calendars[type][defCalendar.id] = defCalendar;
90025             calsStorage[defCalendar.id] = new CalendarStorage(defCalendar);
90026         } else {
90027             for (id in calsStorage) {
90028                 for (i in calsStorage[id].items) {
90029                     item = calsStorage[id].items[i];
90030                 }
90031                 _calendars[type][id] = new Calendar(type, calsStorage[id].name,
90032                         calsStorage[id].items, id);
90033             }
90034         }
90035     }
90036
90037     // public
90038     function getCalendars(type, successCallback, errorCallback) {
90039         if (!_security.getCalendars) {
90040             throw new WebAPIException(errorcode.SECURITY_ERR);
90041         }
90042
90043         t.CalendarManager("getCalendars", arguments);
90044
90045         window.setTimeout(function () {
90046             var i, result = [];
90047
90048             if (tizen1_utils.isEmptyObject(_calendars[type])) {
90049                 loadCalendars(type);
90050             }
90051
90052             if (_calendars.length !== 0) {
90053                 for (i in _calendars[type]) {
90054                     result.push(_calendars[type][i]);
90055                 }
90056                 successCallback(result);
90057             } else if (errorCallback) {
90058                 errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
90059             }
90060         }, 1);
90061     }
90062
90063     function getUnifiedCalendar(type) {
90064         var id, calendar;
90065
90066         if (!_security.getUnifiedCalendar) {
90067             throw new WebAPIException(errorcode.SECURITY_ERR);
90068         }
90069
90070         t.CalendarManager("getUnifiedCalendar", arguments);
90071
90072         if (tizen1_utils.isEmptyObject(_calendars[type])) {
90073             loadCalendars(type);
90074         }
90075
90076         for (id in _calendars[type]) {
90077             calendar = _calendars[type][id];
90078             break;
90079         }
90080
90081         if (calendar === undefined)
90082             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
90083
90084         return calendar;
90085     }
90086
90087     function getDefaultCalendar(type) {
90088         var id, calendar;
90089
90090         if (!_security.getDefaultCalendar) {
90091             throw new WebAPIException(errorcode.SECURITY_ERR);
90092         }
90093
90094         t.CalendarManager("getDefaultCalendar", arguments);
90095
90096         if (tizen1_utils.isEmptyObject(_calendars[type])) {
90097             loadCalendars(type);
90098         }
90099
90100         for (id in _calendars[type]) {
90101             calendar = _calendars[type][id];
90102             break;
90103         }
90104
90105         if (calendar === undefined)
90106             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
90107
90108         return calendar;
90109     }
90110
90111     function getCalendar(type, id) {
90112         var calendar;
90113
90114         if (!_security.getCalendar) {
90115             throw new WebAPIException(errorcode.SECURITY_ERR);
90116         }
90117
90118         t.CalendarManager("getCalendar", arguments);
90119
90120         if (tizen1_utils.isEmptyObject(_calendars[type])) {
90121             loadCalendars(type);
90122         }
90123
90124         calendar = _calendars[type][id];
90125         if (calendar === undefined)
90126             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
90127
90128         return calendar;
90129     }
90130
90131     function handleSubFeatures(subFeatures) {
90132         var i, subFeature;
90133
90134         for (subFeature in subFeatures) {
90135             for (i in _security[subFeature]) {
90136                 _security[_security[subFeature][i]] = true;
90137             }
90138         }
90139     }
90140
90141     calendarManager = {
90142         getCalendars:       getCalendars,
90143         getUnifiedCalendar: getUnifiedCalendar,
90144         getDefaultCalendar: getDefaultCalendar,
90145         getCalendar:        getCalendar,
90146         handleSubFeatures:  handleSubFeatures
90147     };
90148
90149     return calendarManager;
90150 };
90151
90152 Calendar = function (type, name, storageItems, calendarId) {
90153     var privateItems = {},
90154         defaultWatchId = 0;
90155     calendarId = calendarId || Math.uuid(null, 16);
90156
90157     // private
90158     function createCalendarItem() {
90159         var calendarItem = null;
90160
90161         switch (type) {
90162         case "EVENT":
90163             calendarItem = new CalendarEvent();
90164             break;
90165
90166         case "TASK":
90167             calendarItem = new CalendarTask();
90168             break;
90169
90170         default:
90171             break;
90172         }
90173
90174         return calendarItem;
90175     }
90176
90177     function isValidCalendarItemId(itemId) {
90178         var i;
90179
90180         if (!_isValidId(itemId))
90181             return false;
90182
90183         for (i in privateItems) {
90184             if (i === itemId)
90185                 return true;
90186         }
90187
90188         return false;
90189     }
90190
90191     function loadCalendarItemInit(calendarItem, storageItem) {
90192         calendarItem.description    = utils.copy(storageItem.description);
90193         calendarItem.summary        = utils.copy(storageItem.summary);
90194         calendarItem.isAllDay       = utils.copy(storageItem.isAllDay);
90195         calendarItem.startDate      = storageItem.startDate;
90196         if (storageItem.startDate instanceof TZDate) {
90197             calendarItem.startDate      = storageItem.startDate.addDuration(new TDur(0, 'MSECS'));
90198         }
90199         if (typeof storageItem.startDate === 'string') {
90200             calendarItem.startDate      = new TZDate(new Date(storageItem.startDate));
90201         }
90202
90203         calendarItem.duration       = utils.copy(storageItem.duration);
90204         calendarItem.location       = utils.copy(storageItem.location);
90205         calendarItem.geolocation    = utils.copy(storageItem.geolocation);
90206         calendarItem.organizer      = utils.copy(storageItem.organizer);
90207         calendarItem.visibility     = utils.copy(storageItem.visibility);
90208         calendarItem.status         = utils.copy(storageItem.status);
90209         calendarItem.priority       = utils.copy(storageItem.priority);
90210         calendarItem.alarms         = utils.copy(storageItem.alarms);
90211         calendarItem.categories     = utils.copy(storageItem.categories);
90212         calendarItem.attendees      = utils.copy(storageItem.attendees);
90213     }
90214
90215     function loadCalendarEventInit(calendarItem, storageItem) {
90216         loadCalendarItemInit(calendarItem, storageItem);
90217
90218         calendarItem.endDate = storageItem.endDate;
90219         if (storageItem.endDate instanceof TZDate) {
90220             calendarItem.endDate = storageItem.endDate.addDuration(new TDur(0, 'MSECS'));
90221         }
90222         if (typeof storageItem.endDate === 'string') {
90223             calendarItem.endDate = new TZDate(new Date(storageItem.endDate));
90224         }
90225         calendarItem.availability = utils.copy(storageItem.availability);
90226         calendarItem.recurrenceRule = utils.copy(storageItem.recurrenceRule);
90227         calendarItem.expandRecurrence = function (startDate, endDate, successCallback, errorCallback) {
90228             if (!_security.expandRecurrence) {
90229                 throw new WebAPIException(errorcode.SECURITY_ERR);
90230             }
90231
90232             calendarItem.startDate = startDate;
90233             calendarItem.endDate   = endDate;
90234
90235             if (errorCallback) {
90236                 window.setTimeout(function () {
90237                     errorCallback(new WebAPIError(errorcode.NOT_SUPPORTED_ERR));
90238                 }, 1);
90239             }
90240         };
90241         calendarItem.frequency       = utils.copy(storageItem.frequency);
90242         calendarItem.interval        = utils.copy(storageItem.interval);
90243         calendarItem.untilDate = storageItem.untilDate;
90244         if (storageItem.untilDate instanceof TZDate) {
90245             calendarItem.untilDate = storageItem.untilDate.addDuration(new TDur(0, 'MSECS'));
90246         }
90247         if (typeof storageItem.untilDate === 'string') {
90248             calendarItem.untilDate = new TZDate(new Date(storageItem.untilDate));
90249         }
90250         calendarItem.occurrenceCount = utils.copy(storageItem.occurrenceCount);
90251         calendarItem.daysOfTheWeek   = utils.copy(storageItem.daysOfTheWeek);
90252         calendarItem.setPositions    = utils.copy(storageItem.setPositions);
90253         calendarItem.exceptions      = utils.copy(storageItem.exceptions);
90254     }
90255
90256     function loadCalendarTaskInit(calendarItem, storageItem) {
90257         loadCalendarItemInit(calendarItem, storageItem);
90258
90259         calendarItem.dueDate = storageItem.dueDate;
90260         if (storageItem.dueDate instanceof TZDate) {
90261             calendarItem.dueDate = storageItem.dueDate.addDuration(new TDur(0, 'MSECS'));
90262         }
90263         if (typeof storageItem.dueDate === 'string') {
90264             calendarItem.dueDate = new TZDate(new Date(storageItem.dueDate));
90265         }
90266         calendarItem.completeDate = storageItem.completeDate;
90267         if (storageItem.completeDate instanceof TZDate) {
90268             calendarItem.completeDate = storageItem.completeDate.addDuration(new TDur(0, 'MSECS'));
90269         }
90270         if (typeof storageItem.completeDate === 'string') {
90271             calendarItem.completeDate = new TZDate(new Date(storageItem.completeDate));
90272         }
90273         calendarItem.progress      = utils.copy(storageItem.progress);
90274     }
90275
90276     function loadCalendarItems() {
90277         var i, calendarItem;
90278
90279         if (storageItems === undefined)
90280             return;
90281
90282         for (i in storageItems) {
90283             calendarItem = new CalendarItem(type, i, storageItems[i].lastModificationDate? new TZDate(new Date(storageItems[i].lastModificationDate)) : null, _security);
90284
90285             if (type === "EVENT") {
90286                 loadCalendarEventInit(calendarItem, storageItems[i]);
90287             } else {
90288                 loadCalendarTaskInit(calendarItem, storageItems[i]);
90289             }
90290
90291             privateItems[i] = calendarItem;
90292         }
90293     }
90294
90295     function saveCalendarItems() {
90296         _calendarsStorage[type][calendarId] ||  (_calendarsStorage[type][calendarId] = {});
90297         _calendarsStorage[type][calendarId].items = new CalendarItemsStorage(privateItems);
90298         saveCalendars();
90299     }
90300
90301     // public
90302     function get(id) {
90303         var item, uid, CalendarItemType, external = {};
90304
90305         if (!_security.get) {
90306             throw new WebAPIException(errorcode.SECURITY_ERR);
90307         }
90308
90309         t.Calendar("get", arguments);
90310
90311         if (type === "EVENT") {
90312             if (typeof id !== "object") {
90313                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
90314             }
90315             uid = id.uid;
90316             CalendarItemType = CalendarEvent;
90317         } else {
90318             uid = id;
90319             CalendarItemType = CalendarTask;
90320         }
90321
90322         if (!isValidCalendarItemId(uid))
90323             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
90324
90325         item = new CalendarItemType(privateItems[uid]);
90326         external.id                   = privateItems[uid].id;
90327         external.lastModificationDate = privateItems[uid].lastModificationDate;
90328
90329         item.__defineGetter__("calendarId", function () {
90330             return calendarId;
90331         });
90332
90333         item.__defineGetter__("id", function () {
90334             return external.id;
90335         });
90336
90337         item.__defineGetter__("lastModificationDate", function () {
90338             return external.lastModificationDate;
90339         });
90340
90341         return item;
90342     }
90343
90344     function add(item) {
90345         var uid, external = {};
90346
90347         if (!_security.add) {
90348             throw new WebAPIException(errorcode.SECURITY_ERR);
90349         }
90350
90351         t.Calendar("add", arguments);
90352
90353         uid = Math.uuid(null, 16);
90354         privateItems[uid] = t.CalendarItem(item, "+");
90355         if (type === "EVENT") {
90356             privateItems[uid].id = new CalendarEventId(uid);
90357         } else {
90358             privateItems[uid].id = uid;
90359         }
90360         privateItems[uid].lastModificationDate = new TZDate();
90361
90362         external.id = privateItems[uid].id;
90363         external.lastModificationDate = privateItems[uid].lastModificationDate;
90364
90365         saveCalendarItems();
90366
90367         // set the calendarId of the item
90368         item.__defineGetter__("calendarId", function () {
90369             return calendarId;
90370         });
90371
90372         item.__defineGetter__("id", function () {
90373             return external.id;
90374         });
90375
90376         item.__defineGetter__("lastModificationDate", function () {
90377             return external.lastModificationDate;
90378         });
90379
90380         window.setTimeout(function () {
90381             for (var i in _watchers) {
90382                 _watchers[i].onitemsadded([item]);
90383             }
90384         }, 1);
90385     }
90386
90387     function addBatch(items, successCallback, errorCallback) {
90388         if (!_security.addBatch) {
90389             throw new WebAPIException(errorcode.SECURITY_ERR);
90390         }
90391
90392         t.Calendar("addBatch", arguments, true);
90393
90394         window.setTimeout(function () {
90395             var i, j, uid, external = [];
90396
90397             for (i in items) {
90398                 uid = Math.uuid(null, 16);
90399                 privateItems[uid] = utils.copy(items[i]);
90400
90401                 if (type === "EVENT") {
90402                     privateItems[uid].id = new CalendarEventId(uid);
90403                 } else {
90404                     privateItems[uid].id = uid;
90405                 }
90406
90407                 external[i] = {};
90408                 external[i].id = privateItems[uid].id;
90409                 external[i].lastModificationDate = new TZDate();
90410
90411                 items[i].__defineGetter__("calendarId", function () {
90412                     return calendarId;
90413                 });
90414
90415                 items[i].__defineGetter__("id", function () {
90416                     return external[i].id;
90417                 });
90418
90419                 items[i].__defineGetter__("lastModificationDate", function () {
90420                     return external[i].lastModificationDate;
90421                 });
90422             }
90423
90424             saveCalendarItems();
90425
90426             if (successCallback) {
90427                 successCallback(items);
90428             }
90429             for (j in _watchers) {
90430                 _watchers[j].onitemsadded(items);
90431             }
90432         }, 1);
90433     }
90434
90435     function update(item, updateAllInstances) {
90436         var calendarItem, attr, uid;
90437
90438         if (!_security.update) {
90439             throw new WebAPIException(errorcode.SECURITY_ERR);
90440         }
90441
90442         t.Calendar("update", arguments);
90443
90444         uid = (type === "EVENT") ? item.id.uid : item.id;
90445         if (!isValidCalendarItemId(uid))
90446             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
90447
90448         if (updateAllInstances === undefined || updateAllInstances === null) {
90449             updateAllInstances = true;
90450         }
90451
90452         if ((type === "EVENT") && !updateAllInstances) {
90453             calendarItem = createCalendarItem();
90454
90455             for (attr in privateItems[uid]) {
90456                 if (attr !== "id" && attr !== "lastModificationDate") {
90457                     if (item[attr] !== undefined)
90458                         calendarItem[attr] = utils.copy(item[attr]);
90459                     else
90460                         calendarItem[attr] = utils.copy(privateItems[uid][attr]);
90461                 }
90462             }
90463
90464             add(calendarItem);
90465         } else {
90466             for (attr in privateItems[uid]) {
90467                 if ((attr !== "id") && (attr !== "lastModificationDate") && (item[attr] !== undefined))
90468                     privateItems[uid][attr] = utils.copy(item[attr]);
90469             }
90470             window.setTimeout(function () {
90471                 var i;
90472
90473                 for (i in _watchers) {
90474                     _watchers[i].onitemsupdated([utils.copy(privateItems[uid])]);
90475                 }
90476             }, 1);
90477         }
90478         saveCalendarItems();
90479     }
90480
90481     function updateBatch(items, successCallback, errorCallback,
90482             updateAllInstances) {
90483         if (!_security.updateBatch) {
90484             throw new WebAPIException(errorcode.SECURITY_ERR);
90485         }
90486
90487         t.Calendar("updateBatch", arguments, true);
90488
90489         window.setTimeout(function () {
90490             var i, j, attr, calendarItem, updatedItems = [], uid;
90491
90492             for (i in items) {
90493                 uid = (type === "EVENT") ? items[i].id.uid : items[i].id;
90494                 if (!uid || !privateItems[uid]) {
90495                     if (errorCallback) {
90496                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
90497                     }
90498                     return;
90499                 }
90500             }
90501
90502             if (updateAllInstances) {
90503                 for (i in privateItems) {
90504                     for (j in items) {
90505                         uid = (type === "EVENT") ? items[j].id.uid : items[j].id;
90506                         if (i === uid) {
90507                             for (attr in privateItems[i]) {
90508                                 if (attr !== "id" && attr !== "lastModificationDate" && items[j][attr] !== undefined)
90509                                     privateItems[i][attr] = utils.copy(items[j][attr]);
90510                             }
90511                             saveCalendarItems();
90512                             updatedItems.push(utils.copy(privateItems[i]));
90513                         }
90514                     }
90515                 }
90516             } else {
90517                 for (i in items) {
90518                     calendarItem = createCalendarItem();
90519
90520                     uid = (type === "EVENT") ? items[i].id.uid : items[i].id;
90521                     for (attr in privateItems[uid]) {
90522                         if (attr !== "id" && attr !== "lastModificationDate") {
90523                             if (items[i][attr] !== undefined)
90524                                 calendarItem[attr] = utils.copy(items[i][attr]);
90525                             else
90526                                 calendarItem[attr] = utils.copy(privateItems[uid][attr]);
90527                         }
90528                     }
90529
90530                     add(calendarItem);
90531                     updatedItems.push(utils.copy(calendarItem));
90532                 }
90533             }
90534
90535             saveCalendarItems();
90536             if (successCallback) {
90537                 successCallback();
90538             }
90539             for (i in _watchers) {
90540                 _watchers[i].onitemsupdated(utils.copy(updatedItems));
90541             }
90542         }, 1);
90543     }
90544
90545     function remove(id) {
90546         var isFound = false, i, uid;
90547
90548         if (!_security.remove) {
90549             throw new WebAPIException(errorcode.SECURITY_ERR);
90550         }
90551
90552         t.Calendar("remove", arguments);
90553
90554         uid = (type === "EVENT") ? id.uid : id;
90555         for (i in privateItems) {
90556             if (i === uid) {
90557                 delete privateItems[i];
90558                 isFound = true;
90559                 break;
90560             }
90561         }
90562
90563         if (!isFound)
90564             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
90565
90566         saveCalendarItems();
90567
90568         window.setTimeout(function () {
90569             var i;
90570
90571             for (i in _watchers) {
90572                 _watchers[i].onitemsremoved([id]);
90573             }
90574         }, 1);
90575     }
90576
90577     function removeBatch(ids, successCallback, errorCallback) {
90578         if (!_security.removeBatch) {
90579             throw new WebAPIException(errorcode.SECURITY_ERR);
90580         }
90581
90582         t.Calendar("removeBatch", arguments, true);
90583
90584         window.setTimeout(function () {
90585             var i, uid;
90586
90587             for (i in ids) {
90588                 uid = (type === "EVENT") ? ids[i].uid : ids[i];
90589
90590                 if (!privateItems[uid]) {
90591                     if (errorCallback) {
90592                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
90593                     }
90594                     return;
90595                 }
90596             }
90597
90598             for (i in ids) {
90599                 uid = (type === "EVENT") ? ids[i].uid : ids[i];
90600                 delete privateItems[uid];
90601             }
90602             saveCalendarItems();
90603             if (successCallback) {
90604                 successCallback();
90605             }
90606
90607             for (i in _watchers) {
90608                 _watchers[i].onitemsremoved(utils.copy(ids));
90609             }
90610         }, 1);
90611     }
90612
90613     function find(successCallback, errorCallback, filter, sortMode) {
90614         if (!_security.find) {
90615             throw new WebAPIException(errorcode.SECURITY_ERR);
90616         }
90617
90618         t.Calendar("find", arguments, true);
90619
90620         window.setTimeout(function () {
90621             var i, calendarItems = [], result = [];
90622
90623             for (i in privateItems) {
90624                 calendarItems.push(privateItems[i]);
90625             }
90626             if (calendarItems.length > 0) {
90627                 result = tizen1_utils.query(calendarItems, filter, sortMode);
90628             }
90629             successCallback(result);
90630         }, 1);
90631     }
90632
90633     function addChangeListener(successCallback) {
90634         var watchId;
90635
90636         if (!_security.addChangeListener) {
90637             throw new WebAPIException(errorcode.SECURITY_ERR);
90638         }
90639
90640         t.Calendar("addChangeListener", arguments);
90641
90642         watchId = ++defaultWatchId;
90643         _watchers[watchId] = successCallback;
90644
90645         return watchId;
90646     }
90647
90648     function removeChangeListener(watchId) {
90649         if (!_security.removeChangeListener) {
90650             throw new WebAPIException(errorcode.SECURITY_ERR);
90651         }
90652
90653         if (!_watchers[watchId])
90654             return;
90655
90656         delete _watchers[watchId];
90657     }
90658
90659     loadCalendarItems(type, privateItems, storageItems);
90660
90661     this.__defineGetter__("id", function () {
90662         return calendarId;
90663     });
90664     this.__defineGetter__("name", function () {
90665         return name;
90666     });
90667
90668     this.get                  = get;
90669     this.add                  = add;
90670     this.addBatch             = addBatch;
90671     this.update               = update;
90672     this.updateBatch          = updateBatch;
90673     this.remove               = remove;
90674     this.removeBatch          = removeBatch;
90675     this.find                 = find;
90676     this.addChangeListener    = addChangeListener;
90677     this.removeChangeListener = removeChangeListener;
90678 };
90679
90680 CalendarStorage = function (calendar) {
90681     this.id   = calendar.id;
90682     this.name = calendar.name;
90683 };
90684
90685 CalendarItemsStorage = function (privateItems) {
90686     var itemsStorage = {}, i, attr;
90687
90688     for (i in privateItems) {
90689         itemsStorage[i] = {};
90690         for (attr in privateItems[i]) {
90691             //TODO: should be
90692             //      if (privateItems[i][attr] instanceof TZDate) {
90693             //But, we used "utils.copy" before store the item to privateItems list.
90694             //So the constructor information all lost
90695             if ((attr === "startDate" || attr === "endDate" || attr === "dueDate" || attr === "completedDate" || attr === "lastModificationDate") &&
90696                 (privateItems[i][attr])) {
90697
90698                 itemsStorage[i][attr] = privateItems[i][attr].toString();
90699             } else if (typeof privateItems[i] !== "function") {
90700                 itemsStorage[i][attr] = privateItems[i][attr];
90701             }
90702         }
90703     }
90704
90705     return itemsStorage;
90706 };
90707
90708 module.exports = _self;
90709
90710 });
90711 define('ripple/platform/tizen/2.0/callHistory', function (require, exports, module) {
90712 /*
90713  *  Copyright 2012 Intel Corporation.
90714  *
90715  * Licensed under the Apache License, Version 2.0 (the "License");
90716  * you may not use this file except in compliance with the License.
90717  * You may obtain a copy of the License at
90718  *
90719  * http://www.apache.org/licenses/LICENSE-2.0
90720  *
90721  * Unless required by applicable law or agreed to in writing, software
90722  * distributed under the License is distributed on an "AS IS" BASIS,
90723  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
90724  * See the License for the specific language governing permissions and
90725  * limitations under the License.
90726  */
90727
90728 var utils = require('ripple/utils'),
90729     db = require('ripple/db'),
90730     event = require('ripple/event'),
90731     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
90732     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
90733     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
90734     t = require('ripple/platform/tizen/2.0/typecast'),
90735     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
90736     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
90737     _DB_CALL_KEY = "tizen1-db-callhistory",
90738     _data = {
90739         observers: {},
90740         callHistory: []
90741     },
90742     _security = {
90743         "http://tizen.org/privilege/callhistory.read": ["find", "addChangeListener", "removeChangeListener"],
90744         "http://tizen.org/privilege/callhistory.write": ["remove", "removeBatch", "removeAll"]
90745     },
90746     _self;
90747
90748 function _getValue(inputValue, key) {
90749     var keys = key.split("."),
90750         value = inputValue[keys[0]],
90751         index;
90752
90753     for (index = 1; index < keys.length; index++) {
90754         if (value[keys[index]]) {
90755             value = value[keys[index]];
90756         }
90757     }
90758
90759     return value;
90760 }
90761
90762 function _filter(inputArray, filter) {
90763     var index, filterResults = [], compositeResultArray;
90764
90765     if (filter === null || filter === undefined) {
90766         return inputArray;
90767     }
90768
90769     if (filter.type && filter.filters) {
90770         filterResults = _filter(inputArray, filter.filters[0]);
90771         for (index = 1; index < filter.filters.length; index++) {
90772             compositeResultArray = _filter(inputArray, filter.filters[index]);
90773
90774             filterResults = tizen1_utils.arrayComposite(filter.type, filterResults, compositeResultArray);
90775         }
90776         return filterResults;
90777     }
90778
90779     if (filter.attributeName === null || filter.attributeName === undefined) {
90780         throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
90781     }
90782
90783     if (filter.matchFlag) {
90784         if (filter.attributeName === 'features') {
90785             filterResults = tizen1_utils.matchAttributeArrayFilter(inputArray, filter.attributeName, filter.matchFlag, filter.matchValue);
90786         } else {
90787             filterResults = tizen1_utils.matchAttributeFilter(inputArray, filter.attributeName, filter.matchFlag, filter.matchValue);
90788         }
90789     }
90790     else if (filter.initialValue || filter.endValue) {
90791         filterResults = tizen1_utils.matchAttributeRangeFilter(inputArray, filter.attributeName, filter.initialValue, filter.endValue);
90792     }
90793
90794     return filterResults;
90795 }
90796
90797 function _sort(inputArray, sortMode) {
90798     if (sortMode.attributeName === null || sortMode.attributeName === undefined) {
90799         throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
90800     }
90801
90802     inputArray.sort(function (a, b) {
90803         return sortMode.order === "ASC" ? _getValue(a, sortMode.attributeName) - _getValue(b, sortMode.attributeName) :
90804                _getValue(b, sortMode.attributeName) - _getValue(a, sortMode.attributeName);
90805     });
90806
90807     return inputArray;
90808 }
90809
90810 function _save() {
90811     db.saveObject(_DB_CALL_KEY, _data.callHistory);
90812 }
90813
90814 function _retrieve() {
90815     var index;
90816
90817     _data.callHistory = db.retrieveObject(_DB_CALL_KEY) || [];
90818
90819     for (index = 0; index < _data.callHistory.length; index++) {
90820         _data.callHistory[index].startTime = new Date(_data.callHistory[index].startTime);
90821     }
90822 }
90823
90824 function _isValidCallHistoryEntry(arg) {
90825     return arg && arg.hasOwnProperty("uid") && arg.hasOwnProperty("type") &&
90826            arg.hasOwnProperty("features") && arg.hasOwnProperty("remoteParties") &&
90827            arg.hasOwnProperty("startTime") && arg.hasOwnProperty("duration") &&
90828            arg.hasOwnProperty("direction");
90829 }
90830
90831 function _rtnRmtPty(pty) {
90832     var _remoteParty = pty.remoteParty,
90833         _personId = pty.personId,
90834         _self = {};
90835     _self.__defineGetter__("remoteParty", function () {
90836         return _remoteParty;
90837     });
90838     _self.__defineGetter__("personId", function () {
90839         return _personId;
90840     });
90841     return _self;
90842 }
90843
90844 function _rtnEntry(entry) {
90845     var _uid = entry.uid,
90846         _type = entry.type,
90847         _features = tizen1_utils.copy(entry.features),
90848         _remoteParties = [],
90849         _startTime = new Date(entry.startTime),
90850         _duration = entry.duration,
90851         _direction = entry.direction,
90852         _self = {}, i;
90853
90854     for (i = 0; i < entry.remoteParties.length; i++) {
90855         _remoteParties.push(_rtnRmtPty(entry.remoteParties[i]));
90856     }
90857     _self.__defineGetter__("uid", function () {
90858         return _uid;
90859     });
90860     _self.__defineGetter__("type", function () {
90861         return _type;
90862     });
90863     _self.__defineGetter__("features", function () {
90864         return _features;
90865     });
90866     _self.__defineGetter__("remoteParties", function () {
90867         return _remoteParties;
90868     });
90869     _self.__defineGetter__("startTime", function () {
90870         return _startTime;
90871     });
90872     _self.__defineGetter__("duration", function () {
90873         return _duration;
90874     });
90875     _self.direction = _direction;
90876
90877     return _self;
90878 }
90879
90880 function _initialize() {
90881     _retrieve();
90882
90883     event.on("CallInProgress", function () {
90884     });
90885
90886     event.on("CallRecorded", function (record) {
90887         var historyEntry = tizen1_utils.copy(record);
90888         historyEntry.uid = Math.uuid(8, 16);
90889
90890         _data.callHistory.push(historyEntry);
90891         _save();
90892
90893         utils.forEach(_data.observers, function (observer) {
90894             observer.onadded([historyEntry]);
90895         });
90896     });
90897 }
90898
90899 _self = function () {
90900     this.find = function (successCallback, errorCallback, filter, sortMode, limit, offset) {
90901         var i, rtn = [],
90902             filterResults,
90903             limitValue = limit | 0,
90904             offsetValue = offset | 0;
90905
90906         if (!_security.find) {
90907             throw new WebAPIException(errorcode.SECURITY_ERR);
90908         }
90909
90910         t.CallHistory("find", arguments);
90911
90912         filterResults = tizen1_utils.copy(_data.callHistory);
90913         if (filter !== null && filter !== undefined) {
90914             filterResults = _filter(filterResults, filter);
90915         }
90916
90917         if (sortMode !== null && sortMode !== undefined) {
90918             _sort(filterResults, sortMode);
90919         }
90920
90921         setTimeout(function () {
90922             if (limitValue > 0) {
90923                 offsetValue = offsetValue > 0 ? offsetValue : 0;
90924                 filterResults = filterResults.slice(offsetValue, limitValue);
90925             }
90926
90927             for (i = 0; i < filterResults.length; i++) {
90928                 rtn.push(_rtnEntry(filterResults[i]));
90929             }
90930             successCallback(rtn);
90931         }, 1);
90932     };
90933     this.remove = function (entry) {
90934         var isFound = false, rtn = [];
90935
90936         if (!_security.remove) {
90937             throw new WebAPIException(errorcode.SECURITY_ERR);
90938         }
90939
90940         t.CallHistory("remove", arguments);
90941
90942         _data.callHistory = _data.callHistory.filter(function (element) {
90943             return utils.some(element, function (value, key) {
90944                 if (tizen1_utils.isEqual(entry[key], value)) {
90945                     isFound = true;
90946                     return false;
90947                 }
90948                 return true;
90949             });
90950         });
90951
90952         if (!isFound) {
90953             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
90954         }
90955
90956         _save();
90957         rtn.push(_rtnEntry(entry));
90958         utils.forEach(_data.observers, function (observer) {
90959             observer.onchanged(rtn);
90960         });
90961
90962     };
90963     this.removeBatch = function (entries, successCallback, errorCallback) {
90964         var isFound = false, i, rtn = [];
90965
90966         if (!_security.removeBatch) {
90967             throw new WebAPIException(errorcode.SECURITY_ERR);
90968         }
90969
90970         t.CallHistory("removeBatch", arguments);
90971
90972         setTimeout(function () {
90973             isFound = entries.every(function (element) {
90974                 return _data.callHistory.some(function (callHistory) {
90975                     return element.uid === callHistory.uid;
90976                 });
90977             });
90978
90979             if (!isFound) {
90980                 if (errorCallback) {
90981                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
90982                 }
90983                 return;
90984             }
90985
90986             _data.callHistory = _data.callHistory.filter(function (element) {
90987                 return !entries.some(function (entryValue, entryIndex) {
90988                     return tizen1_utils.isEqual(element, entryValue);
90989                 });
90990             });
90991
90992             _save();
90993
90994             if (successCallback) {
90995                 successCallback();
90996             }
90997             for (i = 0; i < entries.length; i++) {
90998                 rtn.push(_rtnEntry(entries[i]));
90999             }
91000             utils.forEach(_data.observers, function (observer) {
91001                 observer.onchanged(rtn);
91002             });
91003         }, 1);
91004     };
91005     this.removeAll = function (successCallback, errorCallback) {
91006         var i, rtn = [];
91007
91008         if (!_security.removeAll) {
91009             throw new WebAPIException(errorcode.SECURITY_ERR);
91010         }
91011
91012         t.CallHistory("removeAll", arguments);
91013
91014         for (i = 0; i < _data.callHistory.length; i++) {
91015             rtn.push(_rtnEntry(_data.callHistory[i]));
91016         }
91017
91018         _data.callHistory = [];
91019         _save();
91020
91021         utils.forEach(_data.observers, function (observer) {
91022             observer.onchanged(rtn);
91023         });
91024
91025         if (successCallback) {
91026             setTimeout(function () {
91027                 successCallback();
91028             }, 1);
91029         }
91030
91031     };
91032     this.addChangeListener = function (observerObj) {
91033         var handle = Number(Math.uuid(8, 10));
91034
91035         if (!_security.addChangeListener) {
91036             throw new WebAPIException(errorcode.SECURITY_ERR);
91037         }
91038
91039         t.CallHistory("addChangeListener", arguments);
91040
91041         _data.observers[handle] = observerObj;
91042
91043         return handle;
91044     };
91045     this.removeChangeListener = function (handle) {
91046         if (!_security.removeChangeListener) {
91047             throw new WebAPIException(errorcode.SECURITY_ERR);
91048         }
91049
91050         if (!_data.observers[handle])
91051             return;
91052
91053         delete _data.observers[handle];
91054     };
91055     this.handleSubFeatures = function (subFeatures) {
91056         function setSecurity(method) {
91057             _security[method] = true;
91058         }
91059
91060         for (var subFeature in subFeatures) {
91061             utils.forEach(_security[subFeature], setSecurity);
91062         }
91063     };
91064 };
91065
91066 _initialize();
91067
91068 module.exports = _self;
91069
91070 });
91071 define('ripple/platform/tizen/2.0/contact', function (require, exports, module) {
91072 /*
91073  *  Copyright 2013 Intel Corporation.
91074  *
91075  * Licensed under the Apache License, Version 2.0 (the "License");
91076  * you may not use this file except in compliance with the License.
91077  * You may obtain a copy of the License at
91078  *
91079  * http://www.apache.org/licenses/LICENSE-2.0
91080  *
91081  * Unless required by applicable law or agreed to in writing, software
91082  * distributed under the License is distributed on an "AS IS" BASIS,
91083  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
91084  * See the License for the specific language governing permissions and
91085  * limitations under the License.
91086  */
91087
91088 var db = require('ripple/db'),
91089     decorator = require('ripple/platform/tizen/2.0/decorator'),
91090     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
91091     t = require('ripple/platform/tizen/2.0/typecast'),
91092     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
91093     utils = require('ripple/utils'),
91094     ContactName = require('ripple/platform/tizen/2.0/ContactName'),
91095     ContactAddress = require('ripple/platform/tizen/2.0/ContactAddress'),
91096     ContactPhoneNumber = require('ripple/platform/tizen/2.0/ContactPhoneNumber'),
91097     ContactEmailAddress = require('ripple/platform/tizen/2.0/ContactEmailAddress'),
91098     ContactAnniversary = require('ripple/platform/tizen/2.0/ContactAnniversary'),
91099     ContactOrganization = require('ripple/platform/tizen/2.0/ContactOrganization'),
91100     ContactWebSite = require('ripple/platform/tizen/2.0/ContactWebSite'),
91101     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
91102     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
91103     AddressBook,
91104     AddressBookData,
91105     AddressBookStorage,
91106     Contact,
91107     ContactData,
91108     ContactInternal,
91109     ContactGroup,
91110     Person,
91111     PersonBuilder,
91112     _data = {
91113         DB_CONTACT_KEY: "tizen1-contact",
91114         addressBooks:   [],
91115         contacts:       {},
91116         persons:        {},
91117         contactData:    {},
91118         dbStorage:      {}
91119     },
91120     _security = {
91121         "http://tizen.org/privilege/contact.read": ["getAddressBooks",
91122                 "getUnifiedAddressBook", "getDefaultAddressBook",
91123                 "getAddressBook", "get", "find", "addChangeListener",
91124                 "removeChangeListener", "getGroup", "getGroups", "clone"],
91125         "http://tizen.org/privilege/contact.write": ["add", "addBatch",
91126                 "update", "updateBatch", "remove", "removeBatch", "addGroup",
91127                 "updateGroup", "removeGroup", "link", "unlink"]
91128     },
91129     _self;
91130
91131 function _get() {
91132     _data.dbStorage = db.retrieveObject(_data.DB_CONTACT_KEY) ||
91133             {addressBooks: [], persons: {}};
91134 }
91135
91136 function _save() {
91137     db.saveObject(_data.DB_CONTACT_KEY, _data.dbStorage);
91138 }
91139
91140 function _serialize(obj) {
91141     var i, dbObj = {};
91142
91143     for (i in obj) {
91144         if (typeof obj[i] !== "function")
91145             dbObj[i] = utils.copy(obj[i]);
91146     }
91147
91148     return dbObj;
91149 }
91150
91151 /* check filter type (it's a recursive function)
91152    0: It is not a filter
91153    1: CompositeFilter
91154    2: AttributeFilter
91155    3: AttributeRangeFilter
91156  */
91157 function _filterType(filter) {
91158     var i = 0, ret;
91159
91160     if (Object.prototype.toString.call(filter) !== "[object Object]") {
91161         return 0; // 0: it is not a filter
91162     }
91163
91164     /* check if it is CompositFilter or not */
91165     if (filter.type !== null && filter.type !== undefined) {
91166         /* attribute 'type' of CompositeFilter must be "UNION" or "INTERSECTION" */
91167         if (filter.type === "UNION" || filter.type === "INTERSECTION") {
91168             /*attribute 'filters' of CompositeFilter must be AbstractFilter array */
91169             if (tizen1_utils.isValidArray(filter.filters)) {
91170                 for (i = 0; i < filter.filters.length; i++) {
91171                     /* recursive call */
91172                     if (_filterType(filter.filters[i]) === 0) {
91173                         return 0; // 0: it is not a filter
91174                     }
91175                 }
91176             } else {
91177                 return 0; // 0: it is not a filter
91178             }
91179         } else {
91180             return 0; // 0: it is not a filter
91181         }
91182         return 1; // CompositeFilter
91183     }
91184
91185     /* AttributeFilter or AttributeRangeFilter must have attributeName */
91186     if (filter.attributeName === null || filter.attributeName === undefined) {
91187         return 0; // 0: it is not a filter
91188     } else {
91189         ret = 2; // assume it is an AttributeFilter
91190         if ((filter.initialValue !== null && filter.initialValue !== undefined) ||
91191             (filter.endValue !== null && filter.endValue !== undefined)) {
91192             ret = 3; // AttributeRangeFilter
91193         }
91194         return ret;
91195     }
91196 }
91197
91198 function _sort(objects, sortMode) {
91199     function getValue(obj, key) {
91200         var keys = key.split("."),
91201             value = obj[keys[0]],
91202             i;
91203
91204         for (i = 1; i < keys.length; i++) {
91205             if (value[keys[i]]) {
91206                 value = value[keys[i]];
91207             }
91208         }
91209
91210         return value;
91211     }
91212
91213     objects.sort(function (a, b) {
91214         return (sortMode.order === "ASC") ?
91215             (getValue(a, sortMode.attributeName) < getValue(b, sortMode.attributeName) ? -1 : 1):
91216             (getValue(a, sortMode.attributeName) > getValue(b, sortMode.attributeName) ? -1 : 1);
91217     });
91218
91219     return objects;
91220 }
91221
91222 function _replacePerson(oldId, newId) {
91223     var contact, dbAddressBook, idab, idc, i;
91224
91225     for (idab in _data.contacts) {
91226         for (idc in _data.contacts[idab]) {
91227             contact = _data.contacts[idab][idc];
91228             if (contact.personId === oldId) {
91229                 if (newId === null) {
91230                     delete _data.contacts[idab][idc];
91231                 } else {
91232                     contact.personId = newId;
91233                 }
91234             }
91235         }
91236     }
91237
91238     if (_data.persons[oldId]) {
91239         delete _data.persons[oldId];
91240     }
91241
91242     for (i in _data.dbStorage.addressBooks) {
91243         dbAddressBook = _data.dbStorage.addressBooks[i];
91244         for (idc in dbAddressBook.contacts) {
91245             contact = dbAddressBook.contacts[idc];
91246             if (contact.personId === oldId) {
91247                 if (newId === null) {
91248                     delete dbAddressBook.contacts[idc];
91249                 } else {
91250                     contact.personId = newId;
91251                 }
91252             }
91253         }
91254     }
91255
91256     if (_data.dbStorage.persons[oldId]) {
91257         delete _data.dbStorage.persons[oldId];
91258     }
91259 }
91260
91261 _self = function () {
91262     var contact;
91263
91264     // private
91265     function loadAddressBooks() {
91266         var i;
91267
91268         _get();
91269
91270         if (_data.dbStorage.addressBooks.length === 0) {
91271             // Initialize default address books if database is empty
91272             _data.dbStorage.addressBooks = [
91273                 new AddressBookStorage(Math.uuid(null, 16), "Phone address book", false, {}, []),
91274                 new AddressBookStorage(Math.uuid(null, 16), "SIM address book", false, {}, [])
91275             ];
91276         }
91277
91278         utils.forEach(_data.dbStorage.addressBooks, function (addressBook) {
91279             _data.addressBooks.push(new AddressBook(addressBook.id, addressBook.name,
91280                 addressBook.readOnly, addressBook.contacts, addressBook.groups));
91281         });
91282
91283         for (i in _data.dbStorage.persons) {
91284             _data.persons[i] = new Person(_data.dbStorage.persons[i]);
91285         }
91286     }
91287
91288     // public
91289     // Address Book Methods
91290     function getAddressBooks(successCallback, errorCallback) {
91291         if (!_security.getAddressBooks) {
91292             throw new WebAPIException(errorcode.SECURITY_ERR);
91293         }
91294
91295         t.ContactManager("getAddressBooks", arguments);
91296
91297         window.setTimeout(function () {
91298             if (_data.addressBooks.length === 0) {
91299                 loadAddressBooks();
91300             }
91301             successCallback(_data.addressBooks);
91302         }, 1);
91303     }
91304
91305     function getUnifiedAddressBook() {
91306         if (!_security.getUnifiedAddressBook) {
91307             throw new WebAPIException(errorcode.SECURITY_ERR);
91308         }
91309         if (_data.addressBooks.length === 0) {
91310             loadAddressBooks();
91311         }
91312         return _data.addressBooks[0];
91313     }
91314
91315     function getDefaultAddressBook() {
91316         if (!_security.getDefaultAddressBook) {
91317             throw new WebAPIException(errorcode.SECURITY_ERR);
91318         }
91319         if (_data.addressBooks.length === 0) {
91320             loadAddressBooks();
91321         }
91322         return _data.addressBooks[0];
91323     }
91324
91325     function getAddressBook(addressBookId) {
91326         var i;
91327
91328         if (!_security.getAddressBook) {
91329             throw new WebAPIException(errorcode.SECURITY_ERR);
91330         }
91331
91332         t.ContactManager("getAddressBook", arguments);
91333
91334         if (_data.addressBooks.length === 0) {
91335             loadAddressBooks();
91336         }
91337         for (i in _data.addressBooks) {
91338             if (_data.addressBooks[i].id === addressBookId) {
91339                 return _data.addressBooks[i];
91340             }
91341         }
91342
91343         /* Cannot found */
91344         throw new WebAPIException(errorcode.NOT_FOUND_ERR);
91345     }
91346
91347     // Person Methods
91348     function get(personId) {
91349         if (!_security.get) {
91350             throw new WebAPIException(errorcode.SECURITY_ERR);
91351         }
91352
91353         t.ContactManager("get", arguments);
91354
91355         if (_data.persons[personId] === undefined) {
91356             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
91357         }
91358
91359         return new Person(_data.persons[personId]);
91360     }
91361
91362     function update(person) {
91363         var updated;
91364
91365         if (!_security.update) {
91366             throw new WebAPIException(errorcode.SECURITY_ERR);
91367         }
91368
91369         t.ContactManager("update", arguments);
91370
91371         if (!person.id) {
91372             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
91373         }
91374         if (_data.persons[person.id] === undefined) {
91375             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
91376         }
91377
91378         updated = new Person(person);
91379
91380         _data.persons[updated.id] = updated;
91381         _data.dbStorage.persons[updated.id] = _serialize(updated);
91382         _save();
91383
91384         window.setTimeout(function () {
91385             utils.forEach(_data.contactData.listeners, function (listener) {
91386                 listener.onpersonsupdated([new Person(updated)]);
91387             });
91388         }, 1);
91389     }
91390
91391     function updateBatch(persons, successCallback, errorCallback) {
91392         if (!_security.updateBatch) {
91393             throw new WebAPIException(errorcode.SECURITY_ERR);
91394         }
91395
91396         t.ContactManager("updateBatch", arguments, true);
91397
91398         window.setTimeout(function () {
91399             var i, updated;
91400
91401             if (persons.length === 0) {
91402                 if (errorCallback) {
91403                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91404                 }
91405                 return;
91406             }
91407
91408             for (i in persons) {
91409                 if (!persons[i].id) {
91410                     if (errorCallback) {
91411                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91412                     }
91413                     return;
91414                 }
91415                 if (_data.persons[persons[i].id] === undefined) {
91416                     if (errorCallback) {
91417                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
91418                     }
91419                     return;
91420                 }
91421             }
91422             for (i in persons) {
91423                 updated = new Person(persons[i]);
91424
91425                 _data.persons[updated.id] = updated;
91426                 _data.dbStorage.persons[updated.id] = _serialize(updated);
91427             }
91428             _save();
91429             if (successCallback) {
91430                 successCallback();
91431             }
91432
91433             utils.forEach(_data.contactData.listeners, function (listener) {
91434                 var i, watched = [];
91435
91436                 for (i in persons) {
91437                     watched.push(new Person(_data.persons[persons[i].id]));
91438                 }
91439                 listener.onpersonsupdated(watched);
91440             });
91441         }, 1);
91442     }
91443
91444     function remove(personId) {
91445         if (!_security.remove) {
91446             throw new WebAPIException(errorcode.SECURITY_ERR);
91447         }
91448
91449         t.ContactManager("remove", arguments);
91450
91451         if (_data.persons[personId] === undefined) {
91452             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
91453         }
91454         _replacePerson(personId, null);
91455         _save();
91456
91457         window.setTimeout(function () {
91458             utils.forEach(_data.contactData.listeners, function (listener) {
91459                 listener.onpersonsremoved([personId]);
91460             });
91461         }, 1);
91462     }
91463
91464     function removeBatch(personIds, successCallback, errorCallback) {
91465         if (!_security.removeBatch) {
91466             throw new WebAPIException(errorcode.SECURITY_ERR);
91467         }
91468
91469         t.ContactManager("removeBatch", arguments, true);
91470
91471         window.setTimeout(function () {
91472             var i;
91473
91474             if (personIds.length === 0) {
91475                 if (errorCallback) {
91476                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91477                 }
91478                 return;
91479             }
91480
91481             for (i in personIds) {
91482                 if (!personIds[i]) {
91483                     if (errorCallback) {
91484                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91485                     }
91486                     return;
91487                 }
91488                 if (_data.persons[personIds[i]] === undefined) {
91489                     if (errorCallback) {
91490                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
91491                     }
91492                     return;
91493                 }
91494             }
91495             for (i in personIds) {
91496                 _replacePerson(personIds[i], null);
91497             }
91498             _save();
91499             if (successCallback) {
91500                 successCallback();
91501             }
91502
91503             utils.forEach(_data.contactData.listeners, function (listener) {
91504                 listener.onpersonsremoved(utils.copy(personIds));
91505             });
91506         }, 1);
91507     }
91508
91509     function find(successCallback, errorCallback, filter, sortMode) {
91510         if (!_security.find) {
91511             throw new WebAPIException(errorcode.SECURITY_ERR);
91512         }
91513
91514         t.ContactManager("find", arguments, true);
91515
91516         window.setTimeout(function () {
91517             var i, matched = [], result = [];
91518
91519             if (filter) {
91520                 switch (_filterType(filter)) {
91521                 case 0:
91522                     if (errorCallback) {
91523                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91524                     }
91525                     return;
91526
91527                 case 1:
91528                     //TODO:
91529                     //"compositeFilter doesn't support"
91530                     if (errorCallback) {
91531                         errorCallback(new WebAPIError(errorcode.NOT_SUPPORTED_ERR));
91532                     }
91533                     return;
91534
91535                 case 2:
91536                 case 3:
91537                     break;
91538                 }
91539             }
91540
91541             if (filter === null || filter === undefined) {
91542                 utils.forEach(_data.persons, function (person) {
91543                     matched.push(person);
91544                 });
91545             } else {
91546                 switch (filter.attributeName) {
91547                 case "id":
91548                 case "displayName":
91549                 case "photoURI":
91550                 case "ringtoneURI":
91551                 case "displayContactId":
91552                     matched = tizen1_utils.matchAttributeFilter(_data.persons,
91553                             filter.attributeName, filter.matchFlag, filter.matchValue);
91554                     break;
91555
91556                 case "contactCount":
91557                     if ((filter.matchFlag !== "EXACTLY") ||
91558                             (typeof filter.matchValue !== "number")) {
91559                         if (errorCallback) {
91560                             errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91561                         }
91562                         return;
91563                     }
91564                     matched = tizen1_utils.matchAttributeFilter(_data.persons,
91565                             filter.attributeName, filter.matchFlag, filter.matchValue);
91566                     break;
91567
91568                 case "hasPhoneNumber":
91569                 case "hasEmail":
91570                 case "isFavorite":
91571                     if ((filter.matchFlag !== "EXACTLY") ||
91572                             (typeof filter.matchValue !== "boolean")) {
91573                         if (errorCallback) {
91574                             errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91575                         }
91576                         return;
91577                     }
91578                     matched = tizen1_utils.matchAttributeBooleanFilter(_data.persons,
91579                             filter.attributeName, filter.matchValue);
91580                     break;
91581
91582                 default:
91583                     if (errorCallback) {
91584                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91585                     }
91586                     return;
91587                 }
91588             }
91589
91590             if (sortMode) {
91591                 _sort(matched, sortMode);
91592             }
91593
91594             for (i in matched) {
91595                 result.push(new Person(matched[i]));
91596             }
91597
91598             successCallback(result);
91599         }, 1);
91600     }
91601
91602     function addChangeListener(successCallback) {
91603         var id;
91604
91605         if (!_security.addChangeListener) {
91606             throw new WebAPIException(errorcode.SECURITY_ERR);
91607         }
91608
91609         t.ContactManager("addChangeListener", arguments);
91610
91611         id = ++_data.contactData.nListener;
91612         _data.contactData.listeners[id] = successCallback;
91613
91614         return id;
91615     }
91616
91617     function removeChangeListener(watchId) {
91618         if (!_security.removeChangeListener) {
91619             throw new WebAPIException(errorcode.SECURITY_ERR);
91620         }
91621
91622         if (!_data.contactData.listeners[watchId])
91623             return;
91624
91625         delete _data.contactData.listeners[watchId];
91626     }
91627
91628     function handleSubFeatures(subFeatures) {
91629         var i, subFeature;
91630
91631         for (subFeature in subFeatures) {
91632             for (i in _security[subFeature]) {
91633                 _security[_security[subFeature][i]] = true;
91634             }
91635         }
91636     }
91637
91638     _data.contactData = new ContactData();
91639
91640     contact = {
91641         getAddressBooks:       getAddressBooks,
91642         getUnifiedAddressBook: getUnifiedAddressBook,
91643         getDefaultAddressBook: getDefaultAddressBook,
91644         getAddressBook:        getAddressBook,
91645
91646         get:                   get,
91647         update:                update,
91648         updateBatch:           updateBatch,
91649         remove:                remove,
91650         removeBatch:           removeBatch,
91651         find:                  find,
91652         addChangeListener:     addChangeListener,
91653         removeChangeListener:  removeChangeListener,
91654         handleSubFeatures:     handleSubFeatures
91655     };
91656
91657     return contact;
91658 };
91659
91660 AddressBook = function (id, name, readOnly, dbContacts, dbGroups) {
91661     var addressBook,
91662         privateData = new AddressBookData(dbContacts, dbGroups);
91663
91664     // private
91665     function addNewContact(contact, external) {
91666         var added, person;
91667
91668         added = new ContactInternal(contact);
91669         privateData.contacts[added.id] = added;
91670
91671         person = new PersonBuilder(added);
91672         _data.persons[person.id] = person;
91673
91674         added.personId = person.id;
91675         added.addressBookId = id;
91676
91677         dbContacts[added.id] = _serialize(added);
91678         _data.dbStorage.persons[person.id] = _serialize(_data.persons[person.id]);
91679
91680         decorator.Contact(external, added);
91681     }
91682
91683     // public
91684     function get(id) {
91685         if (!_security.get) {
91686             throw new WebAPIException(errorcode.SECURITY_ERR);
91687         }
91688
91689         t.AddressBook("get", arguments);
91690
91691         if (privateData.contacts[id] === undefined) {
91692             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
91693         }
91694         return new Contact(privateData.contacts[id]);
91695     }
91696
91697     function add(contact) {
91698         var external = contact;
91699
91700         if (!_security.add) {
91701             throw new WebAPIException(errorcode.SECURITY_ERR);
91702         }
91703         if (addressBook.readOnly) {
91704             throw new WebAPIException(errorcode.SECURITY_ERR);
91705         }
91706
91707         t.AddressBook("add", arguments, true);
91708
91709         addNewContact(contact, external);
91710         _save();
91711
91712         window.setTimeout(function () {
91713             utils.forEach(privateData.listeners, function (listener) {
91714                 listener.oncontactsadded([new Contact(external)]);
91715             });
91716             utils.forEach(_data.contactData.listeners, function (listener) {
91717                 listener.onpersonsadded([new Person(_data.persons[external.personId])]);
91718             });
91719         }, 1);
91720     }
91721
91722     function addBatch(contacts, successCallback, errorCallback) {
91723         var external = contacts;
91724         if (!_security.addBatch) {
91725             throw new WebAPIException(errorcode.SECURITY_ERR);
91726         }
91727         if (addressBook.readOnly) {
91728             throw new WebAPIException(errorcode.SECURITY_ERR);
91729         }
91730
91731         t.AddressBook("addBatch", arguments, true);
91732
91733         window.setTimeout(function () {
91734             var i, personIds = [];
91735
91736             if (contacts.length === 0) {
91737                 if (errorCallback) {
91738                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91739                 }
91740                 return;
91741             }
91742
91743             for (i in contacts) {
91744                 addNewContact(contacts[i], external[i]);
91745                 personIds.push(external[i].personId);
91746             }
91747             _save();
91748             if (successCallback) {
91749                 successCallback(external);
91750             }
91751
91752             utils.forEach(privateData.listeners, function (listener) {
91753                 var i, watched = [];
91754
91755                 for (i in contacts) {
91756                     watched.push(new Contact(external[i]));
91757                 }
91758                 listener.oncontactsadded(watched);
91759             });
91760             utils.forEach(_data.contactData.listeners, function (listener) {
91761                 var i, watched = [];
91762
91763                 for (i in personIds) {
91764                     watched.push(new Person(_data.persons[personIds[i]]));
91765                 }
91766                 listener.onpersonsadded(watched);
91767             });
91768         }, 1);
91769     }
91770
91771     function update(contact) {
91772         var updated;
91773
91774         if (!_security.update) {
91775             throw new WebAPIException(errorcode.SECURITY_ERR);
91776         }
91777         if (addressBook.readOnly) {
91778             throw new WebAPIException(errorcode.SECURITY_ERR);
91779         }
91780
91781         t.AddressBook("update", arguments);
91782
91783         if (!contact.id) {
91784             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
91785         }
91786         if (privateData.contacts[contact.id] === undefined) {
91787             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
91788         }
91789
91790         updated = new ContactInternal(contact);
91791
91792         privateData.contacts[updated.id] = updated;
91793         dbContacts[updated.id] = _serialize(updated);
91794         _save();
91795
91796         window.setTimeout(function () {
91797             utils.forEach(privateData.listeners, function (listener) {
91798                 listener.oncontactsupdated([new Contact(updated)]);
91799             });
91800         }, 1);
91801     }
91802
91803     function updateBatch(contacts, successCallback, errorCallback) {
91804         if (!_security.updateBatch) {
91805             throw new WebAPIException(errorcode.SECURITY_ERR);
91806         }
91807         if (addressBook.readOnly) {
91808             throw new WebAPIException(errorcode.SECURITY_ERR);
91809         }
91810
91811         t.AddressBook("updateBatch", arguments, true);
91812
91813         window.setTimeout(function () {
91814             var i, updated;
91815
91816             if (contacts.length === 0) {
91817                 if (errorCallback) {
91818                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91819                 }
91820                 return;
91821             }
91822
91823             for (i in contacts) {
91824                 if (!contacts[i].id) {
91825                     if (errorCallback) {
91826                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91827                     }
91828                     return;
91829                 }
91830                 if (privateData.contacts[contacts[i].id] === undefined) {
91831                     if (errorCallback) {
91832                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
91833                     }
91834                     return;
91835                 }
91836             }
91837             for (i in contacts) {
91838                 updated = new ContactInternal(contacts[i]);
91839
91840                 privateData.contacts[updated.id] = updated;
91841                 dbContacts[updated.id] = _serialize(updated);
91842             }
91843             _save();
91844             if (successCallback) {
91845                 successCallback();
91846             }
91847
91848             utils.forEach(privateData.listeners, function (listener) {
91849                 var i, watched = [];
91850
91851                 for (i in contacts) {
91852                     watched.push(new Contact(
91853                         privateData.contacts[contacts[i].id]));
91854                 }
91855                 listener.oncontactsupdated(watched);
91856             });
91857         }, 1);
91858     }
91859
91860     function remove(id) {
91861         if (!_security.remove) {
91862             throw new WebAPIException(errorcode.SECURITY_ERR);
91863         }
91864         if (addressBook.readOnly) {
91865             throw new WebAPIException(errorcode.SECURITY_ERR);
91866         }
91867
91868         t.AddressBook("remove", arguments);
91869
91870         if (privateData.contacts[id] === undefined) {
91871             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
91872         }
91873
91874         delete privateData.contacts[id];
91875         if (dbContacts[id]) {
91876             delete dbContacts[id];
91877         }
91878         _save();
91879
91880         window.setTimeout(function () {
91881             utils.forEach(privateData.listeners, function (listener) {
91882                 listener.oncontactsremoved([id]);
91883             });
91884         }, 1);
91885     }
91886
91887     function removeBatch(ids, successCallback, errorCallback) {
91888         if (!_security.removeBatch) {
91889             throw new WebAPIException(errorcode.SECURITY_ERR);
91890         }
91891         if (addressBook.readOnly) {
91892             throw new WebAPIException(errorcode.SECURITY_ERR);
91893         }
91894
91895         t.AddressBook("removeBatch", arguments, true);
91896
91897         window.setTimeout(function () {
91898             var i;
91899
91900             if (ids.length === 0) {
91901                 if (errorCallback) {
91902                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91903                 }
91904                 return;
91905             }
91906
91907             for (i in ids) {
91908                 if (!ids[i]) {
91909                     if (errorCallback) {
91910                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91911                     }
91912                     return;
91913                 }
91914                 if (privateData.contacts[ids[i]] === undefined) {
91915                     if (errorCallback) {
91916                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
91917                     }
91918                     return;
91919                 }
91920             }
91921             for (i in ids) {
91922                 delete privateData.contacts[ids[i]];
91923                 if (dbContacts[ids[i]]) {
91924                     delete dbContacts[ids[i]];
91925                 }
91926             }
91927             _save();
91928             if (successCallback) {
91929                 successCallback();
91930             }
91931
91932             utils.forEach(privateData.listeners, function (listener) {
91933                 listener.oncontactsremoved(utils.copy(ids));
91934             });
91935         }, 1);
91936     }
91937
91938     function find(successCallback, errorCallback, filter, sortMode) {
91939         if (!_security.find) {
91940             throw new WebAPIException(errorcode.SECURITY_ERR);
91941         }
91942
91943         t.AddressBook("find", arguments, true);
91944
91945         window.setTimeout(function () {
91946             var result = [], begin, end, i, atr, _re, errFlag = false,
91947                 _rangeMatch, low, high, matched, _existMatch, _arrayMatch;
91948
91949             if (filter) {
91950                 switch (_filterType(filter)) {
91951                 case 0:
91952                     if (errorCallback) {
91953                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
91954                     }
91955                     return;
91956
91957                 case 1:
91958                     //TODO:
91959                     //"compositeFilter doesn't support"
91960                     if (errorCallback) {
91961                         errorCallback(new WebAPIError(errorcode.NOT_SUPPORTED_ERR));
91962                     }
91963                     return;
91964
91965                 case 2:
91966                 case 3:
91967                     break;
91968                 }
91969             }
91970
91971             /* return all contacts if no filter argument */
91972             if (filter === null || filter === undefined) {
91973                 utils.forEach(privateData.contacts, function (contact) {
91974                     result.push(new Contact(contact));
91975                 });
91976
91977                 successCallback(result);
91978                 return;
91979             }
91980
91981             /* check composition of filter.attributeName */
91982             switch (filter.attributeName) {
91983             case "id" :
91984             case "personId" :
91985             case "addressBookId" :
91986             case "name.prefix" :
91987             case "name.suffix" :
91988             case "name.firstName" :
91989             case "name.middleName" :
91990             case "name.lastName" :
91991             case "name.phoneticFirstName" :
91992             case "name.phoneticLastName" :
91993             case "name.displayName" :
91994             case "account.accountServiceId" :
91995             case "account.contactURI" :
91996             case "photoURI" :
91997             case "ringtoneURI" :
91998                 matched = tizen1_utils.matchAttributeFilter(privateData.contacts,
91999                         filter.attributeName, filter.matchFlag, filter.matchValue);
92000                 break;
92001
92002             case "name.nicknames" :
92003             case "notes" :
92004             case "groupIds" :
92005                 matched = tizen1_utils.matchAttributeArrayFilter(privateData.contacts,
92006                         filter.attributeName, filter.matchFlag, filter.matchValue);
92007                 break;
92008
92009             case "addresses.country" :
92010             case "addresses.region" :
92011             case "addresses.city" :
92012             case "addresses.streetAddress" :
92013             case "addresses.additionalInformation" :
92014             case "addresses.postalCode" :
92015             case "phoneNumbers.number" :
92016             case "emails.email" :
92017             case "anniversaries.label" :
92018             case "organizations.name" :
92019             case "organizations.department" :
92020             case "organizations.title" :
92021             case "organizations.role" :
92022             case "organizations.logoURI" :
92023             case "urls.url" :
92024             case "urls.type" :
92025                 atr = filter.attributeName.split(".");
92026                 _existMatch = function (obj) {
92027                     return (obj[atr[0]] !== undefined);
92028                 };
92029
92030                 if (filter.matchValue === undefined || filter.matchFlag === "EXISTS") {
92031                     matched = utils.filter(privateData.contacts, _existMatch);
92032                     break;
92033                 }
92034
92035                 errFlag = false;
92036
92037                 switch (filter.matchFlag)
92038                 {
92039                 case "EXACTLY":
92040                     _re = new RegExp("^" + filter.matchValue + "$");
92041                     break;
92042                 case "FULLSTRING":
92043                     _re = new RegExp("^" + filter.matchValue + "$", "i");
92044                     break;
92045                 case "CONTAINS":
92046                     _re = new RegExp(filter.matchValue, "i");
92047                     break;
92048                 case "STARTSWITH":
92049                     _re = new RegExp("^" + filter.matchValue, "i");
92050                     break;
92051                 case "ENDSWITH":
92052                     _re = new RegExp(filter.matchValue + "$", "i");
92053                     break;
92054                 default:
92055                     errFlag = true;
92056                 }
92057
92058                 if (errFlag) {
92059                     matched = [];
92060                     break;
92061                 }
92062
92063                 _arrayMatch = function (obj) {
92064                     return (obj[atr[0]].some(function (o) {
92065                         if (typeof o[atr[1]] !== "string") {
92066                             return false;
92067                         } else {
92068                             return (o[atr[1]].search(_re) !== -1);
92069                         }
92070                     }));
92071                 };
92072
92073                 matched = utils.filter(privateData.contacts, _arrayMatch);
92074                 break;
92075
92076             case "addresses.types" :
92077             case "phoneNumbers.types" :
92078             case "emails.types" :
92079                 atr = filter.attributeName.split(".");
92080                 _existMatch = function (obj) {
92081                     return (obj[atr[0]].some(function (o) {
92082                         return (o[atr[1]] !== undefined);
92083                     }));
92084                 };
92085
92086                 if (filter.matchValue === undefined || filter.matchFlag === "EXISTS") {
92087                     matched = utils.filter(privateData.contacts, _existMatch);
92088                     break;
92089                 }
92090
92091                 errFlag = false;
92092
92093                 switch (filter.matchFlag) {
92094                 case "EXACTLY":
92095                     _re = new RegExp("^" + filter.matchValue + "$");
92096                     break;
92097                 case "FULLSTRING":
92098                     _re = new RegExp("^" + filter.matchValue + "$", "i");
92099                     break;
92100                 case "CONTAINS":
92101                     _re = new RegExp(filter.matchValue, "i");
92102                     break;
92103                 case "STARTSWITH":
92104                     _re = new RegExp("^" + filter.matchValue, "i");
92105                     break;
92106                 case "ENDSWITH":
92107                     _re = new RegExp(filter.matchValue + "$", "i");
92108                     break;
92109                 default:
92110                     errFlag = true;
92111                 }
92112
92113                 if (errFlag) {
92114                     matched = [];
92115                     break;
92116                 }
92117
92118                 _arrayMatch = function (obj) {
92119                     return (obj[atr[0]].some(function (o) {
92120                         if (!tizen1_utils.isValidArray(o[atr[1]])) {
92121                             return false;
92122                         } else {
92123                             return (o[atr[1]].some(function (t) {
92124                                 return (t.search(_re) !== -1);
92125                             }));
92126                         }
92127                     }));
92128                 };
92129
92130                 matched = utils.filter(privateData.contacts, _arrayMatch);
92131                 break;
92132
92133             case "anniversaries.date" :
92134                 low = filter.initialValue;
92135                 high = filter.endValue;
92136                 atr = filter.attributeName.split(".");
92137
92138                 _rangeMatch = function (obj) {
92139                     var isMatched = true;
92140                     if (low !== null && low !== undefined) {
92141                         if (!tizen1_utils.isValidArray(obj[atr[0]])) {
92142                             isMatched = false;
92143                         } else {
92144                             isMatched = (obj[atr[0]].some(function (o) {
92145                                 return (o[atr[1]] >= low);
92146                             }));
92147                         }
92148                     }
92149                     if (isMatched && (high !== null && high !== undefined)) {
92150                         if (!tizen1_utils.isValidArray(obj[atr[0]])) {
92151                             isMatched = false;
92152                         } else {
92153                             isMatched = (obj[atr[0]].some(function (o) {
92154                                 return (o[atr[1]] <= high);
92155                             }));
92156                         }
92157                     }
92158                     return isMatched;
92159                 };
92160
92161                 matched = utils.filter(privateData.contacts, _rangeMatch);
92162                 break;
92163
92164             case "addresses.isDefault" :
92165             case "phoneNumbers.isDefault" :
92166             case "emails.isDefault" :
92167                 break;
92168
92169             case "isFavorite" :
92170                 if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
92171                     if (errorCallback) {
92172                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
92173                     }
92174                     return;
92175                 } else {
92176                     matched = tizen1_utils.matchAttributeBooleanFilter(privateData.contacts,
92177                             filter.attributeName, filter.matchValue);
92178                 }
92179                 break;
92180
92181             case "birthday" :
92182                 begin = filter.initialValue;
92183                 end = filter.endValue;
92184
92185                 matched = tizen1_utils.matchAttributeRangeFilter(privateData.contacts,
92186                         filter.attributeName, begin, end);
92187                 break;
92188
92189             default:
92190                 if (errorCallback) {
92191                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
92192                 }
92193                 return;
92194             }
92195
92196             if (sortMode) {
92197                 _sort(matched, sortMode);
92198             }
92199
92200             for (i in matched) {
92201                 result.push(new Contact(matched[i]));
92202             }
92203
92204             successCallback(result);
92205         }, 1);
92206     }
92207
92208     function addChangeListener(successCallback, errorCallback) {
92209         var id;
92210
92211         if (!_security.addChangeListener) {
92212             throw new WebAPIException(errorcode.SECURITY_ERR);
92213         }
92214
92215         t.AddressBook("addChangeListener", arguments);
92216
92217         id = ++privateData.nListener;
92218         privateData.listeners[id] = successCallback;
92219
92220         return id;
92221     }
92222
92223     function removeChangeListener(watchId) {
92224         if (!_security.removeChangeListener) {
92225             throw new WebAPIException(errorcode.SECURITY_ERR);
92226         }
92227
92228         if (!privateData.listeners[watchId])
92229             return;
92230
92231         delete privateData.listeners[watchId];
92232     }
92233
92234     function getGroup(groupId) {
92235         var i;
92236
92237         if (!_security.getGroup) {
92238             throw new WebAPIException(errorcode.SECURITY_ERR);
92239         }
92240
92241         t.AddressBook("getGroup", arguments);
92242
92243         for (i in privateData.groups) {
92244             if (privateData.groups[i].id === groupId)
92245                 break;
92246         }
92247         if (privateData.groups[i] === undefined) {
92248             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
92249         }
92250
92251         return new ContactGroup(privateData.groups[i]);
92252     }
92253
92254     function addGroup(group) {
92255         var external = group;
92256
92257         if (!_security.addGroup) {
92258             throw new WebAPIException(errorcode.SECURITY_ERR);
92259         }
92260
92261         t.AddressBook("addGroup", arguments, true);
92262
92263         group.id            = Math.uuid(null, 16);
92264         group.addressBookId = id;
92265
92266         external.__defineGetter__("id", function () {
92267             return group.id;
92268         });
92269
92270         external.__defineGetter__("addressBookId", function () {
92271             return group.addressBookId;
92272         });
92273
92274         privateData.groups.push(group);
92275         _save();
92276     }
92277
92278     function updateGroup(group) {
92279         var i;
92280
92281         if (!_security.updateGroup) {
92282             throw new WebAPIException(errorcode.SECURITY_ERR);
92283         }
92284
92285         t.AddressBook("updateGroup", arguments);
92286
92287         if (!group.id) {
92288             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
92289         }
92290         for (i in privateData.groups) {
92291             if (privateData.groups[i].id === group.id)
92292                 break;
92293         }
92294         if (privateData.groups[i].id === undefined) {
92295             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
92296         }
92297         if (privateData.groups[i].readOnly) {
92298             throw new WebAPIException(errorcode.SECURITY_ERR);
92299         }
92300         privateData.groups[i] = utils.copy(group);
92301         _save();
92302     }
92303
92304     function removeGroup(groupId) {
92305         var i;
92306
92307         if (!_security.removeGroup) {
92308             throw new WebAPIException(errorcode.SECURITY_ERR);
92309         }
92310
92311         t.AddressBook("removeGroup", arguments);
92312
92313         for (i in privateData.groups) {
92314             if (privateData.groups[i].id === groupId)
92315                 break;
92316         }
92317         if (privateData.groups[i].id === undefined) {
92318             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
92319         }
92320         if (privateData.groups[i].readOnly) {
92321             throw new WebAPIException(errorcode.SECURITY_ERR);
92322         }
92323
92324         privateData.groups.splice(i, 1);
92325         _save();
92326     }
92327
92328     function getGroups() {
92329         var groups = [], i;
92330
92331         if (!_security.getGroups) {
92332             throw new WebAPIException(errorcode.SECURITY_ERR);
92333         }
92334
92335         for (i in privateData.groups) {
92336             groups.push(new ContactGroup(privateData.groups[i]));
92337         }
92338         return groups;
92339     }
92340
92341     privateData.load();
92342     // Make private contacts accessible for Person methods
92343     _data.contacts[id] = privateData.contacts;
92344
92345     addressBook = {
92346         get:                  get,
92347         add:                  add,
92348         addBatch:             addBatch,
92349         update:               update,
92350         updateBatch:          updateBatch,
92351         remove:               remove,
92352         removeBatch:          removeBatch,
92353         find:                 find,
92354         addChangeListener:    addChangeListener,
92355         removeChangeListener: removeChangeListener,
92356
92357         getGroup:             getGroup,
92358         addGroup:             addGroup,
92359         updateGroup:          updateGroup,
92360         removeGroup:          removeGroup,
92361         getGroups:            getGroups
92362     };
92363
92364     addressBook.__defineGetter__("id", function () {
92365         return id;
92366     });
92367
92368     addressBook.__defineGetter__("name", function () {
92369         return name;
92370     });
92371
92372     addressBook.__defineGetter__("readOnly", function () {
92373         return readOnly;
92374     });
92375
92376     return addressBook;
92377 };
92378
92379 AddressBookData = function (contacts, groups) {
92380     var addressBookData;
92381
92382     // private
92383     function loadContacts() {
92384         for (var i in contacts) {
92385             addressBookData.contacts[i] = new ContactInternal(contacts[i]);
92386         }
92387     }
92388
92389     function loadGroups() {
92390         addressBookData.groups = groups;
92391     }
92392
92393     // public
92394     function load() {
92395         loadContacts();
92396         loadGroups();
92397     }
92398
92399     addressBookData = {
92400         contacts:  {},
92401         groups:    [],
92402         listeners: {},
92403         nListener: 0,
92404         load:      load
92405     };
92406
92407     return addressBookData;
92408 };
92409
92410 AddressBookStorage = function (id, name, readOnly, contacts, groups) {
92411     this.id       = id;
92412     this.name     = name;
92413     this.readOnly = readOnly;
92414     this.contacts = contacts;
92415     this.groups   = groups;
92416 };
92417
92418 Contact = function (contact) {
92419     var i, attr, arr;
92420
92421     this.name          = null;
92422     this.addresses     = [];
92423     this.photoURI      = null;
92424     this.phoneNumbers  = [];
92425     this.emails        = [];
92426     this.birthday      = null;
92427     this.anniversaries = [];
92428     this.organizations = [];
92429     this.notes         = [];
92430     this.urls          = [];
92431     this.ringtoneURI   = null;
92432     this.groupIds      = [];
92433
92434     for (attr in contact) {
92435         switch (attr) {
92436         case "name":
92437             this[attr] = new ContactName(contact[attr]);
92438             break;
92439
92440         case "addresses":
92441             arr = contact[attr];
92442             if (arr) {
92443                 for (i in arr) {
92444                     this[attr][i] = new ContactAddress(arr[i]);
92445                 }
92446             }
92447             break;
92448
92449         case "phoneNumbers":
92450             arr = contact[attr];
92451             if (arr) {
92452                 for (i in arr) {
92453                     this[attr][i] = new ContactPhoneNumber(arr[i].number,
92454                             arr[i].types || null, arr[i].isDefault || null);
92455                 }
92456             }
92457             break;
92458
92459         case "emails":
92460             arr = contact[attr];
92461             if (arr) {
92462                 for (i in arr) {
92463                     this[attr][i] = new ContactEmailAddress(arr[i].email,
92464                             arr[i].types || null, arr[i].isDefault || null);
92465                 }
92466             }
92467             break;
92468
92469         case "birthday":
92470             this[attr] = new Date(contact[attr]);
92471             break;
92472
92473         case "anniversaries":
92474             arr = contact[attr];
92475             if (arr) {
92476                 for (i in arr) {
92477                     if (!tizen1_utils.isValidDate(arr[i].date)) {
92478                         arr[i].date = new Date(arr[i].date);
92479                     }
92480                     this[attr][i] = new ContactAnniversary(arr[i].date,
92481                             arr[i].label || null);
92482                 }
92483             }
92484             break;
92485
92486         case "organizations":
92487             arr = contact[attr];
92488             if (arr) {
92489                 for (i in arr) {
92490                     this[attr][i] = new ContactOrganization(arr[i]);
92491                 }
92492             }
92493             break;
92494
92495         case "notes":
92496         case "groupIds":
92497             arr = contact[attr];
92498             if (arr) {
92499                 for (i in arr) {
92500                     this[attr][i] = arr[i];
92501                 }
92502             }
92503             break;
92504
92505         case "urls":
92506             arr = contact[attr];
92507             if (arr) {
92508                 for (i in arr) {
92509                     this[attr][i] = new ContactWebSite(arr[i].url,
92510                             arr[i].type || null);
92511                 }
92512             }
92513             break;
92514
92515         default:
92516             this[attr] = contact[attr];
92517             break;
92518         }
92519     }
92520
92521     decorator.Contact(this, contact);
92522     this.__proto__ = tizen.Contact.prototype;
92523 };
92524
92525 ContactInternal = function (contact) {
92526     var attr;
92527
92528     for (attr in contact) {
92529         this[attr] = contact[attr];
92530     }
92531
92532     if (!contact.id) {
92533         this.id = Math.uuid(null, 16);
92534         this.lastUpdated = new Date();
92535     } else {
92536         this.lastUpdated = new Date(contact.lastUpdated);
92537     }
92538
92539     if (this.name) {
92540         this.name.__defineGetter__("displayName", function () {
92541             var displayName = "";
92542
92543             if (!this)
92544                 return "";
92545
92546             if ((this.firstName !== null) &&
92547                 (this.lastName !== null)) {
92548                 displayName = [this.firstName, this.middleName, this.lastName];
92549                 displayName = displayName.join(" ").replace(/ +/g, " ").trim();
92550             } else if (this.nicknames.length !== 0) {
92551                 this.nicknames.some(function (nickname) {
92552                     displayName = nickname;
92553                     return displayName;
92554                 });
92555             }
92556
92557             return displayName;
92558         });
92559     }
92560 };
92561
92562 ContactData = function () {
92563     this.listeners = {};
92564     this.nListener = 0;
92565 };
92566
92567 ContactGroup = function (groupInitDict) {
92568     var id, addressBookId, readOnly;
92569
92570     this.__defineGetter__("id", function () {
92571         return id;
92572     });
92573
92574     this.__defineGetter__("addressBookId", function () {
92575         return addressBookId;
92576     });
92577
92578     this.__defineGetter__("readOnly", function () {
92579         return readOnly;
92580     });
92581
92582     id               = groupInitDict.id || null;
92583     addressBookId    = groupInitDict.addressBookId || null;
92584     readOnly         = groupInitDict.readOnly || false;
92585
92586     this.name        = groupInitDict.name || "";
92587     this.ringtoneURI = groupInitDict.ringtoneURI || null;
92588     this.photoURI    = groupInitDict.photoURI || null;
92589
92590     this.__proto__ = tizen.ContactGroup.prototype;
92591 };
92592
92593 Person = function (personInitDict) {
92594     var person = {};
92595
92596     function hasContactMethod(method) {
92597         var idab, idc, contact, count = 0;
92598
92599         for (idab in _data.contacts) {
92600             for (idc in _data.contacts[idab]) {
92601                 contact = _data.contacts[idab][idc];
92602                 if (contact.personId === person.id) {
92603                     count += contact[method].length;
92604                 }
92605             }
92606         }
92607
92608         return (count !== 0);
92609     }
92610
92611     person.id               = personInitDict.id || Math.uuid(null, 16);
92612     person.isFavorite       = personInitDict.isFavorite || false;
92613     person.photoURI         = personInitDict.photoURI || null;
92614     person.ringtoneURI      = personInitDict.ringtoneURI || null;
92615     person.displayContactId = personInitDict.displayContactId;
92616
92617     this.__defineGetter__("id", function () {
92618         return person.id;
92619     });
92620
92621     this.__defineGetter__("displayName", function () {
92622         var idab, contact, displayName = "";
92623
92624         for (idab in _data.contacts) {
92625             contact = _data.contacts[idab][this.displayContactId];
92626
92627             if (contact !== undefined) {
92628                 if (contact.name && contact.name.displayName) {
92629                     displayName = contact.name.displayName;
92630                 }
92631                 break;
92632             }
92633         }
92634
92635         return displayName;
92636     });
92637
92638     this.__defineGetter__("contactCount", function () {
92639         var idab, idc, contactCount = 0;
92640
92641         for (idab in _data.contacts) {
92642             for (idc in _data.contacts[idab]) {
92643                 if (_data.contacts[idab][idc].personId === person.id) {
92644                     ++contactCount;
92645                 }
92646             }
92647         }
92648
92649         return contactCount;
92650     });
92651
92652     this.__defineGetter__("hasPhoneNumber", function () {
92653         return hasContactMethod("phoneNumbers");
92654     });
92655
92656     this.__defineGetter__("hasEmail", function () {
92657         return hasContactMethod("emails");
92658     });
92659
92660     this.__defineGetter__("isFavorite", function () {
92661         return person.isFavorite;
92662     });
92663     this.__defineSetter__("isFavorite", function (val) {
92664         try {
92665             person.isFavorite = t.boolean(val);
92666         } catch (e) {
92667         }
92668     });
92669
92670     this.__defineGetter__("photoURI", function () {
92671         return person.photoURI;
92672     });
92673     this.__defineSetter__("photoURI", function (val) {
92674         try {
92675             person.photoURI = t.DOMString(val, "?");
92676         } catch (e) {
92677         }
92678     });
92679
92680     this.__defineGetter__("ringtoneURI", function () {
92681         return person.ringtoneURI;
92682     });
92683     this.__defineSetter__("ringtoneURI", function (val) {
92684         try {
92685             person.ringtoneURI = t.DOMString(val, "?");
92686         } catch (e) {
92687         }
92688     });
92689
92690     this.__defineGetter__("displayContactId", function () {
92691         return person.displayContactId;
92692     });
92693     this.__defineSetter__("displayContactId", function (val) {
92694         try {
92695             person.displayContactId = t.ContactId(val);
92696         } catch (e) {
92697         }
92698     });
92699
92700     this.link = function (personId) {
92701         if (!_security.link) {
92702             throw new WebAPIException(errorcode.SECURITY_ERR);
92703         }
92704
92705         t.Person("link", arguments);
92706
92707         if (_data.persons[personId] === undefined) {
92708             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
92709         }
92710
92711         _replacePerson(personId, person.id);
92712         _save();
92713     };
92714
92715     this.unlink = function (contactId) {
92716         var idab, contact, separated, i, dbAddressBook;
92717
92718         if (!_security.unlink) {
92719             throw new WebAPIException(errorcode.SECURITY_ERR);
92720         }
92721
92722         t.Person("unlink", arguments);
92723
92724         for (idab in _data.contacts) {
92725             if (_data.contacts[idab][contactId] !== undefined) {
92726                 contact = _data.contacts[idab][contactId];
92727                 break;
92728             }
92729         }
92730
92731         if (contact === undefined) {
92732             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
92733         }
92734         if (contact.personId !== person.id) {
92735             throw new WebAPIException(errorcode.UNKNOWN_ERR);
92736         }
92737
92738         separated = new PersonBuilder(contact);
92739         _data.persons[separated.id] = separated;
92740         contact.personId = separated.id;
92741
92742         _data.dbStorage.persons[separated.id] = _serialize(separated);
92743         for (i in _data.dbStorage.addressBooks) {
92744             dbAddressBook = _data.dbStorage.addressBooks[i];
92745             if (dbAddressBook.id === idab) {
92746                 dbAddressBook.contacts[contact.id].personId = separated.id;
92747                 break;
92748             }
92749         }
92750         _save();
92751
92752         return separated;
92753     };
92754 };
92755
92756 PersonBuilder = function (contact) {
92757     var person, personInitDict = {};
92758
92759     personInitDict.displayContactId = contact.id;
92760     person = new Person(personInitDict);
92761
92762     return person;
92763 };
92764
92765 module.exports = _self;
92766
92767 });
92768 define('ripple/platform/tizen/2.0/content', function (require, exports, module) {
92769 /*
92770  *  Copyright 2013 Intel Corporation
92771  *
92772  * Licensed under the Apache License, Version 2.0 (the "License");
92773  * you may not use this file except in compliance with the License.
92774  * You may obtain a copy of the License at
92775  *
92776  * http://www.apache.org/licenses/LICENSE-2.0
92777  *
92778  * Unless required by applicable law or agreed to in writing, software
92779  * distributed under the License is distributed on an "AS IS" BASIS,
92780  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
92781  * See the License for the specific language governing permissions and
92782  * limitations under the License.
92783  */
92784
92785 var db = require('ripple/db'),
92786     utils = require('ripple/utils'),
92787     dbfs = require('ripple/platform/tizen/2.0/dbfs'),
92788     dbinit = require('ripple/platform/tizen/2.0/dbinit'),
92789     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
92790     t = require('ripple/platform/tizen/2.0/typecast'),
92791     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
92792     SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
92793     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
92794     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
92795     Content,
92796     ContentDirectory,
92797     ContentFactory,
92798     ContentStorage,
92799     AudioContent,
92800     ImageContent,
92801     VideoContent,
92802     ContentInternal,
92803     ContentDirectoryInternal,
92804     AudioContentInternal,
92805     ImageContentInternal,
92806     VideoContentInternal,
92807     AudioContentLyrics,
92808     _data = {
92809         DB_CONTENT_KEY: "tizen1-db-content",
92810         content:        {},
92811         listener:       null,
92812         dbStorage:      null
92813     },
92814     _security = {
92815         "http://tizen.org/privilege/content.read": ["find",
92816             "setChangeListener", "unsetChangeListener"],
92817         "http://tizen.org/privilege/content.write": ["update", "updateBatch",
92818             "scanFile"]
92819     },
92820     _self;
92821
92822 function _get() {
92823     _data.dbStorage = db.retrieveObject(_data.DB_CONTENT_KEY) || dbinit.Content;
92824 }
92825
92826 function _save() {
92827     db.saveObject(_data.DB_CONTENT_KEY, _data.dbStorage);
92828 }
92829
92830 function _initialize() {
92831     _get();
92832
92833     if (!_data.dbStorage)
92834         return;
92835
92836     utils.forEach(_data.dbStorage, function (content) {
92837         _data.content[content.directoryURI] = new ContentStorage(content);
92838     });
92839
92840     _data.dbStorage = _data.content;
92841     _save();
92842 }
92843
92844 _self = function () {
92845     var content;
92846
92847     // private
92848     function getType(file) {
92849         var extName, type;
92850
92851         extName = file.substr(file.lastIndexOf(".") + 1).toLowerCase();
92852
92853         switch (extName) {
92854         case "bmp":
92855         case "gif":
92856         case "jpeg":
92857         case "jpg":
92858         case "png":
92859             type = "IMAGE";
92860             break;
92861
92862         case "avi":
92863         case "mpeg":
92864         case "mpg":
92865         case "wmv":
92866         case "mp4":
92867             type = "VIDEO";
92868             break;
92869
92870         case "wav":
92871         case "mp3":
92872             type = "AUDIO";
92873             break;
92874
92875         default:
92876             type = "OTHER";
92877             break;
92878         }
92879
92880         return type;
92881     }
92882
92883     function getMimeType(file) {
92884         var mimeTypeTab = {
92885             IMAGE: "image/x-msimage",
92886             VIDEO: "video/x-msvideo",
92887             AUDIO: "audio/x-msaudio",
92888             OTHER: "other/unknown"
92889         };
92890
92891         return mimeTypeTab[getType(file)];
92892     }
92893
92894     function getTitle(file) {
92895         var title;
92896
92897         title = file.substr(0, file.lastIndexOf("."));
92898         title = title.charAt(0).toUpperCase() + title.substr(1).toLowerCase();
92899
92900         return title;
92901     }
92902
92903     function getDirectoryURI(contentURI) {
92904         return contentURI.slice(0, contentURI.lastIndexOf("/") + 1)
92905                 .replace(/file:\/\//, "");
92906     }
92907
92908     function extractProperties(entry) {
92909         var contentInitDict = {};
92910
92911         contentInitDict.editableAttributes = ["name", "title", "description",
92912                 "rating"];
92913         contentInitDict.name               = entry.name;
92914         contentInitDict.type               = getType(entry.name);
92915         contentInitDict.mimeType           = getMimeType(entry.name);
92916         contentInitDict.title              = getTitle(entry.name);
92917         contentInitDict.contentURI         = entry.fullPath ?
92918                 "file://" + entry.fullPath : entry.fullPath;
92919         contentInitDict.thumbnailURIs      = [entry.fullPath];
92920         contentInitDict.releaseDate        = entry.lastModifiedDate;
92921         contentInitDict.modifiedDate       = entry.lastModifiedDate;
92922         contentInitDict.size               = 1048576;
92923
92924         return contentInitDict;
92925     }
92926
92927     function updateContents(contents, successCallback, errorCallback) {
92928         var i, isFound = false, dir, matched = [];
92929
92930         for (i in contents) {
92931             dir = getDirectoryURI(contents[i].contentURI);
92932
92933             isFound = ((dir in _data.content) && (contents[i].contentURI in
92934                     _data.content[dir].contents));
92935
92936             if (!isFound)
92937                 break;
92938
92939             matched.push(dir);
92940         }
92941
92942         if (!isFound) {
92943             if (errorCallback) {
92944                 errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
92945             }
92946             return;
92947         }
92948
92949         for (i in matched) {
92950             _data.content[matched[i]].contents[contents[i].contentURI] =
92951                     new ContentFactory(contents[i], true);
92952         }
92953
92954         _save();
92955
92956         if (successCallback) {
92957             successCallback();
92958         }
92959
92960         if (_data.listener !== null) {
92961             for (i in matched) {
92962                 _data.listener.oncontentupdated(new ContentFactory(_data
92963                         .content[matched[i]].contents[contents[i].contentURI],
92964                         false));
92965             }
92966         }
92967     }
92968
92969     // public
92970     function update(content) {
92971         if (!_security.update) {
92972             throw new WebAPIException(errorcode.SECURITY_ERR);
92973         }
92974
92975         t.ContentManager("update", arguments);
92976
92977         updateContents([content]);
92978     }
92979
92980     function updateBatch(contents, successCallback, errorCallback) {
92981         if (!_security.updateBatch) {
92982             throw new WebAPIException(errorcode.SECURITY_ERR);
92983         }
92984
92985         t.ContentManager("updateBatch", arguments);
92986
92987         window.setTimeout(function () {
92988             updateContents(contents, successCallback, errorCallback);
92989         }, 1);
92990     }
92991
92992     function getDirectories(successCallback, errorCallback) {
92993         t.ContentManager("getDirectories", arguments);
92994
92995         window.setTimeout(function () {
92996             var i, directories = [];
92997
92998             for (i in _data.content) {
92999                 directories.push(new ContentDirectory(_data.content[i]));
93000             }
93001
93002             if (directories.length === 0) {
93003                 if (errorCallback) {
93004                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
93005                 }
93006                 return;
93007             }
93008
93009             successCallback(directories);
93010         }, 1);
93011     }
93012
93013     function find(successCallback, errorCallback, directoryId, filter, sortMode,
93014             count, offset) {
93015         if (!_security.find) {
93016             throw new WebAPIException(errorcode.SECURITY_ERR);
93017         }
93018
93019         t.ContentManager("find", arguments);
93020
93021         window.setTimeout(function () {
93022             var i, dir, contents = [], results = [], matchedDir;
93023
93024             if (!directoryId) {
93025                 for (dir in _data.content) {
93026                     for (i in _data.content[dir].contents) {
93027                         contents.push(_data.content[dir].contents[i]);
93028                     }
93029                 }
93030             } else {
93031                 for (dir in _data.content) {
93032                     if (_data.content[dir].id === directoryId) {
93033                         matchedDir = dir;
93034                         break;
93035                     }
93036                 }
93037
93038                 if (!matchedDir) {
93039                     if (errorCallback) {
93040                         errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
93041                     }
93042                     return;
93043                 }
93044
93045                 for (i in _data.content[matchedDir].contents) {
93046                     contents.push(_data.content[matchedDir].contents[i]);
93047                 }
93048             }
93049
93050             if (contents.length === 0) {
93051                 if (errorCallback) {
93052                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
93053                 }
93054                 return;
93055             }
93056
93057             contents = tizen1_utils.query(contents, filter, sortMode, count,
93058                     offset);
93059
93060             contents.forEach(function (content) {
93061                 results.push(new ContentFactory(content, false));
93062             });
93063
93064             successCallback(results);
93065         }, 1);
93066     }
93067
93068     function scanFile(contentURI, successCallback, errorCallback) {
93069         var dir, isFound;
93070
93071         function onStatSuccess(entry) {
93072             var contentInitDict, content;
93073
93074             if (isFound) {
93075                 content = new ContentFactory(_data.content[dir]
93076                         .contents[contentURI], true);
93077             } else {
93078                 contentInitDict = extractProperties(entry);
93079                 content = new ContentFactory(contentInitDict, true);
93080                 _data.content[dir].contents[contentURI] = content;
93081             }
93082
93083             _save();
93084
93085             if (successCallback) {
93086                 successCallback(contentURI);
93087             }
93088
93089             if (_data.listener !== null) {
93090                 if (isFound) {
93091                     _data.listener.oncontentupdated(
93092                             new ContentFactory(content, false));
93093                 } else {
93094                     _data.listener.oncontentadded(
93095                             new ContentFactory(content, false));
93096                 }
93097             }
93098         }
93099
93100         function onStatError() {
93101             if (isFound) {
93102                 delete _data.content[dir].contents[contentURI];
93103                 _save();
93104
93105                 if (successCallback) {
93106                     successCallback(contentURI);
93107                 }
93108
93109                 if (_data.listener !== null) {
93110                     _data.listener.oncontentremoved(_data.content[dir]
93111                             .contents[contentURI].id);
93112                 }
93113             } else if (errorCallback) {
93114                 errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
93115             }
93116         }
93117
93118         if (!_security.scanFile) {
93119             throw new WebAPIException(errorcode.SECURITY_ERR);
93120         }
93121
93122         t.ContentManager("scanFile", arguments);
93123
93124         window.setTimeout(function () {
93125             dir = getDirectoryURI(contentURI);
93126
93127             isFound = ((dir in _data.content) &&
93128                     (contentURI in _data.content[dir].contents));
93129
93130             dbfs.stat(contentURI.replace(/file:\/\//, ""), onStatSuccess,
93131                     onStatError);
93132         }, 1);
93133     }
93134
93135     function setChangeListener(changeCallback) {
93136         if (!_security.setChangeListener) {
93137             throw new WebAPIException(errorcode.SECURITY_ERR);
93138         }
93139
93140         t.ContentManager("setChangeListener", arguments);
93141
93142         _data.listener = changeCallback;
93143     }
93144
93145     function unsetChangeListener() {
93146         if (!_security.unsetChangeListener) {
93147             throw new WebAPIException(errorcode.SECURITY_ERR);
93148         }
93149
93150         _data.listener = null;
93151     }
93152
93153     function handleSubFeatures(subFeatures) {
93154         var i, subFeature;
93155
93156         for (subFeature in subFeatures) {
93157             for (i in _security[subFeature]) {
93158                 _security[_security[subFeature][i]] = true;
93159             }
93160         }
93161     }
93162
93163     content = {
93164         update:              update,
93165         updateBatch:         updateBatch,
93166         getDirectories:      getDirectories,
93167         find:                find,
93168         scanFile:            scanFile,
93169         setChangeListener:   setChangeListener,
93170         unsetChangeListener: unsetChangeListener,
93171         handleSubFeatures:   handleSubFeatures
93172     };
93173
93174     return content;
93175 };
93176
93177 ContentDirectoryInternal = function (contentDirectoryInitDict) {
93178     this.id           = contentDirectoryInitDict.id || null;
93179     this.directoryURI = contentDirectoryInitDict.directoryURI || null;
93180     this.title        = contentDirectoryInitDict.title || "";
93181     this.storageType  = contentDirectoryInitDict.storageType || "INTERNAL";
93182     this.modifiedDate = contentDirectoryInitDict.modifiedDate ?
93183             new Date(contentDirectoryInitDict.modifiedDate) : null;
93184 };
93185
93186 ContentDirectory = function (contentDirectoryInitDict) {
93187     var contentDirectory = {};
93188
93189     contentDirectory.id           = contentDirectoryInitDict.id || null;
93190     contentDirectory.directoryURI = contentDirectoryInitDict.directoryURI || null;
93191     contentDirectory.title        = contentDirectoryInitDict.title || "";
93192     contentDirectory.storageType  = contentDirectoryInitDict.storageType || "INTERNAL";
93193     contentDirectory.modifiedDate = contentDirectoryInitDict.modifiedDate ?
93194             new Date(contentDirectoryInitDict.modifiedDate) : null;
93195
93196     this.__defineGetter__("id", function () {
93197         return contentDirectory.id;
93198     });
93199
93200     this.__defineGetter__("directoryURI", function () {
93201         return contentDirectory.directoryURI;
93202     });
93203
93204     this.__defineGetter__("title", function () {
93205         return contentDirectory.title;
93206     });
93207
93208     this.__defineGetter__("storageType", function () {
93209         return contentDirectory.storageType;
93210     });
93211
93212     this.__defineGetter__("modifiedDate", function () {
93213         return contentDirectory.modifiedDate;
93214     });
93215 };
93216
93217 ContentInternal = function (contentInitDict) {
93218     this.editableAttributes = contentInitDict.editableAttributes || [];
93219     this.id                 = contentInitDict.id || Math.uuid(null, 16);
93220     this.type               = contentInitDict.type || "IMAGE";
93221     this.mimeType           = contentInitDict.mimeType || "";
93222     this.title              = contentInitDict.title || "";
93223     this.contentURI         = contentInitDict.contentURI || "";
93224     this.thumbnailURIs      = contentInitDict.thumbnailURIs || null;
93225     this.releaseDate        = contentInitDict.releaseDate ?
93226             new Date(contentInitDict.releaseDate) : null;
93227     this.modifiedDate       = contentInitDict.modifiedDate ?
93228             new Date(contentInitDict.modifiedDate) : null;
93229     this.size               = contentInitDict.size || 0;
93230     this.name               = contentInitDict.name || "";
93231     this.description        = contentInitDict.description || null;
93232     this.rating             = contentInitDict.rating || 0;
93233 };
93234
93235 Content = function (contentInitDict) {
93236     var content = {};
93237
93238     content.editableAttributes = contentInitDict.editableAttributes || [];
93239     content.id                 = contentInitDict.id || Math.uuid(null, 16);
93240     content.name               = contentInitDict.name || "";
93241     content.type               = contentInitDict.type || "IMAGE";
93242     content.mimeType           = contentInitDict.mimeType || "";
93243     content.title              = contentInitDict.title || "";
93244     content.contentURI         = contentInitDict.contentURI || "";
93245     content.thumbnailURIs      = contentInitDict.thumbnailURIs || null;
93246     content.releaseDate        = contentInitDict.releaseDate ?
93247             new Date(contentInitDict.releaseDate) : null;
93248     content.modifiedDate       = contentInitDict.modifiedDate ?
93249             new Date(contentInitDict.modifiedDate) : null;
93250     content.size               = contentInitDict.size || 0;
93251     content.description        = contentInitDict.description || null;
93252     content.rating             = contentInitDict.rating || 0;
93253
93254     this.__defineGetter__("editableAttributes", function () {
93255         return content.editableAttributes;
93256     });
93257
93258     this.__defineGetter__("id", function () {
93259         return content.id;
93260     });
93261
93262     this.__defineGetter__("name", function () {
93263         return content.name;
93264     });
93265     this.__defineSetter__("name", function (val) {
93266         try {
93267             content.name = t.DOMString(val);
93268         } catch (e) {
93269         }
93270     });
93271
93272     this.__defineGetter__("type", function () {
93273         return content.type;
93274     });
93275
93276     this.__defineGetter__("mimeType", function () {
93277         return content.mimeType;
93278     });
93279
93280     this.__defineGetter__("title", function () {
93281         return content.title;
93282     });
93283
93284     this.__defineGetter__("contentURI", function () {
93285         return content.contentURI;
93286     });
93287
93288     this.__defineGetter__("thumbnailURIs", function () {
93289         return content.thumbnailURIs;
93290     });
93291
93292     this.__defineGetter__("releaseDate", function () {
93293         return content.releaseDate;
93294     });
93295
93296     this.__defineGetter__("modifiedDate", function () {
93297         return content.modifiedDate;
93298     });
93299
93300     this.__defineGetter__("size", function () {
93301         return content.size;
93302     });
93303
93304     this.__defineGetter__("description", function () {
93305         return content.description;
93306     });
93307     this.__defineSetter__("description", function (val) {
93308         try {
93309             content.description = t.DOMString(val, "?");
93310         } catch (e) {
93311         }
93312     });
93313
93314     this.__defineGetter__("rating", function () {
93315         return content.rating;
93316     });
93317     this.__defineSetter__("rating", function (val) {
93318         try {
93319             val = t.unsigned_long(val);
93320             if ((val < 0) || (val > 10))
93321                 return;
93322             content.rating = val;
93323         } catch (e) {
93324         }
93325     });
93326 };
93327
93328 VideoContentInternal = function (videoContentInitDict) {
93329     ContentInternal.call(this, videoContentInitDict);
93330
93331     this.album       = videoContentInitDict.album || null;
93332     this.artists     = videoContentInitDict.artists || null;
93333     this.duration    = videoContentInitDict.duration || 0;
93334     this.width       = videoContentInitDict.width || 0;
93335     this.height      = videoContentInitDict.height || 0;
93336     this.geolocation = null;
93337
93338     if (videoContentInitDict.geolocation) {
93339         this.geolocation = new SimpleCoordinates(
93340                 videoContentInitDict.geolocation.latitude || null,
93341                 videoContentInitDict.geolocation.longitude || null);
93342     }
93343 };
93344
93345 VideoContent = function (videoContentInitDict) {
93346     var videoContent = {};
93347
93348     Content.call(this, videoContentInitDict);
93349
93350     videoContent.album       = videoContentInitDict.album || null;
93351     videoContent.artists     = videoContentInitDict.artists || null;
93352     videoContent.duration    = videoContentInitDict.duration || 0;
93353     videoContent.width       = videoContentInitDict.width || 0;
93354     videoContent.height      = videoContentInitDict.height || 0;
93355     videoContent.geolocation = null;
93356
93357     if (videoContentInitDict.geolocation) {
93358         videoContent.geolocation = new SimpleCoordinates(
93359                 videoContentInitDict.geolocation.latitude,
93360                 videoContentInitDict.geolocation.longitude);
93361     }
93362
93363     this.__defineGetter__("geolocation", function () {
93364         return videoContent.geolocation;
93365     });
93366     this.__defineSetter__("geolocation", function (val) {
93367         try {
93368             videoContent.geolocation = t.SimpleCoordinates(val, "?");
93369         } catch (e) {
93370         }
93371     });
93372
93373     this.__defineGetter__("album", function () {
93374         return videoContent.album;
93375     });
93376
93377     this.__defineGetter__("artists", function () {
93378         return videoContent.artists;
93379     });
93380
93381     this.__defineGetter__("duration", function () {
93382         return videoContent.duration;
93383     });
93384
93385     this.__defineGetter__("width", function () {
93386         return videoContent.width;
93387     });
93388
93389     this.__defineGetter__("height", function () {
93390         return videoContent.height;
93391     });
93392 };
93393
93394 AudioContentInternal = function (audioContentInitDict) {
93395     ContentInternal.call(this, audioContentInitDict);
93396
93397     this.album       = audioContentInitDict.album || null;
93398     this.genres      = audioContentInitDict.genres || null;
93399     this.artists     = audioContentInitDict.artists || null;
93400     this.composers   = audioContentInitDict.composers || null;
93401     this.lyrics      = audioContentInitDict.lyrics ?
93402             new AudioContentLyrics(audioContentInitDict.lyrics) : null;
93403     this.copyright   = audioContentInitDict.copyright || null;
93404     this.bitrate     = audioContentInitDict.bitrate || 0;
93405     this.trackNumber = audioContentInitDict.trackNumber || null;
93406     this.duration    = audioContentInitDict.duration || 0;
93407 };
93408
93409 AudioContentLyrics = function (lyrics) {
93410     var audioContentLyrics = {};
93411
93412     audioContentLyrics.type       = lyrics.type;
93413     audioContentLyrics.texts      = lyrics.texts;
93414     audioContentLyrics.timestamps = (lyrics.type === "SYNCHRONIZED") ?
93415             lyrics.timestamps : undefined;
93416
93417     this.__defineGetter__("type", function () {
93418         return audioContentLyrics.type;
93419     });
93420
93421     this.__defineGetter__("texts", function () {
93422         return audioContentLyrics.texts;
93423     });
93424
93425     this.__defineGetter__("timestamps", function () {
93426         return audioContentLyrics.timestamps;
93427     });
93428 };
93429
93430 AudioContent = function (audioContentInitDict) {
93431     var audioContent = {};
93432
93433     Content.call(this, audioContentInitDict);
93434
93435     audioContent.album       = audioContentInitDict.album || null;
93436     audioContent.genres      = audioContentInitDict.genres || null;
93437     audioContent.artists     = audioContentInitDict.artists || null;
93438     audioContent.composers   = audioContentInitDict.composers || null;
93439     audioContent.lyrics      = audioContentInitDict.lyrics ?
93440             new AudioContentLyrics(audioContentInitDict.lyrics) : null;
93441     audioContent.copyright   = audioContentInitDict.copyright || null;
93442     audioContent.bitrate     = audioContentInitDict.bitrate || 0;
93443     audioContent.trackNumber = audioContentInitDict.trackNumber || null;
93444     audioContent.duration    = audioContentInitDict.duration || 0;
93445
93446     this.__defineGetter__("album", function () {
93447         return audioContent.album;
93448     });
93449
93450     this.__defineGetter__("genres", function () {
93451         return audioContent.genres;
93452     });
93453
93454     this.__defineGetter__("artists", function () {
93455         return audioContent.artists;
93456     });
93457
93458     this.__defineGetter__("composers", function () {
93459         return audioContent.composers;
93460     });
93461
93462     this.__defineGetter__("lyrics", function () {
93463         return audioContent.lyrics;
93464     });
93465
93466     this.__defineGetter__("copyright", function () {
93467         return audioContent.copyright;
93468     });
93469
93470     this.__defineGetter__("bitrate", function () {
93471         return audioContent.bitrate;
93472     });
93473
93474     this.__defineGetter__("trackNumber", function () {
93475         return audioContent.trackNumber;
93476     });
93477
93478     this.__defineGetter__("duration", function () {
93479         return audioContent.duration;
93480     });
93481 };
93482
93483 ImageContentInternal = function (imageContentInitDict) {
93484     ContentInternal.call(this, imageContentInitDict);
93485
93486     this.geolocation = null;
93487     this.width       = imageContentInitDict.width || 0;
93488     this.height      = imageContentInitDict.height || 0;
93489     this.orientation = imageContentInitDict.orientation || "NORMAL";
93490
93491     if (imageContentInitDict.geolocation) {
93492         this.geolocation = new SimpleCoordinates(
93493                 imageContentInitDict.geolocation.latitude,
93494                 imageContentInitDict.geolocation.longitude);
93495     }
93496 };
93497
93498 ImageContent = function (imageContentInitDict) {
93499     var imageContent = {};
93500
93501     Content.call(this, imageContentInitDict);
93502
93503     imageContent.width       = imageContentInitDict.width || 0;
93504     imageContent.height      = imageContentInitDict.height || 0;
93505     imageContent.geolocation = null;
93506     imageContent.orientation = imageContentInitDict.orientation || "NORMAL";
93507
93508     if (imageContentInitDict.geolocation) {
93509         imageContent.geolocation = new SimpleCoordinates(
93510                 imageContentInitDict.geolocation.latitude,
93511                 imageContentInitDict.geolocation.longitude);
93512     }
93513
93514     this.__defineGetter__("geolocation", function () {
93515         return imageContent.geolocation;
93516     });
93517     this.__defineSetter__("geolocation", function (val) {
93518         try {
93519             imageContent.geolocation = t.SimpleCoordinates(val, "?");
93520         } catch (e) {
93521         }
93522     });
93523
93524     this.__defineGetter__("width", function () {
93525         return imageContent.width;
93526     });
93527
93528     this.__defineGetter__("height", function () {
93529         return imageContent.height;
93530     });
93531
93532     this.__defineGetter__("orientation", function () {
93533         return imageContent.orientation;
93534     });
93535     this.__defineSetter__("orientation", function (val) {
93536         try {
93537             imageContent.orientation = t.ImageContentOrientation(val);
93538         } catch (e) {
93539         }
93540     });
93541 };
93542
93543 ContentFactory = function (contentInitDict, isInternal) {
93544     var ContentType;
93545
93546     switch (contentInitDict.type) {
93547     case "IMAGE":
93548         ContentType = isInternal ? ImageContentInternal : ImageContent;
93549         break;
93550
93551     case "VIDEO":
93552         ContentType = isInternal ? VideoContentInternal : VideoContent;
93553         break;
93554
93555     case "AUDIO":
93556         ContentType = isInternal ? AudioContentInternal : AudioContent;
93557         break;
93558
93559     default:
93560         ContentType = isInternal ? ContentInternal : Content;
93561         break;
93562     }
93563
93564     return new ContentType(contentInitDict);
93565 };
93566
93567 ContentStorage = function (content) {
93568     var i;
93569
93570     ContentDirectoryInternal.call(this, content);
93571     this.contents = {};
93572
93573     for (i in content.contents) {
93574         this.contents[i] = new ContentFactory(content.contents[i], true);
93575     }
93576 };
93577
93578 _initialize();
93579
93580 module.exports = _self;
93581
93582 });
93583 define('ripple/platform/tizen/2.0/datacontrol', function (require, exports, module) {
93584 /*
93585  *  Copyright 2013 Intel Corporation
93586  *
93587  * Licensed under the Apache License, Version 2.0 (the "License");
93588  * you may not use this file except in compliance with the License.
93589  * You may obtain a copy of the License at
93590  *
93591  * http://www.apache.org/licenses/LICENSE-2.0
93592  *
93593  * Unless required by applicable law or agreed to in writing, software
93594  * distributed under the License is distributed on an "AS IS" BASIS,
93595  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
93596  * See the License for the specific language governing permissions and
93597  * limitations under the License.
93598  */
93599
93600 var db = require('ripple/db'),
93601     utils = require('ripple/utils'),
93602     t = require('ripple/platform/tizen/2.0/typecast'),
93603     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
93604     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
93605     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
93606     DataControlConsumerFactory,
93607     DataControlConsumerObject,
93608     SQLDataControlConsumer,
93609     MappedDataControlConsumer,
93610     SQLData,
93611     MappedData,
93612     _data = {
93613         DB_DATACONTROL_KEY: "tizen1-db-datacontrol",
93614         IDS_PROVIDER:       ["http://tizen.org/datacontrol/provider/DictionaryDataControlProvider"],
93615         IDS_DATA:           ["Dictionary"],
93616         PERSIST_DELAY:      1000,
93617         SQL:                null,
93618         MAP:                null,
93619         dbStorage:          null
93620     },
93621     _security = {
93622         "http://tizen.org/privilege/datacontrol.consumer":
93623             ["getDataControlConsumer", "insert", "update", "remove", "select",
93624             "addValue", "removeValue", "getValue", "updateValue"]
93625     },
93626     _self;
93627
93628 function _get() {
93629     _data.dbStorage = db.retrieveObject(_data.DB_DATACONTROL_KEY) || {};
93630 }
93631
93632 function _save() {
93633     db.saveObject(_data.DB_DATACONTROL_KEY, _data.dbStorage);
93634 }
93635
93636 function _load(type) {
93637     if (!_data.dbStorage[type])
93638         return;
93639
93640     _data[type] = {};
93641
93642     utils.forEach(_data.dbStorage[type], function (provider, id) {
93643         var dataId;
93644
93645         _data[type][id] = {};
93646
93647         for (dataId in provider) {
93648             _data[type][id][dataId] = new DataControlConsumerFactory(type,
93649                     id, dataId, provider[dataId]);
93650         }
93651     });
93652 }
93653
93654 function _initialize() {
93655     _get();
93656
93657     _load("SQL");
93658     _load("MAP");
93659 }
93660
93661 _self = function () {
93662     var datacontrol;
93663
93664     // private
93665     function initConsumer(type) {
93666         var providers;
93667
93668         _data.dbStorage[type] = {};
93669         providers = _data.dbStorage[type];
93670
93671         _data.IDS_PROVIDER.forEach(function (id) {
93672             providers[id] = {};
93673
93674             _data.IDS_DATA.forEach(function (dataId) {
93675                 providers[id][dataId] = {};
93676             });
93677         });
93678
93679         _load(type);
93680     }
93681
93682     // public
93683     function getDataControlConsumer(providerId, dataId, type) {
93684         if (!_security.getDataControlConsumer) {
93685             throw new WebAPIException(errorcode.SECURITY_ERR);
93686         }
93687
93688         t.DataControlManager("getDataControlConsumer", arguments);
93689
93690         if (_data[type] === null) {
93691             initConsumer(type);
93692         }
93693         if (!_data[type][providerId] || !_data[type][providerId][dataId]) {
93694             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
93695         }
93696
93697         return _data[type][providerId][dataId];
93698     }
93699
93700     function handleSubFeatures(subFeatures) {
93701         var i, subFeature;
93702
93703         for (subFeature in subFeatures) {
93704             for (i in _security[subFeature]) {
93705                 _security[_security[subFeature][i]] = true;
93706             }
93707         }
93708     }
93709
93710     datacontrol = {
93711         getDataControlConsumer: getDataControlConsumer,
93712         handleSubFeatures:      handleSubFeatures
93713     };
93714
93715     return datacontrol;
93716 };
93717
93718 DataControlConsumerObject = function (type, providerId, dataId) {
93719     this.__defineGetter__("type", function () {
93720         return type;
93721     });
93722
93723     this.__defineGetter__("providerId", function () {
93724         return providerId;
93725     });
93726
93727     this.__defineGetter__("dataId", function () {
93728         return dataId;
93729     });
93730 };
93731
93732 SQLDataControlConsumer = function (providerId, dataId, dc) {
93733     var self, privateData = new SQLData(dc);
93734
93735     // public
93736     function insert(reqId, insertionData, successCallback, errorCallback) {
93737         if (!_security.insert) {
93738             throw new WebAPIException(errorcode.SECURITY_ERR);
93739         }
93740
93741         t.SQLDataControlConsumer("insert", arguments, true);
93742
93743         privateData.insert(insertionData, function (rowId) {
93744             if (successCallback) {
93745                 successCallback(reqId, rowId);
93746             }
93747         }, function (error) {
93748             if (errorCallback) {
93749                 errorCallback(reqId, error);
93750             }
93751         });
93752     }
93753
93754     function update(reqId, updateData, where, successCallback, errorCallback) {
93755         if (!_security.update) {
93756             throw new WebAPIException(errorcode.SECURITY_ERR);
93757         }
93758
93759         t.SQLDataControlConsumer("update", arguments, true);
93760
93761         privateData.update(updateData, where, function () {
93762             if (successCallback) {
93763                 successCallback(reqId);
93764             }
93765         }, function (error) {
93766             if (errorCallback) {
93767                 errorCallback(reqId, error);
93768             }
93769         });
93770     }
93771
93772     function remove(reqId, where, successCallback, errorCallback) {
93773         if (!_security.remove) {
93774             throw new WebAPIException(errorcode.SECURITY_ERR);
93775         }
93776
93777         t.SQLDataControlConsumer("remove", arguments, true);
93778
93779         privateData.remove(where, function () {
93780             if (successCallback) {
93781                 successCallback(reqId);
93782             }
93783         }, function (error) {
93784             if (errorCallback) {
93785                 errorCallback(reqId, error);
93786             }
93787         });
93788     }
93789
93790     function select(reqId, columns, where, successCallback, errorCallback, page,
93791             maxNumberPerPage) {
93792         if (!_security.select) {
93793             throw new WebAPIException(errorcode.SECURITY_ERR);
93794         }
93795
93796         t.SQLDataControlConsumer("select", arguments, true);
93797
93798         privateData.select(columns, where, function (rows) {
93799             successCallback(rows, reqId);
93800         }, function (error) {
93801             if (errorCallback) {
93802                 errorCallback(reqId, error);
93803             }
93804         }, page, maxNumberPerPage);
93805     }
93806
93807     self = new DataControlConsumerObject("SQL", providerId, dataId);
93808
93809     self.insert = insert;
93810     self.update = update;
93811     self.remove = remove;
93812     self.select = select;
93813
93814     return self;
93815 };
93816
93817 MappedDataControlConsumer = function (providerId, dataId, dc) {
93818     var self, privateData = new MappedData(dc);
93819
93820     function addValue(reqId, key, value, successCallback, errorCallback) {
93821         if (!_security.addValue) {
93822             throw new WebAPIException(errorcode.SECURITY_ERR);
93823         }
93824
93825         t.MappedDataControlConsumer("addValue", arguments);
93826
93827         window.setTimeout(function () {
93828             if (privateData.insert(key, value)) {
93829                 if (successCallback) {
93830                     successCallback(reqId);
93831                 }
93832             } else if (errorCallback) {
93833                 errorCallback(reqId, new WebAPIError(errorcode.UNKNOWN_ERR));
93834             }
93835         }, 1);
93836     }
93837
93838     function removeValue(reqId, key, value, successCallback, errorCallback) {
93839         if (!_security.removeValue) {
93840             throw new WebAPIException(errorcode.SECURITY_ERR);
93841         }
93842
93843         t.MappedDataControlConsumer("removeValue", arguments);
93844
93845         window.setTimeout(function () {
93846             if (privateData.remove(key, value)) {
93847                 successCallback(reqId);
93848             } else if (errorCallback) {
93849                 errorCallback(reqId, new WebAPIError(errorcode.NOT_FOUND_ERR));
93850             }
93851         }, 1);
93852     }
93853
93854     function getValue(reqId, key, successCallback, errorCallback) {
93855         if (!_security.getValue) {
93856             throw new WebAPIException(errorcode.SECURITY_ERR);
93857         }
93858
93859         t.MappedDataControlConsumer("getValue", arguments);
93860
93861         window.setTimeout(function () {
93862             var values;
93863
93864             values = privateData.search(key);
93865
93866             if (values !== null) {
93867                 successCallback(values, reqId);
93868             } else if (errorCallback) {
93869                 errorCallback(reqId, new WebAPIError(errorcode.NOT_FOUND_ERR));
93870             }
93871         }, 1);
93872     }
93873
93874     function updateValue(reqId, key, oldValue, newValue, successCallback,
93875             errorCallback) {
93876         if (!_security.updateValue) {
93877             throw new WebAPIException(errorcode.SECURITY_ERR);
93878         }
93879
93880         t.MappedDataControlConsumer("updateValue", arguments);
93881
93882         window.setTimeout(function () {
93883             if (privateData.update(key, oldValue, newValue)) {
93884                 successCallback(reqId);
93885             } else if (errorCallback) {
93886                 errorCallback(reqId, new WebAPIError(errorcode.NOT_FOUND_ERR));
93887             }
93888         }, 1);
93889     }
93890
93891     self = new DataControlConsumerObject("MAP", providerId, dataId);
93892
93893     self.addValue    = addValue;
93894     self.removeValue = removeValue;
93895     self.getValue    = getValue;
93896     self.updateValue = updateValue;
93897
93898     return self;
93899 };
93900
93901 DataControlConsumerFactory = function (type, providerId, dataId, dc) {
93902     var self;
93903
93904     switch (type) {
93905     case "SQL":
93906         self = new SQLDataControlConsumer(providerId, dataId, dc);
93907         break;
93908
93909     case "MAP":
93910         self = new MappedDataControlConsumer(providerId, dataId, dc);
93911         break;
93912     }
93913
93914     return self;
93915 };
93916
93917 SQLData = function (dc) {
93918     var self, data, columnNames, SQLErr2WebAPIErr;
93919
93920     // private
93921     function getDBTableName() {
93922         return "DC_" + Math.uuid(8, 16);
93923     }
93924
93925     function getColumnNames(tx, results) {
93926         columnNames = results.rows.item(0).sql
93927                 .replace(/^[^\(]+\(([^\)]+)\)/g, "$1")
93928                 .replace(/(^|(,) )([^ ,]+)([^,]*|$)/g, "$2$3")
93929                 .split(",");
93930     }
93931
93932     function queryColumns(columns) {
93933         return columns.join("=?,") + "=?";
93934     }
93935
93936     function queryValues(n) {
93937         return (new Array(n)).join("?,") + "?";
93938     }
93939
93940     function shedQuotes(values) {
93941         return values.every(function (value, i, arr) {
93942             arr[i] = value.replace(/^('|")(.*)\1$/g, "$2");
93943
93944             return (arr[i] !== value);
93945         });
93946     }
93947
93948     function isNull(p) {
93949         return ((p === undefined) || (p === null));
93950     }
93951
93952     function initialize() {
93953         SQLErr2WebAPIErr = [
93954             0,      // 0: UNKNOWN_ERR         0: UNKNOWN_ERR
93955             100,    // 1: DATABASE_ERR      100: IO_ERR
93956             100,    // 2: VERSION_ERR       100: IO_ERR
93957             100,    // 3: TOO_LARGE_ERR     100: IO_ERR
93958             22,     // 4: QUOTA_ERR          22: QUOTA_EXCEEDED_ERR
93959             12,     // 5: SYNTAX_ERR         12: SYNTAX_ERR
93960             100,    // 6: CONSTRAINT_ERR    100: IO_ERR
93961             23      // 7: TIMEOUT_ERR        23: TIMEOUT_ERR
93962         ];
93963
93964         if (!("table" in dc)) {
93965             dc.table = getDBTableName();
93966             columnNames = ["id"];
93967             _save();
93968         }
93969
93970         data = openDatabase('tinyHippos', '1.0', 'tiny Hippos persistence',
93971                 2 * 1024 * 1024);
93972
93973         data.transaction(function (tx) {
93974             tx.executeSql('CREATE TABLE IF NOT EXISTS ' + dc.table +
93975                     ' (id unique)');
93976             tx.executeSql('SELECT sql FROM sqlite_master WHERE type="table" AND name=?',
93977                     [dc.table], getColumnNames);
93978         });
93979     }
93980
93981     // public
93982     function insert(rowData, onSuccess, onError) {
93983         if (rowData.columns.length > rowData.values.length) {
93984             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
93985         }
93986         if (!shedQuotes(rowData.values)) {
93987             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
93988         }
93989
93990         data.transaction(function (tx) {
93991             rowData.columns.forEach(function (column) {
93992                 if (columnNames.indexOf(column) !== -1)
93993                     return;
93994
93995                 tx.executeSql('ALTER TABLE ' + dc.table + ' ADD ' + column +
93996                         ' TEXT', [], function () {
93997                             columnNames.push(column);
93998                         }, function (tx, error) {
93999                             onError(new WebAPIError(
94000                                     SQLErr2WebAPIErr[error.code],
94001                                     error.message));
94002                         });
94003             });
94004
94005             tx.executeSql('INSERT INTO ' + dc.table + ' (' +
94006                     rowData.columns.join() + ') VALUES (' +
94007                     queryValues(rowData.values.length) + ')', rowData.values,
94008                     function (tx, results) {
94009                         onSuccess(results.insertId);
94010                     }, function (tx, error) {
94011                         onError(new WebAPIError(SQLErr2WebAPIErr[error.code],
94012                                 error.message));
94013                     });
94014         });
94015     }
94016
94017     function update(rowData, where, onSuccess, onError) {
94018         if (rowData.columns.length > rowData.values.length) {
94019             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
94020         }
94021         if (!shedQuotes(rowData.values)) {
94022             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
94023         }
94024
94025         data.transaction(function (tx) {
94026             tx.executeSql('UPDATE ' + dc.table + ' SET ' +
94027                     queryColumns(rowData.columns) + ' WHERE ' + where,
94028                     rowData.values, onSuccess, function (tx, error) {
94029                         onError(new WebAPIError(SQLErr2WebAPIErr[error.code],
94030                                 error.message));
94031                     });
94032         });
94033     }
94034
94035     function remove(where, onSuccess, onError) {
94036         data.transaction(function (tx) {
94037             tx.executeSql('DELETE FROM ' + dc.table + ' WHERE ' + where, [],
94038                     onSuccess, function (tx, error) {
94039                         onError(new WebAPIError(SQLErr2WebAPIErr[error.code],
94040                                 error.message));
94041                     });
94042         });
94043     }
94044
94045     function select(columns, where, onSuccess, onError, page, maxNumberPerPage) {
94046         if (isNull(page)) {
94047             page = 1;
94048         } else {
94049             if (page <= 0) {
94050                 throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
94051             }
94052             page = parseInt(page, 10);
94053         }
94054
94055         if (isNull(maxNumberPerPage)) {
94056             if (page > 1) {
94057                 throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
94058             }
94059         } else {
94060             if (maxNumberPerPage <= 0) {
94061                 throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
94062             }
94063             maxNumberPerPage = parseInt(maxNumberPerPage, 10);
94064         }
94065
94066         data.transaction(function (tx) {
94067             tx.executeSql('SELECT ' + columns.join() + ' FROM ' + dc.table +
94068                     ' WHERE ' + where, [], function (tx, results) {
94069                         var rows = [], rowStart, rowData, r, c;
94070
94071                         rowStart = maxNumberPerPage ?
94072                             (page - 1) * maxNumberPerPage : 0;
94073
94074                         for (r = rowStart; r < results.rows.length; ++r) {
94075                             rowData = {
94076                                 columns: columns,
94077                                 values: []
94078                             };
94079                             for (c in columns) {
94080                                 rowData.values.push(results.rows
94081                                     .item(r)[columns[c]]);
94082                             }
94083                             rows.push(rowData);
94084
94085                             if (maxNumberPerPage && (--maxNumberPerPage === 0))
94086                                 break;
94087                         }
94088
94089                         onSuccess(rows);
94090                     }, function (tx, error) {
94091                         onError(new WebAPIError(SQLErr2WebAPIErr[error.code],
94092                                 error.message));
94093                     });
94094         });
94095     }
94096
94097     initialize();
94098
94099     self = {
94100         insert: insert,
94101         update: update,
94102         remove: remove,
94103         select: select
94104     };
94105
94106     return self;
94107 };
94108
94109 MappedData = function (dc) {
94110     var self, data = {}, ioStamp = 0;
94111
94112     // private
94113     function addNode(tree, arr, i) {
94114         var key, value;
94115
94116         if (typeof arr[i] === "string") {
94117             key = arr[i];
94118             value = 1;
94119         } else {
94120             key = arr[i][0];
94121             value = arr[i][1];
94122         }
94123         tree.insert(key, value);
94124     }
94125
94126     function bisearch(tree, arr, queue) {
94127         var start, end, mid;
94128
94129         if (queue.length === 0)
94130             return;
94131
94132         start = queue.shift();
94133         end = queue.shift();
94134
94135         if (start > end)
94136             return;
94137
94138         mid = start + parseInt((end - start) / 2, 10);
94139         addNode(tree, arr, mid);
94140         queue.push(start, mid - 1);
94141         queue.push(mid + 1, end);
94142     }
94143
94144     function build(arr) {
94145         var tree, mid, lTree = [], rTree = [];
94146
94147         tree = redblack.tree();
94148         mid = parseInt(arr.length / 2, 10);
94149         addNode(tree, arr, mid);
94150
94151         lTree.push(0, mid - 1);
94152         rTree.push(mid + 1, arr.length - 1);
94153
94154         while ((lTree.length > 0) || (rTree.length > 0)) {
94155             bisearch(tree, arr, lTree);
94156             bisearch(tree, arr, rTree);
94157         }
94158
94159         return tree;
94160     }
94161
94162     function initialize() {
94163         for (var key in dc) {
94164             data[key] = build(dc[key]);
94165         }
94166     }
94167
94168     function traverse(tree, key) {
94169         dc[key] = [];
94170         tree.forEach(function (count, value) {
94171             dc[key].push((count === 1) ? value : [value, count]);
94172         });
94173     }
94174
94175     function persist() {
94176         if (ioStamp !== 0) {
94177             window.clearTimeout(ioStamp);
94178         }
94179         ioStamp = window.setTimeout(function () {
94180             var key;
94181
94182             for (key in data) {
94183                 traverse(data[key], key);
94184             }
94185
94186             _save();
94187
94188             ioStamp = 0;
94189         }, _data.PERSIST_DELAY);
94190     }
94191
94192     // public
94193     function insert(key, value) {
94194         var tree, count;
94195
94196         if (!(key in data)) {
94197             data[key] = redblack.tree();
94198         }
94199
94200         tree = data[key];
94201
94202         if (!tree)
94203             return false;
94204
94205         count = tree.get(value);
94206         tree.insert(value, count ? (count + 1) : 1);
94207         persist();
94208
94209         return true;
94210     }
94211
94212     function remove(key, value) {
94213         var tree, count;
94214
94215         if (!(key in data))
94216             return false;
94217
94218         tree = data[key];
94219         count = tree.get(value);
94220         if (count === null)
94221             return false;
94222
94223         tree.delete(value);
94224
94225         if (tree.root === null) {
94226             delete data[key];
94227             if (key in dc) {
94228                 delete dc[key];
94229             }
94230         }
94231
94232         persist();
94233
94234         return true;
94235     }
94236
94237     function search(key) {
94238         var values = [], tree;
94239
94240         if (!(key in data))
94241             return null;
94242
94243         tree = data[key];
94244         tree.forEach(function (count, value) {
94245             while (count--) {
94246                 values.push(value);
94247             }
94248         });
94249
94250         return values;
94251     }
94252
94253     function update(key, oldValue, newValue) {
94254         var tree, count, countNew;
94255
94256         if (!(key in data))
94257             return false;
94258
94259         tree = data[key];
94260         count = tree.get(oldValue);
94261         if (count === null)
94262             return false;
94263
94264         countNew = tree.get(newValue);
94265         count += (countNew === null) ? 0 : countNew;
94266         tree.delete(oldValue);
94267         tree.insert(newValue, count);
94268         persist();
94269
94270         return true;
94271     }
94272
94273     initialize();
94274
94275     self = {
94276         insert: insert,
94277         remove: remove,
94278         search: search,
94279         update: update
94280     };
94281
94282     return self;
94283 };
94284
94285 _initialize();
94286
94287 module.exports = _self;
94288
94289 });
94290 define('ripple/platform/tizen/2.0/datasync', function (require, exports, module) {
94291 /*
94292  *  Copyright 2013 Intel Corporation
94293  *
94294  * Licensed under the Apache License, Version 2.0 (the "License");
94295  * you may not use this file except in compliance with the License.
94296  * You may obtain a copy of the License at
94297  *
94298  * http://www.apache.org/licenses/LICENSE-2.0
94299  *
94300  * Unless required by applicable law or agreed to in writing, software
94301  * distributed under the License is distributed on an "AS IS" BASIS,
94302  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
94303  * See the License for the specific language governing permissions and
94304  * limitations under the License.
94305  */
94306
94307 var db = require('ripple/db'),
94308     utils = require('ripple/utils'),
94309     ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'),
94310     t = require('ripple/platform/tizen/2.0/typecast'),
94311     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
94312     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
94313     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
94314     SyncInfoMod = require('ripple/platform/tizen/2.0/SyncInfo'),
94315     SyncServiceInfoMod = require('ripple/platform/tizen/2.0/SyncServiceInfo'),
94316     SyncProfileInfoMod = require('ripple/platform/tizen/2.0/SyncProfileInfo'),
94317     SyncStatistics = require('ripple/platform/tizen/2.0/SyncStatistics'),
94318     _data = {
94319         DB_DATASYNC_ITEMS: "tizen1-db-datasync-items",
94320         DB_DATASYNC_COUNTER: "tizen1-db-datasync-counter",
94321         MAX_PROFILE_NUMBER: 5,
94322         profile_num: 0,
94323         profiles: {},
94324         sync_accounts: {},
94325         service_accounts: {},
94326         item_counter: 1000,
94327         type_table: {
94328             "TWO_WAY":             1,
94329             "SLOW":                2,
94330             "ONE_WAY_FROM_CLIENT": 3,
94331             "REFRESH_FROM_CLIENT": 4,
94332             "ONE_WAY_FROM_SERVER": 5,
94333             "REFRESH_FROM_SERVER": 6
94334         },
94335         mode_table: {
94336             "TWO_WAY":             200,
94337             "SLOW":                201,
94338             "ONE_WAY_FROM_CLIENT": 202,
94339             "REFRESH_FROM_CLIENT": 203,
94340             "ONE_WAY_FROM_SERVER": 204,
94341             "REFRESH_FROM_SERVER": 205
94342         },
94343         items: {}
94344     },
94345     _security = {
94346         "http://tizen.org/privilege/datasync":
94347             ["add", "update", "remove", "getMaxProfilesNum", "getProfilesNum",
94348              "get", "getAll", "startSync", "stopSync", "getLastSyncStatistics"]
94349     },
94350     _self,
94351     syncml = {
94352         adapter: require('ripple/platform/tizen/2.0/syncml-js-lib/adapter'),
94353         agent: require('ripple/platform/tizen/2.0/syncml-js-lib/agent'),
94354         base64: require('ripple/platform/tizen/2.0/syncml-js-lib/base64'),
94355         codec:  require('ripple/platform/tizen/2.0/syncml-js-lib/codec'),
94356         common: require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
94357         constant: require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
94358         context: require('ripple/platform/tizen/2.0/syncml-js-lib/context'),
94359         ctype: require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'),
94360         devinfo: require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'),
94361         item: require('ripple/platform/tizen/2.0/syncml-js-lib/item'),
94362         localadapter: require('ripple/platform/tizen/2.0/syncml-js-lib/localadapter'),
94363         matcher: require('ripple/platform/tizen/2.0/syncml-js-lib/matcher'),
94364         protocol: require('ripple/platform/tizen/2.0/syncml-js-lib/protocol'),
94365         remoteadapter: require('ripple/platform/tizen/2.0/syncml-js-lib/remoteadapter'),
94366         router: require('ripple/platform/tizen/2.0/syncml-js-lib/router'),
94367         state: require('ripple/platform/tizen/2.0/syncml-js-lib/state'),
94368         storage: require('ripple/platform/tizen/2.0/syncml-js-lib/storage'),
94369         store: require('ripple/platform/tizen/2.0/syncml-js-lib/store'),
94370         synchronizer: require('ripple/platform/tizen/2.0/syncml-js-lib/synchronizer'),
94371         useragent: require('ripple/platform/tizen/2.0/syncml-js-lib/useragent')
94372     },
94373     TizenAgent;
94374
94375 function _get() {
94376     _data.item_counter = db.retrieveObject(_data.DB_DATASYNC_COUNTER) || 1000;
94377     _data.items = db.retrieveObject(_data.DB_DATASYNC_ITEMS) || {};
94378 }
94379
94380 function _save() {
94381     db.saveObject(_data.DB_DATASYNC_COUNTER, _data.item_counter);
94382     db.saveObject(_data.DB_DATASYNC_ITEMS, _data.items);
94383 }
94384
94385 TizenAgent = syncml.agent.Agent.extend({
94386     constructor: function() {
94387     },
94388     getContentTypes: function() {
94389         return [
94390             new syncml.ctype.ContentTypeInfo('text/x-vcard', '2.1',{preferred: true})
94391         ];
94392     },
94393     dumpsItem: function(item, contentType, version, cb) {
94394         var cdata = new ET.CdataElement(item.item);
94395         cb(null, cdata);
94396     },
94397     loadsItem: function(data, contentType, version, cb) {
94398         return cb(null, {item: data._node.textContent});
94399     },
94400     getAllItems: function(cb) {
94401         var items = [];
94402         utils.forEach(_data.items, function(contact) {
94403             items.push(contact);
94404         });
94405         return cb(null, items);
94406     },
94407     addItem: function(item, cb) {
94408         _data.item_counter++;
94409         item.id = _data.item_counter.toString();
94410         _data.items[item.id] = item;
94411         _save();
94412         return cb(null, item);
94413     },
94414     getItem: function(itemID, cb) {
94415         return cb(null, _data.items[itemID]);
94416     },
94417     replaceItem: function(item, reportChanges, cb) {
94418         _data.items[item.id] = item;
94419         _save();
94420         return cb(null, null);
94421     },
94422     deleteItem: function(itemID, cb) {
94423         delete _data.items[itemID];
94424         _save();
94425         return cb(null);
94426     }
94427 });
94428
94429 function _initialize() {
94430     _data.agent = new TizenAgent();
94431     _get();
94432 }
94433
94434 _self = function () {
94435     var datasync;
94436
94437     // private
94438     function createInternalProfile(profile) {
94439         var _profile, sync_account, service_accounts;
94440
94441         sync_account = db.retrieveObject("save-syncinfo")[profile.syncInfo.__syncInfoID__];
94442
94443         _profile = {
94444             profileName: profile.profileName,
94445             syncInfo: {
94446                 url:        profile.syncInfo.url,
94447                 id:         sync_account.id,
94448                 password:   sync_account.password,
94449                 mode:       profile.syncInfo.mode
94450             },
94451             serviceInfo: []
94452         };
94453
94454         switch (_profile.syncInfo.mode) {
94455         case "MANUAL":
94456             _profile.syncInfo.type = profile.syncInfo.type || "TWO_WAY";
94457             break;
94458         case "PERIODIC":
94459             //TODO: set 1_HOUR as default value
94460             _profile.interval = profile.syncInfo.interval || "1_HOUR";
94461             _profile.syncInfo.type = "TWO_WAY";
94462             break;
94463         case "PUSH":
94464             _profile.syncInfo.type = "TWO_WAY";
94465             break;
94466         }
94467
94468         if (profile.serviceInfo) {
94469             service_accounts = db.retrieveObject("save-syncserviceinfo");
94470             utils.forEach(profile.serviceInfo, function (service) {
94471                 _profile.serviceInfo.push({
94472                     enable:             service.enable,
94473                     serviceType:        service.serviceType,
94474                     serverDatabaseUri:  service.serverDatabaseUri,
94475                     id:                 service_accounts[service.__syncServiceInfoID__].id,
94476                     password:           service_accounts[service.__syncServiceInfoID__].password
94477                 });
94478             });
94479         }
94480
94481         return _profile;
94482     }
94483
94484     function createExternalProfile(profileId) {
94485         var profile, i, _syncinfo, _serviceinfo, p;
94486
94487         p = _data.profiles[profileId];
94488
94489         switch (p.syncInfo.mode) {
94490         case "MANUAL":
94491             _syncinfo = new SyncInfoMod(p.syncInfo.url, p.syncInfo.id, p.syncInfo.password, "MANUAL", p.syncInfo.type);
94492             _syncinfo.interval = null;
94493             break;
94494         case "PERIODIC":
94495             _syncinfo = new SyncInfoMod(p.syncInfo.url, p.syncInfo.id, p.syncInfo.password, "PERIODIC", p.syncInfo.interval);
94496             break;
94497         case "PUSH":
94498             _syncinfo = new SyncInfoMod(p.syncInfo.url, p.syncInfo.id, p.syncInfo.password, "PUSH");
94499             break;
94500         }
94501
94502         if (p.serviceInfo) {
94503             _serviceinfo = [];
94504             for (i in p.serviceInfo) {
94505                 var info;
94506                 info = new SyncServiceInfoMod(p.serviceInfo[i].enable,
94507                         p.serviceInfo[i].serviceType, p.serviceInfo[i].serverDatabaseUri,
94508                         p.serviceInfo[i].id || null, p.serviceInfo[i].password || null);
94509                 _serviceinfo.push(info);
94510             }
94511         }
94512
94513         profile = new SyncProfileInfoMod(p.profileName, _syncinfo, _serviceinfo);
94514         Object.defineProperty(profile, "profileId", {value: p.profileId, writable: false});
94515
94516         return profile;
94517     }
94518
94519     // public
94520     function add(profile) {
94521         var _profile;
94522
94523         if (!_security.add) {
94524             throw new WebAPIException(errorcode.SECURITY_ERR);
94525         }
94526
94527         t.DataSynchronizationManager("add", arguments);
94528
94529         _profile = createInternalProfile(profile);
94530
94531         if (_data.profile_num > _data.MAX_PROFILE_NUMBER) {
94532             throw new WebAPIException(errorcode.QUOTA_EXCEEDED_ERR);
94533         }
94534
94535         _profile.profileId = Math.uuid(null, 16);
94536         _data.profiles[_profile.profileId] = _profile;
94537         _data.profile_num++;
94538
94539         Object.defineProperty(profile, "profileId", {value: _profile.profileId, writable: false});
94540     }
94541
94542     function update(profile) {
94543         var _profile;
94544
94545         if (!_security.update) {
94546             throw new WebAPIException(errorcode.SECURITY_ERR);
94547         }
94548
94549         t.DataSynchronizationManager("update", arguments);
94550
94551         _profile = createInternalProfile(profile);
94552
94553         if (!profile.profileId || !_data.profiles[profile.profileId]) {
94554             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
94555         }
94556
94557         _profile.profileId = profile.profileId;
94558         _data.profiles[_profile.profileId] = _profile;
94559     }
94560
94561     function remove(profileId) {
94562         if (!_security.remove) {
94563             throw new WebAPIException(errorcode.SECURITY_ERR);
94564         }
94565
94566         t.DataSynchronizationManager("remove", arguments);
94567
94568         if (!_data.profiles[profileId]) {
94569             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
94570         }
94571
94572         delete _data.profiles[profileId];
94573         _data.profile_num--;
94574     }
94575
94576     function getMaxProfilesNum() {
94577         if (!_security.getMaxProfilesNum) {
94578             throw new WebAPIException(errorcode.SECURITY_ERR);
94579         }
94580
94581         return _data.MAX_PROFILE_NUMBER;
94582     }
94583
94584     function getProfilesNum() {
94585         if (!_security.getProfilesNum) {
94586             throw new WebAPIException(errorcode.SECURITY_ERR);
94587         }
94588
94589         return _data.profile_num;
94590     }
94591
94592     function get(profileId) {
94593         var profile;
94594
94595         if (!_security.get) {
94596             throw new WebAPIException(errorcode.SECURITY_ERR);
94597         }
94598
94599         t.DataSynchronizationManager("get", arguments);
94600
94601         if (!_data.profiles[profileId]) {
94602             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
94603         }
94604
94605         profile = createExternalProfile(profileId);
94606
94607         return profile;
94608     }
94609
94610     function getAll() {
94611         var profiles = [], i;
94612
94613         if (!_security.getAll) {
94614             throw new WebAPIException(errorcode.SECURITY_ERR);
94615         }
94616
94617         for (i in _data.profiles) {
94618             profiles.push(createExternalProfile(_data.profiles[i].profileId));
94619         }
94620
94621         return profiles;
94622     }
94623
94624     function startSync(profileId, progressCallback) {
94625         var _profile, _stores, _routes, sync_peer;
94626
94627         if (!_security.startSync) {
94628             throw new WebAPIException(errorcode.SECURITY_ERR);
94629         }
94630
94631         t.DataSynchronizationManager("startSync", arguments);
94632
94633         if (!_data.profiles[profileId]) {
94634             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
94635         }
94636         _data.profiles[profileId].stop_flag = false;
94637
94638         sync_peer = function(adapter, store, peer, type) {
94639             adapter.sync(peer, type, function(err, stats) {
94640                 var p, name, hereTotal, peerTotal;
94641                 p = _data.profiles[profileId];
94642                 if (p.stop_flag === true) {
94643                     p.syncStatistics =[{
94644                         syncStatus: "STOP",
94645                         serviceType:            p.serviceInfo[0].serviceType,
94646                         lastSyncTime:           new Date(),
94647                         serverToClientTotal:    0,
94648                         serverToClientAdded:    0,
94649                         serverToClientUpdated:  0,
94650                         serverToClientRemoved:  0,
94651                         clientToServerTotal:    0,
94652                         clientToServerAdded:    0,
94653                         clientToServerUpdated:  0,
94654                         clientToServerRemoved:  0
94655                     }];
94656                     p.stop_flag = false;
94657                     return;
94658                 }
94659                 if (err) {
94660                     if (progressCallback) {
94661                         if (progressCallback.onfailed) {
94662                             progressCallback.onfailed(profileId, new WebAPIError(errorcode.UNKNOWN_ERR));
94663                         }
94664                     }
94665                     p.syncStatistics =[{
94666                         syncStatus: "FAIL",
94667                         serviceType:            p.serviceInfo[0].serviceType,
94668                         lastSyncTime:           new Date(),
94669                         serverToClientTotal:    0,
94670                         serverToClientAdded:    0,
94671                         serverToClientUpdated:  0,
94672                         serverToClientRemoved:  0,
94673                         clientToServerTotal:    0,
94674                         clientToServerAdded:    0,
94675                         clientToServerUpdated:  0,
94676                         clientToServerRemoved:  0
94677                     }];
94678                     p.stop_flag = false;
94679                     return;
94680                 }
94681                 name = p.profileName + "-" + p.serviceInfo[0].serviceType;
94682                 hereTotal = stats[name].hereAdd + stats[name].hereDel + stats[name].hereMod;
94683                 peerTotal = stats[name].peerAdd + stats[name].peerDel + stats[name].peerMod;
94684                 p.syncStatistics =[{
94685                     syncStatus: "SUCCESS",
94686                     serviceType:            p.serviceInfo[0].serviceType,
94687                     lastSyncTime:           new Date(),
94688                     serverToClientTotal:    hereTotal,
94689                     serverToClientAdded:    stats[name].hereAdd,
94690                     serverToClientUpdated:  stats[name].hereMod,
94691                     serverToClientRemoved:  stats[name].hereDel,
94692                     clientToServerTotal:    peerTotal,
94693                     clientToServerAdded:    stats[name].peerAdd,
94694                     clientToServerUpdated:  stats[name].peerMod,
94695                     clientToServerRemoved:  stats[name].peerDel
94696                 }];
94697                 p.stop_flag = false;
94698
94699                 if (progressCallback) {
94700                     if (progressCallback.oncompleted) {
94701                         progressCallback.oncompleted(profileId);
94702                     }
94703                 }
94704             });
94705         };
94706         _profile = _data.profiles[profileId];
94707         _profile.context = new syncml.context.Context({prefix: "tizen-"});
94708         _stores = [];
94709         _routes = [];
94710         utils.forEach(_profile.serviceInfo, function(service) {
94711             var name = _profile.profileName + "-" + service.serviceType;
94712             _stores.push({
94713                 uri:            name,
94714                 displayName:    name,
94715                 maxGuidSize:    64,
94716                 maxObjSize:     4000000,
94717                 agent:          _data.agent
94718             });
94719             _routes.push([name, service.serverDatabaseUri]);
94720         });
94721         _profile.context.getEasyClientAdapter({
94722             displayName: "Tizen syncML adapter",
94723             devInfo: {
94724                 devID: "tizen-syncml-03",
94725                 devType: syncml.constant.DEVTYPE_WORKSTATION,
94726                 manufacturerName: "Tizen",
94727                 modelName: "tizen.syncml.client",
94728                 hierarchicalSync: false
94729             },
94730             stores: _stores,
94731             peer: {
94732                 url:        _profile.syncInfo.url,
94733                 username:   _profile.syncInfo.id,
94734                 password:   _profile.syncInfo.password
94735             },
94736             routes: _routes
94737         }, function(err, adapter, stores, peer) {
94738             if (err) {
94739                 console.log("[datasync.syncml] getEasyClientAdapter fail:", err);
94740                 return;
94741             }
94742             utils.forEach(stores, function(store) {
94743                 var args = {
94744                     data:       _data.mode_table[_profile.syncInfo.type],
94745                     source:     store.uri,
94746                     target:     _profile.serviceInfo[0].serverDatabaseUri,
94747                     nextAnchor: syncml.common.ts()
94748                 };
94749                 if (args.data === _data.mode_table["SLOW"]) {
94750                     args.lastAnchor = null;
94751                 } else if (peer.getStore(args.target)) {
94752                     args.lastAnchor = peer.getStore(args.target)._getBinding().localAnchor;
94753                 }
94754
94755                 db.saveObject("syncml-alert-args", args);
94756                 db.saveObject("syncml-first-flag", false);
94757                 sync_peer(adapter, store, peer, _data.type_table[_profile.syncInfo.type]);
94758             });
94759         });
94760
94761     }
94762
94763     function stopSync(profileId) {
94764         if (!_security.stopSync) {
94765             throw new WebAPIException(errorcode.SECURITY_ERR);
94766         }
94767
94768         t.DataSynchronizationManager("stopSync", arguments);
94769
94770         if (!_data.profiles[profileId]) {
94771             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
94772         }
94773
94774         _data.profiles[profileId].stop_flag = true;
94775     }
94776
94777     function getLastSyncStatistics(profileId) {
94778         var s, statistics = [], i;
94779
94780         if (!_security.getLastSyncStatistics) {
94781             throw new WebAPIException(errorcode.SECURITY_ERR);
94782         }
94783
94784         t.DataSynchronizationManager("getLastSyncStatistics", arguments);
94785
94786         if (!_data.profiles[profileId]) {
94787             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
94788         }
94789
94790         s = _data.profiles[profileId].syncStatistics;
94791
94792         for (i in s) {
94793             statistics.push(
94794                 new SyncStatistics(s[i].syncStatus, s[i].serviceType, s[i].lastSyncTime,
94795                     s[i].serverToClientTotal, s[i].serverToClientAdded,
94796                     s[i].serverToClientUpdated, s[i].serverToClientRemoved,
94797                     s[i].clientToServerTotal, s[i].clientToServerAdded,
94798                     s[i].clientToServerUpdated, s[i].clientToServerRemoved)
94799             );
94800         }
94801
94802         return statistics;
94803     }
94804
94805     function handleSubFeatures(subFeatures) {
94806         var i, subFeature;
94807
94808         for (subFeature in subFeatures) {
94809             for (i in _security[subFeature]) {
94810                 _security[_security[subFeature][i]] = true;
94811             }
94812         }
94813     }
94814
94815     datasync = {
94816         add:                    add,
94817         update:                 update,
94818         remove:                 remove,
94819         getMaxProfilesNum:      getMaxProfilesNum,
94820         getProfilesNum:         getProfilesNum,
94821         get:                    get,
94822         getAll:                 getAll,
94823         startSync:              startSync,
94824         stopSync:               stopSync,
94825         getLastSyncStatistics:  getLastSyncStatistics,
94826         handleSubFeatures:      handleSubFeatures
94827     };
94828
94829     return datasync;
94830 };
94831
94832 _initialize();
94833
94834 module.exports = _self;
94835
94836 });
94837 define('ripple/platform/tizen/2.0/dbfs', function (require, exports, module) {
94838 /*
94839  *  Copyright 2011 Research In Motion Limited.
94840  *  Copyright 2012 Intel Corporation.
94841  *
94842  * Licensed under the Apache License, Version 2.0 (the "License");
94843  * you may not use this file except in compliance with the License.
94844  * You may obtain a copy of the License at
94845  *
94846  * http://www.apache.org/licenses/LICENSE-2.0
94847  *
94848  * Unless required by applicable law or agreed to in writing, software
94849  * distributed under the License is distributed on an "AS IS" BASIS,
94850  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
94851  * See the License for the specific language governing permissions and
94852  * limitations under the License.
94853  */
94854
94855 var db = require('ripple/db'),
94856     utils = require('ripple/utils'),
94857     _console = require('ripple/console'),
94858     _cache = {},
94859     _self;
94860
94861 function _get(path) {
94862     return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
94863         return token === "" ? obj : ((obj && obj.children) ? obj.children[token] || null : null);
94864     }, _cache);
94865 }
94866
94867 function _getInfo(path) {
94868     var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
94869         name = parent.splice(parent.length - 1, 1).join("");
94870
94871     return {
94872         name: name,
94873         parent: parent.join("/") || "/"
94874     };
94875 }
94876
94877 function _set(path, obj) {
94878     var parent = _cache,
94879         tokens = path.replace(/^\//, '').split("/"),
94880         child = tokens.splice(tokens.length - 1, 1).join("");
94881
94882     tokens.forEach(function (token) {
94883         parent = parent.children[token];
94884     });
94885
94886     parent.children = parent.children || {};
94887     parent.children[child] = obj;
94888 }
94889
94890 function _delete(path) {
94891     var parent = _cache,
94892         tokens = path.replace(/^\//, '').split("/"),
94893         child = tokens.splice(tokens.length - 1, 1).join("");
94894
94895     tokens.forEach(function (token) {
94896         parent = parent.children[token];
94897     });
94898
94899     delete parent.children[child];
94900 }
94901
94902 function _save() {
94903     db.saveObject("tizen1-db-filesystem", _cache);
94904 }
94905
94906 function _walk(path, parent) {
94907     _self.ls(path, function (entries) {
94908         parent.children = parent.children || {};
94909
94910         entries.forEach(function (entry) {
94911             parent.children[entry.name] = entry;
94912
94913             if (entry.isDirectory) {
94914                 _walk(entry.fullPath, entry);
94915             } else {
94916                 /* after getting Date out of DB, Date will become
94917                    a string, so need to recast it back to Date */
94918                 if (entry.lastModifiedDate !== null && entry.lastModifiedDate !== undefined)
94919                     entry.lastModifiedDate = new Date(entry.lastModifiedDate);
94920                 if (entry.createdDate !== null && entry.createdDate !== undefined)
94921                     entry.createdDate = new Date(entry.createdDate);
94922
94923                 _self.read(entry.fullPath, function (data) {
94924                     parent.children[entry.name].data = data;
94925                 }, function (e) {
94926                     _console.error(e);
94927                 });
94928             }
94929         });
94930     }, function (e) {
94931         _console.error(e);
94932     });
94933 }
94934
94935 function _createPath(path) {
94936     var parts = path.replace(/^\//, '').split("/"),
94937         workflow = jWorkflow.order();
94938
94939     parts.forEach(function (part, index) {
94940         var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/");
94941
94942         workflow.andThen(function (prev, baton) {
94943             baton.take();
94944             _self.mkdir(dir, baton.pass, baton.pass);
94945         });
94946     });
94947
94948     workflow.start();
94949 }
94950
94951 _self = {
94952     // The order is consistent with _virtualRoots in filesystem.js
94953     roots: ["/opt/documents", "/opt/images", "/opt/music", "/opt/videos", "/opt/downloads", "/home/user/appdata/simulatedapp/wgt-package", "/home/user/appdata/simulatedapp/wgt-private", "/home/user/appdata/simulatedapp/wgt-private-tmp", "/SDCard", "/opt/attachments"],
94954     initialize: function () {
94955         // TODO: Initialize at bootstrap and emulatorBridge.link
94956         _cache = db.retrieveObject("tizen1-db-filesystem") || {};
94957         // create real root paths if empty
94958         _self.roots.every(function (root) {
94959             _createPath(root);
94960             return true;
94961         });
94962         // build the file system cache so that we could access information synchronously
94963         _walk("/", _cache);
94964     },
94965     ls: function (path, success, error) {
94966         try {
94967             var dir = _get(path),
94968                 items = [];
94969
94970             if (dir) {
94971                 utils.forEach(dir.children, function (item) {
94972                     items.push(item);
94973                 });
94974             }
94975             else {
94976                 items = {};
94977             }
94978
94979             success(items);
94980         }
94981         catch (e) {
94982             e.code = 1;
94983             error(e);
94984         }
94985     },
94986     rm: function (path, success, error, options) {
94987         _delete(path);
94988         _save();
94989         success();
94990     },
94991     rmdir: function (path, success, error, options) {
94992         _delete(path);
94993         _save();
94994         success();
94995     },
94996     mkdir: function (path, success, error) {
94997         var entry = _get(path),
94998             info = _getInfo(path);
94999
95000         if (!entry) {
95001             _set(path, {
95002                 lastModifiedDate: new Date(),
95003                 createdDate: new Date(),
95004                 name: info.name,
95005                 isDirectory: true,
95006                 fullPath: path
95007             });
95008             entry = _get(path);
95009             _save();
95010         }
95011
95012         if (entry) {
95013             success(entry);
95014         }
95015         else {
95016             error({code: 1});
95017         }
95018     },
95019     mv: function (from, to, success, error) {
95020         try {
95021             var fromEntry = _get(from),
95022                 toInfo = _getInfo(to);
95023
95024             fromEntry.fullPath = to;
95025             fromEntry.name = toInfo.name;
95026
95027             _set(to, fromEntry);
95028             _delete(from);
95029             _save();
95030             success();
95031         }
95032         catch (e) {
95033             e.code = 1;
95034             error(e);
95035         }
95036     },
95037     touch: function (path, success, error) {
95038         var entry = _get(path),
95039             info  = _getInfo(path);
95040
95041         if (!entry) {
95042             _set(path, {
95043                 lastModifiedDate: new Date(),
95044                 createdDate: new Date(),
95045                 name: info.name,
95046                 isDirectory: false,
95047                 fullPath: path,
95048                 data: ""
95049             });
95050             entry = _get(path);
95051         }
95052         _save();
95053         success(entry);
95054     },
95055     cp: function (from, to, success, error) {
95056         try {
95057             var fromEntry = _get(from),
95058                 copied = utils.copy(fromEntry);
95059
95060             copied.name  = _getInfo(to).name;
95061             copied.fullPath = to;
95062             _set(to, copied);
95063             _save();
95064             success();
95065         }
95066         catch (e) {
95067             e.code = 1;
95068             error(e);
95069         }
95070     },
95071     stat: function (path, success, error) {
95072         var entry = _get(path);
95073
95074         if (entry) {
95075             success(entry);
95076         } else {
95077             error({code: 1});
95078         }
95079     },
95080     write: function (path, contents, success, error, options) {
95081         var entry = _get(path);
95082
95083         if (entry) {
95084             entry.lastModifiedDate = new Date();
95085             entry.data = contents;
95086             _save();
95087             success();
95088         } else {
95089             error({code: 1});
95090         }
95091
95092     },
95093     read: function (path, success, error) {
95094         var entry = _get(path);
95095
95096         if (entry) {
95097             success(utils.copy(entry.data));
95098         }
95099         else {
95100             error({code: 1});
95101         }
95102     }
95103 };
95104
95105 module.exports = _self;
95106
95107 });
95108 define('ripple/platform/tizen/2.0/dbinit', function (require, exports, module) {
95109 /*
95110  *  Copyright 2013 Intel Corporation.
95111  *
95112  * Licensed under the Apache License, Version 2.0 (the "License");
95113  * you may not use this file except in compliance with the License.
95114  * You may obtain a copy of the License at
95115  *
95116  * http://www.apache.org/licenses/LICENSE-2.0
95117  *
95118  * Unless required by applicable law or agreed to in writing, software
95119  * distributed under the License is distributed on an "AS IS" BASIS,
95120  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95121  * See the License for the specific language governing permissions and
95122  * limitations under the License.
95123  */
95124
95125 var utils = require('ripple/utils'),
95126     exception = require('ripple/exception'),
95127     dbfs = require('ripple/platform/tizen/2.0/dbfs'),
95128     filesystem = require('ripple/platform/tizen/2.0/filesystem'),
95129     DBBuilder,
95130     Content,
95131     FileSystem,
95132     _data = {
95133         dbBuilder: null
95134     },
95135     _self = {};
95136
95137 function _initialize() {
95138     _data.dbBuilder = new DBBuilder();
95139
95140     _data.dbBuilder.register("FileSystem", "", FileSystem);
95141     _data.dbBuilder.register("Content", "dbcontent.xml", Content);
95142     _data.dbBuilder.register("Package", "dbpackage.xml");
95143     _data.dbBuilder.register("Application", "dbapplication.xml");
95144     _data.dbBuilder.register("Bluetooth", "dbbluetooth.xml");
95145
95146     _data.FileSystem.initdb();
95147 }
95148
95149 DBBuilder = function () {
95150     var self;
95151
95152     // private
95153     function formatString(str) {
95154         return str.replace(/^\s+|[\t\n\r\v]+|\s+$/g, "").replace(/\s+/g, " ");
95155     }
95156
95157     function getType(node) {
95158         var type, reNum, reDate, reHexNum;
95159
95160         if (node.childNodes) {
95161             return (node.childNodes[0].nodeName === "i") ? "Array" : "Object";
95162         }
95163
95164         // Special case
95165         if (node.nodeName === "version") {
95166             return "DOMString";
95167         }
95168
95169         reNum = /^(-?\d+)(\.\d+)?$/;
95170         reHexNum = /^0[xX][0-9a-fA-F]+$/;
95171         reDate = /^(\d{4})\-(\d{2})\-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/;
95172
95173         if (reNum.test(node.textContent)) {
95174             type = "Number";
95175         } else if (reHexNum.test(node.textContent)) {
95176             type = "Number";
95177         } else if (reDate.test(node.textContent)) {
95178             type = "Date";
95179         } else if (node.textContent === "true" || node.textContent === "false") {
95180             type = "Boolean";
95181         } else {
95182             type = "DOMString";
95183         }
95184
95185         return type;
95186     }
95187
95188     function build(node) {
95189         var i, value;
95190
95191         switch (getType(node)) {
95192         case "Boolean":
95193             value = (formatString(node.textContent) === "true");
95194             break;
95195
95196         case "Date":
95197             value = new Date(formatString(node.textContent));
95198             break;
95199
95200         case "Number":
95201             value = Number(formatString(node.textContent));
95202             break;
95203
95204         case "Object":
95205             value = {};
95206             for (i in node.childNodes) {
95207                 value[node.childNodes[i].nodeName] = build(node.childNodes[i]);
95208             }
95209             break;
95210
95211         case "Array":
95212             value = [];
95213             for (i in node.childNodes) {
95214                 value.push(build(node.childNodes[i]));
95215             }
95216             break;
95217
95218         default:  // "DOMString"
95219             value = formatString(node.textContent);
95220             break;
95221         }
95222
95223         return value;
95224     }
95225
95226     function parse(obj) {
95227         var i, res = {};
95228
95229         res.nodeName = ("name" in obj.attributes) ?
95230                 obj.attributes["name"].value : obj.nodeName;
95231
95232         if (obj.childElementCount === 0) {
95233             res.textContent = obj.textContent;
95234         } else {
95235             res.childNodes = [];
95236
95237             for (i in obj.childNodes) {
95238                 if (obj.childNodes[i].attributes) {
95239                     res.childNodes.push(parse(obj.childNodes[i]));
95240                 }
95241             }
95242         }
95243
95244         return res;
95245     }
95246
95247     // public
95248     function register(type, dbXml, Extension) {
95249         _data[type] = Extension ? new Extension() : {};
95250
95251         if (!dbXml)
95252             return;
95253
95254         _self.__defineGetter__(type, function () {
95255             var fnInit;
95256
95257             if (!_data[type].db) {
95258                 fnInit = _data[type].initdb || initdb;
95259                 _data[type].db = fnInit(dbXml);
95260             }
95261
95262             return _data[type].db;
95263         });
95264     }
95265
95266     function initdb(dbXml) {
95267         var db = {}, xmlHttp, res;
95268
95269         try {
95270             xmlHttp = new XMLHttpRequest();
95271             xmlHttp.open("GET", "dbsamples/" + dbXml, false);
95272             xmlHttp.send();
95273         } catch (e) {
95274             exception.handle(e);
95275         }
95276
95277         if (!xmlHttp.responseXML) {
95278             return null;
95279         }
95280
95281         res = parse(xmlHttp.responseXML.documentElement);
95282         res.childNodes.forEach(function (node) {
95283             db[node.nodeName] = build(node);
95284         });
95285
95286         return db;
95287     }
95288
95289     self = {
95290         register: register,
95291         initdb:   initdb
95292     };
95293
95294     return self;
95295 };
95296
95297 /*
95298  * FileSystem
95299  */
95300
95301 FileSystem = function () {
95302     var self;
95303
95304     // private
95305     function createPath(path) {
95306         var parts = path.replace(/^\//, "").split("/"),
95307             workflow = jWorkflow.order();
95308
95309         parts.forEach(function (part, index) {
95310             var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/");
95311
95312             workflow.andThen(function (prev, baton) {
95313                 baton.take();
95314                 dbfs.mkdir(dir, baton.pass, baton.pass);
95315             });
95316         });
95317
95318         workflow.start();
95319     }
95320
95321     // public
95322     function initdb() {
95323         filesystem.resolve("images", function () {});
95324         filesystem.resolve("videos", function () {});
95325         filesystem.resolve("music", function () {});
95326     }
95327
95328     function createFile(uri) {
95329         var directoryURI;
95330
95331         directoryURI = uri.slice(0, uri.lastIndexOf("/") + 1)
95332                 .replace(/file:\/\//, "");
95333
95334         dbfs.stat(directoryURI, function () {}, function () {
95335             createPath(directoryURI);
95336         });
95337
95338         uri = uri.replace(/file:\/\//, "");
95339         dbfs.touch(uri, function () {});
95340     }
95341
95342     self = {
95343         initdb: initdb,
95344         createFile: createFile
95345     };
95346
95347     return self;
95348 };
95349
95350 /*
95351  * Content
95352  */
95353
95354 Content = function () {
95355     var self, ContentStorage;
95356
95357     ContentStorage = function (contents, directories) {
95358         var i, parentURI;
95359
95360         for (i in directories) {
95361             directories[i].contents = {};
95362             this[directories[i].directoryURI] = directories[i];
95363         }
95364
95365         for (i in contents) {
95366             parentURI = contents[i].contentURI.slice(0,
95367                     contents[i].contentURI.lastIndexOf("/") + 1)
95368                     .replace(/file:\/\//, "");
95369
95370             if (parentURI in this) {
95371                 this[parentURI].contents[contents[i].contentURI] = contents[i];
95372             }
95373         }
95374     };
95375
95376     // public
95377     function initdb(dbXml) {
95378         var i, db;
95379
95380         db = _data.dbBuilder.initdb(dbXml);
95381
95382         if (!db)
95383             return null;
95384
95385         for (i in db.contents) {
95386             _data.FileSystem.createFile(db.contents[i].contentURI);
95387         }
95388
95389         return new ContentStorage(db.contents, db.directories);
95390     }
95391
95392     self = {
95393         initdb: initdb
95394     };
95395
95396     return self;
95397 };
95398
95399 _initialize();
95400
95401 module.exports = _self;
95402
95403 });
95404 define('ripple/platform/tizen/2.0/decorator', function (require, exports, module) {
95405 /*
95406  *  Copyright 2013 Intel Corporation.
95407  *
95408  * Licensed under the Apache License, Version 2.0 (the "License");
95409  * you may not use this file except in compliance with the License.
95410  * You may obtain a copy of the License at
95411  *
95412  * http://www.apache.org/licenses/LICENSE-2.0
95413  *
95414  * Unless required by applicable law or agreed to in writing, software
95415  * distributed under the License is distributed on an "AS IS" BASIS,
95416  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95417  * See the License for the specific language governing permissions and
95418  * limitations under the License.
95419  */
95420
95421 var t = require('ripple/platform/tizen/2.0/typecast'),
95422     ContactDecorator,
95423     _self;
95424
95425 ContactDecorator = function (contact, overlap) {
95426     var raw = {};
95427
95428     // private
95429     function clone(obj) {
95430         return function () {
95431             var Contact = require('ripple/platform/tizen/2.0/ContactBase'),
95432                 duplicate;
95433
95434             duplicate = new Contact(obj);
95435
95436             duplicate.__defineGetter__("id", function () {
95437                 return null;
95438             });
95439
95440             duplicate.__defineGetter__("addressBookId", function () {
95441                 return null;
95442             });
95443
95444             return duplicate;
95445         };
95446     }
95447
95448     // public
95449     function convertToString(format) {
95450         t.Contact("convertToString", arguments);
95451
95452         // TODO: Convert contact according to VCard protocal
95453         return "";
95454     }
95455
95456     raw.id            = overlap ? overlap.id : null;
95457     raw.personId      = overlap ? overlap.personId : null;
95458     raw.addressBookId = overlap ? overlap.addressBookId : null;
95459     raw.lastUpdated   = overlap ? overlap.lastUpdated : null;
95460     raw.isFavorite    = overlap ? overlap.isFavorite : false;
95461     raw.name          = contact.name;
95462     raw.addresses     = contact.addresses;
95463     raw.photoURI      = contact.photoURI;
95464     raw.phoneNumbers  = contact.phoneNumbers;
95465     raw.emails        = contact.emails;
95466     raw.birthday      = contact.birthday;
95467     raw.anniversaries = contact.anniversaries;
95468     raw.organizations = contact.organizations;
95469     raw.notes         = contact.notes;
95470     raw.urls          = contact.urls;
95471     raw.ringtoneURI   = contact.ringtoneURI;
95472     raw.groupIds      = contact.groupIds;
95473
95474     contact.__defineGetter__("id", function () {
95475         return raw.id;
95476     });
95477
95478     contact.__defineGetter__("personId", function () {
95479         return raw.personId;
95480     });
95481
95482     contact.__defineGetter__("addressBookId", function () {
95483         return raw.addressBookId;
95484     });
95485
95486     contact.__defineGetter__("lastUpdated", function () {
95487         return raw.lastUpdated;
95488     });
95489
95490     contact.__defineGetter__("isFavorite", function () {
95491         return raw.isFavorite;
95492     });
95493
95494     contact.__defineGetter__("name", function () {
95495         return raw.name;
95496     });
95497     contact.__defineSetter__("name", function (val) {
95498         try {
95499             raw.name = t.ContactName(val, "?");
95500         } catch (e) {
95501         }
95502     });
95503
95504     contact.__defineGetter__("addresses", function () {
95505         return raw.addresses;
95506     });
95507     contact.__defineSetter__("addresses", function (val) {
95508         try {
95509             raw.addresses = t.ContactAddress(val, "[]");
95510         } catch (e) {
95511         }
95512     });
95513
95514     contact.__defineGetter__("photoURI", function () {
95515         return raw.photoURI;
95516     });
95517     contact.__defineSetter__("photoURI", function (val) {
95518         try {
95519             raw.photoURI = t.DOMString(val, "?");
95520         } catch (e) {
95521         }
95522     });
95523
95524     contact.__defineGetter__("phoneNumbers", function () {
95525         return raw.phoneNumbers;
95526     });
95527     contact.__defineSetter__("phoneNumbers", function (val) {
95528         try {
95529             raw.phoneNumbers = t.ContactPhoneNumber(val, "[]");
95530         } catch (e) {
95531         }
95532     });
95533
95534     contact.__defineGetter__("emails", function () {
95535         return raw.emails;
95536     });
95537     contact.__defineSetter__("emails", function (val) {
95538         try {
95539             raw.emails = t.ContactEmailAddress(val, "[]");
95540         } catch (e) {
95541         }
95542     });
95543
95544     contact.__defineGetter__("birthday", function () {
95545         return raw.birthday;
95546     });
95547     contact.__defineSetter__("birthday", function (val) {
95548         try {
95549             raw.birthday = t.Date(val, "?");
95550         } catch (e) {
95551         }
95552     });
95553
95554     contact.__defineGetter__("anniversaries", function () {
95555         return raw.anniversaries;
95556     });
95557     contact.__defineSetter__("anniversaries", function (val) {
95558         try {
95559             raw.anniversaries = t.ContactAnniversary(val, "[]");
95560         } catch (e) {
95561         }
95562     });
95563
95564     contact.__defineGetter__("organizations", function () {
95565         return raw.organizations;
95566     });
95567     contact.__defineSetter__("organizations", function (val) {
95568         try {
95569             raw.organizations = t.ContactOrganization(val, "[]");
95570         } catch (e) {
95571         }
95572     });
95573
95574     contact.__defineGetter__("notes", function () {
95575         return raw.notes;
95576     });
95577     contact.__defineSetter__("notes", function (val) {
95578         try {
95579             raw.notes = t.DOMString(val, "[]");
95580         } catch (e) {
95581         }
95582     });
95583
95584     contact.__defineGetter__("urls", function () {
95585         return raw.urls;
95586     });
95587     contact.__defineSetter__("urls", function (val) {
95588         try {
95589             raw.urls = t.ContactWebSite(val, "[]");
95590         } catch (e) {
95591         }
95592     });
95593
95594     contact.__defineGetter__("ringtoneURI", function () {
95595         return raw.ringtoneURI;
95596     });
95597     contact.__defineSetter__("ringtoneURI", function (val) {
95598         try {
95599             raw.ringtoneURI = t.DOMString(val, "?");
95600         } catch (e) {
95601         }
95602     });
95603
95604     contact.__defineGetter__("groupIds", function () {
95605         return raw.groupIds;
95606     });
95607     contact.__defineSetter__("groupIds", function (val) {
95608         try {
95609             raw.groupIds = t.ContactGroupId(val, "[]");
95610         } catch (e) {
95611         }
95612     });
95613
95614     if (contact.name) {
95615         contact.name.__defineGetter__("displayName", function () {
95616             return ((overlap && overlap.name) ? overlap.name.displayName :
95617                     null);
95618         });
95619     }
95620
95621     contact.convertToString = convertToString;
95622     contact.clone           = clone(contact);
95623 };
95624
95625 _self = {
95626     Contact: ContactDecorator
95627 };
95628
95629 module.exports = _self;
95630
95631 });
95632 define('ripple/platform/tizen/2.0/download', function (require, exports, module) {
95633 /*
95634  *  Copyright 2012 Intel Corporation.
95635  *
95636  * Licensed under the Apache License, Version 2.0 (the "License");
95637  * you may not use this file except in compliance with the License.
95638  * You may obtain a copy of the License at
95639  *
95640  * http://www.apache.org/licenses/LICENSE-2.0
95641  *
95642  * Unless required by applicable law or agreed to in writing, software
95643  * distributed under the License is distributed on an "AS IS" BASIS,
95644  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95645  * See the License for the specific language governing permissions and
95646  * limitations under the License.
95647  */
95648
95649 var db = require('ripple/db'),
95650     event = require('ripple/event'),
95651     t = require('ripple/platform/tizen/2.0/typecast'),
95652     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
95653     filesystem = require('ripple/platform/tizen/2.0/filesystem'),
95654     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
95655     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
95656     DownloadRequest = require('ripple/platform/tizen/2.0/DownloadRequest'),
95657     DownloadState = {
95658         QUEUED: "QUEUED",
95659         DOWNLOADING: "DOWNLOADING",
95660         PAUSED: "PAUSED",
95661         CANCELED: "CANCELED",
95662         COMPLETED: "COMPLETED",
95663         FAILED: "FAILED"
95664     },
95665     _security = {
95666         "http://tizen.org/privilege/download": ["start"]
95667     },
95668     DB_DOWNLOAD_KEY = "tizen1-db-download",
95669     DownloadItem, _isInitialized = false, INTERVAL = 1000,
95670     _downloads = [], _resources = [], _self;
95671
95672 function _initDownloadItem(download) {
95673     var url, index, isExist = false;
95674     url = download.url;
95675     if (download.destination === null) {
95676         download.destination = "downloads";
95677     }
95678     if (download.fileName === null) {
95679         index = url.lastIndexOf('\/') + 1;
95680         download.fileName = url.substring(index);
95681     }
95682     if (!_isInitialized) {
95683         initializeResource();
95684     }
95685     _resources.some(function (value) {
95686         if (value.url === url) {
95687             download.size           = Number(value.size);
95688             download.speed          = Number(value.speed);
95689             download.estimatedTime = Math.round(value.estimatedTime * 100) / 100;
95690             download.MIMEType       = value.MIMEType;
95691             isExist =  true;
95692             return;
95693         }
95694     });
95695     if (!isExist) {
95696         download.state = DownloadState.FAILED;
95697         _exec(download.callback, 'onfailed', download.id, new WebAPIError(errorcode.NOT_FOUND_ERR));
95698         return;
95699     }
95700     return download;
95701 }
95702
95703 function _exec(callback, name, downloadId, arg1, arg2) {
95704     if (callback === null) {
95705         return;
95706     }
95707
95708     window.setTimeout(function () {
95709         switch (name) {
95710         case "onprogress":
95711             callback[name](downloadId, arg1, arg2);
95712             break;
95713
95714         case "onpaused":
95715             callback[name](downloadId);
95716             break;
95717
95718         case "oncanceled":
95719             callback[name](downloadId);
95720             break;
95721
95722         case "oncompleted":
95723             callback[name](downloadId, arg1);
95724             break;
95725
95726         case "onfailed":
95727             callback[name](downloadId, arg1);
95728             break;
95729
95730         default:
95731             break;
95732         }
95733     }, 1);
95734 }
95735
95736 function _getDownloadObjById(id) {
95737     var isFound = false, backObj;
95738     id = Number(id);
95739     _downloads.some(function (obj) {
95740         if (obj.id === id) {
95741             backObj = obj;
95742             isFound = true;
95743             return;
95744         }
95745     });
95746     if (!isFound) {
95747         throw new WebAPIException(errorcode.NOT_FOUND_ERR);
95748     }
95749     return backObj;
95750 }
95751
95752 function initializeResource() {
95753     _resources = db.retrieveObject(DB_DOWNLOAD_KEY);
95754     _isInitialized = true;
95755 }
95756
95757 function _saveFile(downloadObj, callback) {
95758     var name, path, content;
95759
95760     name = downloadObj.fileName;
95761     path = downloadObj.destination;
95762     content = 'size|' + downloadObj.size + ',speed|' + downloadObj.speed + ',url|' + downloadObj.url + ',estimatedTime|' + downloadObj.estimatedTime;
95763     function onsuccess(fs) {
95764         fs.write(content);
95765         fs.close();
95766     }
95767     function onerror(e) {
95768         _exec(downloadObj.callback, 'onfailed', downloadObj.id, e);
95769     }
95770     function rename(name) { //index.html==>index_1.html
95771         var index, c;
95772         index = name.lastIndexOf('.');
95773         if (index < 0) {
95774             index = name.length;
95775         }
95776         c = name.substr(index - 2, 1);
95777         if (c === '_') {
95778             name = name.substr(0, index - 1) + (Number(name.substr(index - 1, 1)) + 1) + name.substring(index);
95779         } else {
95780             name = name.substr(0, index) + "_1" + name.substring(index);
95781         }
95782         return name;
95783     }
95784
95785     filesystem.resolve(path, function (dir) {
95786         var file, isExist = true;
95787         while (isExist) {
95788             try {
95789                 file = dir.resolve(name);
95790                 name = rename(name);
95791             } catch (e) {
95792                 isExist = false;
95793             }
95794         }
95795         file = dir.createFile(name);
95796         file.openStream('w', onsuccess, onerror, 'UTF-8');
95797         callback(name);
95798     }, onerror, "rw");
95799 }
95800
95801 DownloadItem = function (download, callback) {
95802     var _self;
95803     _self = {
95804         id           : Number(Math.uuid(8, 10)),
95805         url          : download.url,
95806         state        : DownloadState.QUEUED,
95807         fileName     : download.fileName || null,
95808         destination  : download.destination || null,
95809         callback     : callback || null
95810     };
95811     return _self;
95812 };
95813
95814 _self = function () {
95815     function start(downloadRequest, downloadCallback) {
95816         var downloadObj, fileSize, increment, receivedSize = 0, intervalId;
95817
95818         if (!_security.start) {
95819             throw new WebAPIException(errorcode.SECURITY_ERR);
95820         }
95821
95822         t.DownloadManager("start", arguments);
95823
95824         downloadObj = new DownloadItem(downloadRequest, downloadCallback);
95825         _downloads.push(downloadObj);
95826         downloadObj = _initDownloadItem(downloadObj);
95827         if (downloadObj === null || downloadObj === undefined) {
95828             return;
95829         }
95830         downloadObj.state = DownloadState.DOWNLOADING;
95831
95832         fileSize = downloadObj.size;
95833         increment = downloadObj.speed;
95834         intervalId = setInterval(function () {
95835             if (receivedSize >= fileSize) {//Finish downloading
95836                 receivedSize = fileSize;
95837                 downloadObj.state = DownloadState.COMPLETED;
95838                 _saveFile(downloadObj, function (fileName) {
95839                     _exec(downloadObj.callback, 'oncompleted', downloadObj.id, fileName);
95840                 });
95841                 clearInterval(intervalId);
95842             } else { // Continue downloading
95843                 receivedSize += increment;
95844                 downloadObj.receivedSize = receivedSize;
95845                 _exec(downloadObj.callback, 'onprogress', downloadObj.id, receivedSize, fileSize);
95846             }
95847         }, INTERVAL);
95848         downloadObj.intervalId = intervalId;
95849         return downloadObj.id;
95850     }
95851
95852     function cancel(downloadId) {
95853         var downloadObj;
95854
95855         t.DownloadManager("cancel", arguments);
95856
95857         downloadObj = _getDownloadObjById(downloadId);
95858         clearInterval(downloadObj.intervalId);
95859         if (downloadObj.state !== DownloadState.DOWNLOADING &&
95860             downloadObj.state !== DownloadState.PAUSED) {
95861             _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR));
95862             return;
95863         }
95864         downloadObj.state = DownloadState.CANCELED;
95865         _exec(downloadObj.callback, 'oncanceled', downloadObj.id);
95866     }
95867
95868     function pause(downloadId) {
95869         var downloadObj;
95870
95871         t.DownloadManager("pause", arguments);
95872
95873         downloadObj = _getDownloadObjById(downloadId);
95874         clearInterval(downloadObj.intervalId);
95875         if (downloadObj.state !== DownloadState.DOWNLOADING) {
95876             _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR));
95877             return;
95878         }
95879         downloadObj.state = DownloadState.PAUSED;
95880         _exec(downloadObj.callback, 'onpaused', downloadObj.id);
95881     }
95882
95883     function resume(downloadId) {
95884         var downloadObj, fileSize, receivedSize, increment, intervalId;
95885
95886         t.DownloadManager("resume", arguments);
95887
95888         downloadObj  = _getDownloadObjById(downloadId);
95889         fileSize     = downloadObj.size;
95890         receivedSize = downloadObj.receivedSize;
95891         increment    = downloadObj.speed;
95892
95893         if (downloadObj.state !== DownloadState.PAUSED) {
95894             _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR));
95895             return;
95896         }
95897         downloadObj.state = DownloadState.DOWNLOADING;
95898         intervalId = setInterval(function () {
95899             if (receivedSize >= fileSize) {//Finish downloading
95900                 receivedSize = fileSize;
95901                 downloadObj.state = DownloadState.COMPLETED;
95902                 _saveFile(downloadObj, function (fileName) {
95903                     _exec(downloadObj.callback, 'oncompleted', downloadObj.id, fileName);
95904                 });
95905                 clearInterval(intervalId);
95906             } else {// Continue downloading
95907                 receivedSize += increment;
95908                 downloadObj.receivedSize = receivedSize;
95909                 _exec(downloadObj.callback, 'onprogress', downloadObj.id, receivedSize, fileSize);
95910             }
95911         }, INTERVAL);
95912         downloadObj.intervalId = intervalId;
95913     }
95914
95915     function getState(downloadId) {
95916         var downloadObj;
95917
95918         t.DownloadManager("getState", arguments);
95919
95920         downloadObj = _getDownloadObjById(downloadId);
95921         return downloadObj.state;
95922     }
95923
95924     function getDownloadRequest(downloadId) {
95925         var req, downloadObj;
95926
95927         t.DownloadManager("getDownloadRequest", arguments);
95928
95929         downloadObj = _getDownloadObjById(downloadId);
95930         req = new DownloadRequest(downloadObj.url, downloadObj.destination, downloadObj.fileName);
95931         return req;
95932     }
95933
95934     function getMIMEType(downloadId) {
95935         var downloadObj;
95936
95937         t.DownloadManager("getMIMEType", arguments);
95938
95939         downloadObj = _getDownloadObjById(downloadId);
95940         return downloadObj.MIMEType;
95941     }
95942
95943     function setListener(downloadId, downloadCallback) {
95944         var downloadObj;
95945
95946         t.DownloadManager("setListener", arguments);
95947
95948         downloadObj = _getDownloadObjById(downloadId);
95949         if (downloadObj) {
95950             downloadObj.callback = downloadCallback;
95951         }
95952     }
95953
95954     function handleSubFeatures(subFeatures) {
95955         var i, subFeature;
95956
95957         for (subFeature in subFeatures) {
95958             for (i in _security[subFeature]) {
95959                 _security[_security[subFeature][i]] = true;
95960             }
95961         }
95962     }
95963
95964     var download = {
95965         start: start,
95966         cancel: cancel,
95967         pause: pause,
95968         resume: resume,
95969         getState: getState,
95970         getDownloadRequest: getDownloadRequest,
95971         getMIMEType: getMIMEType,
95972         setListener: setListener,
95973         handleSubFeatures: handleSubFeatures
95974     };
95975
95976     return download;
95977 };
95978
95979 event.on('downloadResourceChanged', function () {
95980     _isInitialized = false;
95981 });
95982
95983 module.exports = _self;
95984
95985 });
95986 define('ripple/platform/tizen/2.0/errorcode', function (require, exports, module) {
95987 /*
95988  *  Copyright 2011 Intel Corporation.
95989  *
95990  * Licensed under the Apache License, Version 2.0 (the "License"),
95991  * you may not use this file except in compliance with the License.
95992  * You may obtain a copy of the License at
95993  *
95994  * http://www.apache.org/licenses/LICENSE-2.0
95995  *
95996  * Unless required by applicable law or agreed to in writing, software
95997  * distributed under the License is distributed on an "AS IS" BASIS,
95998  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95999  * See the License for the specific language governing permissions and
96000  * limitations under the License.
96001  */
96002
96003 var _self = {};
96004
96005 _self.__defineGetter__("UNKNOWN_ERR", function () {
96006     return 0;
96007 });
96008
96009 _self.__defineGetter__("INDEX_SIZE_ERR", function () {
96010     return 1;
96011 });
96012
96013 _self.__defineGetter__("DOMSTRING_SIZE_ERR", function () {
96014     return 2;
96015 });
96016
96017 _self.__defineGetter__("HIERARCHY_REQUEST_ERR", function () {
96018     return 3;
96019 });
96020
96021 _self.__defineGetter__("WRONG_DOCUMENT_ERR", function () {
96022     return 4;
96023 });
96024
96025 _self.__defineGetter__("INVALID_CHARACTER_ERR", function () {
96026     return 5;
96027 });
96028
96029 _self.__defineGetter__("NO_DATA_ALLOWED_ERR", function () {
96030     return 6;
96031 });
96032
96033 _self.__defineGetter__("NO_MODIFICATION_ALLOWED_ERR", function () {
96034     return 7;
96035 });
96036
96037 _self.__defineGetter__("NOT_FOUND_ERR", function () {
96038     return 8;
96039 });
96040
96041 _self.__defineGetter__("NOT_SUPPORTED_ERR", function () {
96042     return 9;
96043 });
96044
96045 _self.__defineGetter__("INUSE_ATTRIBUTE_ERR", function () {
96046     return 10;
96047 });
96048
96049 _self.__defineGetter__("INVALID_STATE_ERR", function () {
96050     return 11;
96051 });
96052
96053 _self.__defineGetter__("SYNTAX_ERR", function () {
96054     return 12;
96055 });
96056
96057 _self.__defineGetter__("INVALID_MODIFICATION_ERR", function () {
96058     return 13;
96059 });
96060
96061 _self.__defineGetter__("NAMESPACE_ERR", function () {
96062     return 14;
96063 });
96064
96065 _self.__defineGetter__("INVALID_ACCESS_ERR", function () {
96066     return 15;
96067 });
96068
96069 _self.__defineGetter__("VALIDATION_ERR", function () {
96070     return 16;
96071 });
96072
96073 _self.__defineGetter__("TYPE_MISMATCH_ERR", function () {
96074     return 17;
96075 });
96076
96077 _self.__defineGetter__("SECURITY_ERR", function () {
96078     return 18;
96079 });
96080
96081 _self.__defineGetter__("NETWORK_ERR", function () {
96082     return 19;
96083 });
96084
96085 _self.__defineGetter__("ABORT_ERR", function () {
96086     return 20;
96087 });
96088
96089 _self.__defineGetter__("URL_MISMATCH_ERR", function () {
96090     return 21;
96091 });
96092
96093 _self.__defineGetter__("QUOTA_EXCEEDED_ERR", function () {
96094     return 22;
96095 });
96096
96097 _self.__defineGetter__("TIMEOUT_ERR", function () {
96098     return 23;
96099 });
96100
96101 _self.__defineGetter__("INVALID_NODE_TYPE_ERR", function () {
96102     return 24;
96103 });
96104
96105 _self.__defineGetter__("DATA_CLONE_ERR", function () {
96106     return 25;
96107 });
96108
96109 _self.__defineGetter__("INVALID_VALUES_ERR", function () {
96110     return 99;
96111 });
96112
96113 _self.__defineGetter__("IO_ERR", function () {
96114     return 100;
96115 });
96116
96117 _self.__defineGetter__("SERVICE_NOT_AVAILABLE_ERR", function () {
96118     return 111;
96119 });
96120
96121 module.exports = _self;
96122
96123
96124 });
96125 define('ripple/platform/tizen/2.0/filesystem', function (require, exports, module) {
96126 /*
96127  *  Copyright 2012 Intel Corporation.
96128  *
96129  * Licensed under the Apache License, Version 2.0 (the "License");
96130  * you may not use this file except in compliance with the License.
96131  * You may obtain a copy of the License at
96132  *
96133  * http://www.apache.org/licenses/LICENSE-2.0
96134  *
96135  * Unless required by applicable law or agreed to in writing, software
96136  * distributed under the License is distributed on an "AS IS" BASIS,
96137  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
96138  * See the License for the specific language governing permissions and
96139  * limitations under the License.
96140  */
96141
96142 var event = require('ripple/event'),
96143     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
96144     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
96145     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
96146     utils = require('ripple/utils'),
96147     dbfs  = require('ripple/platform/tizen/2.0/dbfs'),
96148     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
96149     _maxPathLength = 256,
96150     _virtualRoots = ["documents", "images", "music", "videos", "downloads", "wgt-package", "wgt-private", "wgt-private-tmp", "removable", "attachments"],
96151     _security = {
96152         "http://tizen.org/privilege/filesystem": [],
96153         "http://tizen.org/privilege/filesystem.read": ["copyTo", "moveTo", "createDirectory", "createFile", "deleteDirectory", "deleteFile", "openStreamR"],
96154         "http://tizen.org/privilege/filesystem.write": ["readAsText", "openStreamW"],
96155         all: true
96156     },
96157     _realRoots = dbfs.roots,
96158     _r2vmap = {},
96159     _v2rmap = {},
96160     _initialized = false,
96161     _readOnly  = false,
96162     _writeOnly = false,
96163     _defaultMode = "rw",
96164     _storages = [], // filesystem storages
96165     _observers = [],
96166     File,
96167     FileStream,
96168     FileFilter,
96169     FileSystemStorage;
96170
96171 function _isValidChar(c) {
96172     return  (c >= '0' && c <= '9') ||
96173         (c >= 'a' && c <= 'z') ||
96174         (c >= 'A' && c <= 'Z') ||
96175         (c === ' ') ||
96176         (c === '_') ||
96177         (c === '-') ||
96178         (c === '.');
96179 }
96180
96181 function _isValidFileName(name) {
96182     var _valid = true,
96183         _c;
96184
96185     if (name === '' || name === '.' || name === '..' || (name.length > _maxPathLength)) {
96186         _valid = false;
96187     } else {
96188         for (_c = 0; _c < name.length; _c++) {
96189             if (!_isValidChar(name[_c])) {
96190                 _valid = false;
96191                 break;
96192             }
96193         }
96194     }
96195
96196     return _valid;
96197 }
96198
96199 function _initialize() {
96200     var _i;
96201
96202     _storages.push(FileSystemStorage("InternalFlash", "INTERNAL", "MOUNTED" ));
96203     _storages.push(FileSystemStorage("MMC", "EXTERNAL", "REMOVED"));
96204     dbfs.initialize();
96205
96206     // set up the map between real path and virtual path
96207     for (_i = 0; _i < _virtualRoots.length; _i++) {
96208         _r2vmap[_realRoots[_i]] = _virtualRoots[_i];
96209     }
96210
96211     utils.forEach(_r2vmap, function (value, key) {
96212         _v2rmap[value] = key;
96213     });
96214 }
96215
96216 function _resolveSync(srcLocation, onSuccess, onError, accessMode) {
96217     var _parts = srcLocation.replace(/\/$/, '').split("/"),
96218         _header, _fullPath,
96219         _i;
96220
96221     // TODO: Initialize at bootstrap and emulatorBridge.link
96222     if (!_initialized) {
96223         _initialize();
96224         _initialized = true;
96225     }
96226
96227     for (_i = 0; _i < _parts.length; _i++) {
96228         if (!_isValidFileName(_parts[_i])) {
96229             if (onError) {
96230                 onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
96231             }
96232             return;
96233         }
96234     }
96235
96236     _header = _v2rmap[_parts[0]];
96237     if (_header === undefined) {
96238         if (onError) {
96239             onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
96240         }
96241         return;
96242     }
96243
96244     if (_parts.length === 1) {
96245         _fullPath = _header;
96246     } else {
96247         _fullPath = _header + "/" + _parts.splice(1, _parts.length - 1).join("/");
96248     }
96249
96250     dbfs.stat(_fullPath,
96251             function (entry) {
96252                 onSuccess(new File(entry, accessMode));
96253             },
96254             function () {
96255                 if (onError) {
96256                     onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
96257                 }
96258             });
96259 }
96260
96261 function _resolveAsync(onSuccess, onError, srcLocation, accessMode) {
96262     _resolveSync(srcLocation,
96263                 function (file) {
96264                     setTimeout(function () {
96265                         onSuccess(file);
96266                     }, 1);
96267                 },
96268                 function (e) {
96269                     setTimeout(function () {
96270                         onError(e);
96271                     }, 1);
96272                 },
96273                 accessMode);
96274 }
96275
96276 File = function (entry, mode) {
96277     var _entry = entry,
96278         _mode = mode,
96279         _parent,
96280         _self;
96281
96282     function _r2v(rpath) {
96283         var i, v, r, regExp;
96284
96285         for (i = 0; i < _virtualRoots.length; i++) {
96286             v = _virtualRoots[i];
96287             r = _v2rmap[v];
96288             if (rpath.match("^" + r)) {
96289                 regExp = new RegExp("^" + r);
96290                 return rpath.replace(regExp, v);
96291             }
96292         }
96293
96294         return "";
96295     }
96296
96297     function _v2r(vpath) {
96298         var i, v, r, regExp;
96299
96300         for (i = 0; i < _virtualRoots.length; i++) {
96301             v = _virtualRoots[i];
96302             r = _v2rmap[v];
96303             if (vpath.match("^" + v)) {
96304                 regExp = new RegExp("^" + v);
96305                 return vpath.replace(regExp, r);
96306             }
96307         }
96308
96309         return "";
96310     }
96311
96312     function _copyMoveInternal(onSuccess, onError, src, dst, overwrite, func) {
96313         var _srcName = String(src),
96314             _dstName = String(dst),
96315             _src = null,
96316             _dst = null,
96317             _error = false,
96318             _dstParent = null,
96319             _dstParts  = _dstName.split("/"),
96320             _dstParentName = _dstParts.splice(0, _dstParts.length - 1).join("/");
96321
96322         if (!_entry.isDirectory) {
96323             if (onError) {
96324                 setTimeout(function () {
96325                     onError(new WebAPIError(errorcode.IO_ERR));
96326                 }, 1);
96327             }
96328             return undefined;
96329         }
96330
96331         _resolveSync(_srcName,
96332                 function (file) {
96333                     _src = file;
96334                 },
96335                 function (e) {
96336                     setTimeout(function () {
96337                         onError(e);
96338                     }, 1);
96339                 },
96340                 _mode);
96341
96342         if (_src) {
96343             if (_src.parent.fullPath === _self.fullPath) {
96344                 if (!_readOnly && _mode !== "r") {
96345                     _resolveSync(_dstParentName,
96346                             function (file) {
96347                                 _dstParent = file;
96348                             },
96349                             function (e) {
96350                                 setTimeout(function () {
96351                                     onError(e);
96352                                 }, 1);
96353                             },
96354                             _mode);
96355
96356                     if (_dstParent === null) {
96357                         return undefined;
96358                     }
96359
96360                     _resolveSync(_dstName,
96361                             function (file) {
96362                                 _dst = file;
96363                             },
96364                             function (e) {
96365                                 if (e.code !== errorcode.NOT_FOUND_ERR) {
96366                                     setTimeout(function () {
96367                                         onError(e);
96368                                     }, 1);
96369                                     _error = true;
96370                                 }
96371                             },
96372                             _mode);
96373
96374                     if (_error) {
96375                         return undefined;
96376                     }
96377
96378                     if (_src.isFile) {
96379                         if (_dst === null) {
96380                             func(_v2r(_srcName), _v2r(_dstName),
96381                                     function () {
96382                                         setTimeout(function () {
96383                                             onSuccess();
96384                                         }, 1);
96385                                     },
96386                                     function () {});
96387                             return null;
96388                         } else {
96389                             if (_dst.isFile && Boolean(overwrite) && (_srcName !== _dstName)) {
96390                                 func(_v2r(_srcName), _v2r(_dstName),
96391                                         function () {
96392                                             setTimeout(function () {
96393                                                 onSuccess();
96394                                             }, 1);
96395                                         },
96396                                         function () {});
96397                                 return null;
96398                             } else {
96399                                 setTimeout(function () {
96400                                     onError(new WebAPIError(errorcode.IO_ERR));
96401                                 }, 1);
96402                             }
96403                         }
96404                     } else {
96405                         if (_dst === null) {
96406                             func(_v2r(_srcName), _v2r(_dstName),
96407                                 function () {
96408                                     setTimeout(function () {
96409                                         onSuccess();
96410                                     }, 1);
96411                                 },
96412                                 function () {});
96413                             return null;
96414                         } else {
96415                             setTimeout(function () {
96416                                 onError(new WebAPIError(errorcode.IO_ERR));
96417                             }, 1);
96418                         }
96419                     }
96420                 } else {
96421                     if (onError) {
96422                         setTimeout(function () {
96423                             onError(new WebAPIError(errorcode.SECURITY_ERR));
96424                         }, 1);
96425                     }
96426                 }
96427             } else {
96428                 if (onError) {
96429                     setTimeout(function () {
96430                         onError(new WebAPIError(errorcode.IO_ERR));
96431                     }, 1);
96432                 }
96433             }
96434         }
96435
96436         return undefined;
96437     }
96438
96439     _self = {
96440         toURI: function () {
96441             return "file://" + _entry.fullPath;
96442         },
96443         listFiles: function (onSuccess, onError, filter) {
96444             var _filter, _filterName, _startCreated, _endCreated, _startModified, _endModified;
96445
96446             if (filter !== null && filter !== undefined) {
96447
96448                 if (typeof filter === 'number' || typeof filter === 'string') {
96449                     throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
96450                 }
96451                 _filter = filter;
96452                 _filterName = _filter.name;
96453                 _startModified = _filter.startModified;
96454                 _endModified   = _filter.endModified;
96455                 _startCreated = _filter.startCreated;
96456                 _endCreated   = _filter.endCreated;
96457
96458             }
96459             if ((_filterName !== undefined && typeof _filterName !== 'string') ||
96460                 (_startModified !== undefined && !tizen1_utils.isValidDate(_startModified)) ||
96461                 (_endModified !== undefined && !tizen1_utils.isValidDate(_endModified)) ||
96462                 (_endCreated !== undefined && !tizen1_utils.isValidDate(_endCreated)) ||
96463                 (_startCreated !== undefined && !tizen1_utils.isValidDate(_startCreated))) {
96464                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
96465             }
96466
96467             function _matchName(fileName) {
96468                 var _matched = true,
96469                     _name1 = String(_filterName).toLowerCase(),
96470                     _name2 = fileName.toLowerCase(),
96471                     _pattern;
96472
96473                 if (_filterName !== undefined && _filterName !== null) {
96474                     if (!_name1.match("\\\\%")) {
96475                         if (_name1.match("%")) {
96476                             _pattern = new RegExp("^" + _name1.replace(/%/g, ".*") + "$");
96477                             _matched = _name2.match(_pattern) ? true : false;
96478                         } else {
96479                             _matched = (_name1 === _name2);
96480                         }
96481                     } else {
96482                         // % is not allowed as a part of file name
96483                         _matched = false;
96484                     }
96485                 }
96486
96487                 return _matched;
96488             }
96489
96490             function _matchDate(date) {
96491                 var _matched = true;
96492
96493                 if (date === undefined) return true;
96494
96495                 if (_startModified !== undefined && _startModified !== null) {
96496                     _matched = (date.getTime() >= _startModified.getTime());
96497                 }
96498
96499                 if (_matched && (_endModified !== undefined && _endModified !== null)) {
96500                     _matched = (date.getTime() <= _endModified.getTime());
96501                 }
96502
96503                 return _matched;
96504             }
96505
96506             function _matchFilter(entry) {
96507                 return _matchName(entry.name) && _matchDate(entry.lastModifiedDate) && _matchDate(entry.createdDate);
96508             }
96509
96510             function _listFiles() {
96511                 var _files = [];
96512
96513                 if (!_entry.isDirectory) {
96514                     if (onError) {
96515                         setTimeout(function () {
96516                             onError(new WebAPIError(errorcode.IO_ERR));
96517                         }, 1);
96518                     }
96519                     return undefined;
96520                 }
96521
96522                 utils.forEach(_entry.children, function (child) {
96523                     if (_matchFilter(child)) {
96524                         _files.push(new File(child, _mode));
96525                     }
96526                 });
96527
96528                 setTimeout(function () {
96529                     onSuccess(_files);
96530                 }, 1);
96531
96532                 return null;
96533             }
96534
96535             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "listFiles", _listFiles);
96536         },
96537         openStream: function (mode, onSuccess, onError, encoding) {
96538             function _openStream() {
96539                 var  _openMode = String(mode),
96540                     _encoding = encoding ? String(encoding) : "UTF-8";
96541
96542                 if (_openMode !== "r" && _openMode !== "w" && _openMode !== "a") {
96543                     if (onError) {
96544                         setTimeout(function () {
96545                             onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
96546                         }, 1);
96547                     }
96548                     return undefined;
96549                 }
96550
96551                 if (!_security.all && ((!_security.openStreamR && _openMode === "r") || (!_security.openStreamW && _openMode === "w"))) {
96552                     throw new WebAPIException(errorcode.SECURITY_ERR);
96553                 }
96554
96555                 if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
96556                     if (onError) {
96557                         setTimeout(function () {
96558                             onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
96559                         }, 1);
96560                     }
96561                     return undefined;
96562                 }
96563
96564                 if (((_readOnly || _mode === "r") && (_openMode === "w" || _openMode === "a")) ||
96565                     (_writeOnly && _openMode === "r")) {
96566                     if (onError) {
96567                         setTimeout(function () {
96568                             onError(new WebAPIError(errorcode.SECURITY_ERR));
96569                         }, 1);
96570                     }
96571                     return undefined;
96572                 }
96573
96574                 setTimeout(function () {
96575                     onSuccess(new FileStream(_entry, _openMode, _encoding));
96576                 }, 1);
96577
96578                 return null;
96579             }
96580
96581             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "openStream", _openStream);
96582         },
96583         readAsText: function (onSuccess, onError, encoding) {
96584             if (!_security.all && !_security.readAsText) {
96585                 throw new WebAPIException(errorcode.SECURITY_ERR);
96586             }
96587
96588             function _readAsText() {
96589                 var _encoding = encoding ? String(encoding) : "UTF-8";
96590                 if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
96591                     if (onError) {
96592                         setTimeout(function () {
96593                             onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
96594                         }, 1);
96595                     }
96596                     return undefined;
96597                 }
96598
96599                 if (_writeOnly) {
96600                     if (onError) {
96601                         setTimeout(function () {
96602                             onError(new WebAPIError(errorcode.SECURITY_ERR));
96603                         }, 1);
96604                     }
96605                     return undefined;
96606                 }
96607
96608                 if (_self.isFile) {
96609                     dbfs.read(_entry.fullPath,
96610                             function (data) {
96611                                 setTimeout(function () {
96612                                     onSuccess(data);
96613                                 }, 1);
96614                             },
96615                             function () {});
96616                     return null;
96617                 } else {
96618                     if (onError) {
96619                         setTimeout(function () {
96620                             onError(new WebAPIError(errorcode.IO_ERR));
96621                         }, 1);
96622                     }
96623                 }
96624
96625                 return undefined;
96626             }
96627
96628             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "readAsText", _readAsText);
96629         },
96630         copyTo: function (src, dst, overwrite, onSuccess, onError) {
96631             if (!_security.all && !_security.copyTo) {
96632                 throw new WebAPIException(errorcode.SECURITY_ERR);
96633             }
96634
96635             function _copyTo() {
96636                 return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.cp);
96637             }
96638
96639             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "copyTo", _copyTo);
96640         },
96641         moveTo: function (src, dst, overwrite, onSuccess, onError) {
96642             if (!_security.all && !_security.moveTo) {
96643                 throw new WebAPIException(errorcode.SECURITY_ERR);
96644             }
96645
96646             function _moveTo() {
96647                 return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.mv);
96648             }
96649
96650             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "moveTo", _moveTo);
96651         },
96652         createDirectory: function (dirPath) {
96653             var _path  = String(dirPath),
96654                 _parts = _path.replace(/\/$/, "").split("/"),
96655                 _dir   = null,
96656                 _exist = null,
96657                 _current = _entry.fullPath,
96658                 _i;
96659
96660             if (!_security.all && !_security.createDirectory) {
96661                 throw new WebAPIException(errorcode.SECURITY_ERR);
96662             }
96663
96664             function onSuccess(entry) {
96665                 _dir = entry;
96666             }
96667
96668             for (_i = 0; _i < _parts.length; _i++) {
96669                 if (!_isValidFileName(_parts[_i])) {
96670                     throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
96671                 }
96672             }
96673
96674             if (!entry.isDirectory) {
96675                 throw new WebAPIException(errorcode.IO_ERR);
96676             }
96677
96678             _exist = _parts.reduce(function (obj, token) {
96679                 return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
96680             }, _entry);
96681
96682             if (_exist) {
96683                 throw new WebAPIException(errorcode.IO_ERR);
96684             }
96685
96686             if (_readOnly || _mode === "r") {
96687                 throw new WebAPIException(errorcode.SECURITY_ERR);
96688             }
96689
96690             for (_i = 0; _i < _parts.length; _i++) {
96691                 _current = _current + "/" + _parts[_i];
96692                 dbfs.mkdir(_current, onSuccess);
96693             }
96694
96695             return new File(_dir, _mode);
96696         },
96697         createFile: function (filePath) {
96698             var _name = String(filePath),
96699                 _file = null;
96700
96701             if (!_security.all && !_security.createFile) {
96702                 throw new WebAPIException(errorcode.SECURITY_ERR);
96703             }
96704
96705             if (!_isValidFileName(_name)) {
96706                 throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
96707             }
96708
96709             if (!entry.isDirectory || (_entry.children && _entry.children[_name])) {
96710                 throw new WebAPIException(errorcode.IO_ERR);
96711             }
96712
96713             if (_readOnly || _mode === "r") {
96714                 throw new WebAPIException(errorcode.SECURITY_ERR);
96715             }
96716
96717             dbfs.touch(_entry.fullPath + "/" + _name,
96718                         function (entry) {
96719                             _file = new File(entry, _mode);
96720                         },
96721                         function () {});
96722
96723             return _file;
96724         },
96725         resolve: function (filePath) {
96726             var _fullPath = _self.fullPath + "/" + String(filePath),
96727                 _file = null;
96728
96729             if (!_entry.isDirectory) {
96730                 throw new WebAPIException(errorcode.IO_ERR);
96731             }
96732
96733             _resolveSync(_fullPath,
96734                     function (file) {
96735                         _file = file;
96736                     },
96737                     function (e) {
96738                         throw (e);
96739                     },
96740                     _mode);
96741
96742             return _file;
96743         },
96744         deleteDirectory: function (directory, recursive, onSuccess, onError) {
96745             if (!_security.all && !_security.deleteDirectory) {
96746                 throw new WebAPIException(errorcode.SECURITY_ERR);
96747             }
96748
96749             function _deleteDirectory() {
96750                 var _dir = null,
96751                     _dirName = String(directory);
96752                 _resolveSync(_dirName,
96753                         function (file) {
96754                             _dir = file;
96755                         },
96756                         function (e) {
96757                             setTimeout(function () {
96758                                 onError(e);
96759                             }, 1);
96760                         },
96761                         _mode);
96762
96763                 if (_dir) {
96764                     if (_dir.isDirectory &&
96765                         _dir.parent.fullPath === _self.fullPath &&
96766                         (!recursive && _dir.length === 0)) {
96767                         if (!_readOnly && _mode !== "r") {
96768                             dbfs.rmdir(_v2r(_dirName),
96769                                     function () {
96770                                         setTimeout(function () {
96771                                             onSuccess();
96772                                         }, 1);
96773                                     },
96774                                     function () {});
96775                             return null;
96776                         } else {
96777                             if (onError) {
96778                                 setTimeout(function () {
96779                                     onError(new WebAPIError(errorcode.SECURITY_ERR));
96780                                 }, 1);
96781                             }
96782                         }
96783                     } else {
96784                         if (onError) {
96785                             setTimeout(function () {
96786                                 onError(new WebAPIError(errorcode.IO_ERR));
96787                             }, 1);
96788                         }
96789                     }
96790                 }
96791
96792                 return undefined;
96793             }
96794
96795             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "deleteDirectory", _deleteDirectory);
96796         },
96797         deleteFile: function (fileName, onSuccess, onError) {
96798             if (!_security.all && !_security.deleteFile) {
96799                 throw new WebAPIException(errorcode.SECURITY_ERR);
96800             }
96801
96802             function _deleteFile() {
96803                 var _file = null;
96804                 _resolveSync(String(fileName),
96805                         function (file) {
96806                             _file = file;
96807                         },
96808                         function (e) {
96809                             if (onError) {
96810                                 setTimeout(function () {
96811                                     onError(e);
96812                                 }, 1);
96813                             }
96814                         },
96815                         _mode);
96816
96817                 if (_file) {
96818                     if (_file.isFile && _file.parent.fullPath === _self.fullPath) {
96819                         if (!_readOnly && _mode !== "r") {
96820                             dbfs.rm(_v2r(fileName),
96821                                     function () {
96822                                         setTimeout(function () {
96823                                             onSuccess();
96824                                         }, 1);
96825                                     },
96826                                     function () {});
96827                             return null;
96828                         } else {
96829                             if (onError) {
96830                                 setTimeout(function () {
96831                                     onError(new WebAPIError(errorcode.SECURITY_ERR));
96832                                 }, 1);
96833                             }
96834                         }
96835                     } else {
96836                         if (onError) {
96837                             setTimeout(function () {
96838                                 onError(new WebAPIError(errorcode.IO_ERR));
96839                             }, 1);
96840                         }
96841                     }
96842                 }
96843
96844                 return undefined;
96845             }
96846
96847             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "deleteFile", _deleteFile);
96848         }
96849     };
96850
96851     _self.__defineGetter__("parent", function () {
96852         var _parts = _self.fullPath.split("/");
96853
96854         if (_parent === undefined) {
96855             if (_parts.length === 1) {
96856                 // virtual root's parent is null
96857                 _parent = null;
96858             } else {
96859                 _resolveSync(_parts.splice(0, _parts.length - 1).join("/"),
96860                         function (file) {
96861                             _parent = file;
96862                         },
96863                         function () {},
96864                         _mode);
96865             }
96866             return _parent;
96867         } else {
96868             return _parent;
96869         }
96870     });
96871
96872     _self.__defineGetter__("readOnly", function () {
96873         return false;
96874     });
96875
96876     _self.__defineGetter__("isFile", function () {
96877         return !_entry.isDirectory;
96878     });
96879
96880     _self.__defineGetter__("isDirectory", function () {
96881         return _entry.isDirectory;
96882     });
96883
96884     _self.__defineGetter__("created", function () {
96885         return _entry.createdDate;
96886     });
96887
96888     _self.__defineGetter__("modified", function () {
96889         return _entry.lastModifiedDate;
96890     });
96891
96892     _self.__defineGetter__("path", function () {
96893         var _parts = _self.fullPath.split("/");
96894
96895         if (_parts.length === 1) {
96896             // virtual root
96897             return _parts.join("");
96898         } else {
96899             return _parts.splice(0, _parts.length - 1).join("/") + "/";
96900         }
96901     });
96902
96903     _self.__defineGetter__("name", function () {
96904         return _entry.name;
96905     });
96906
96907     _self.__defineGetter__("fullPath", function () {
96908         return _r2v(_entry.fullPath);
96909     });
96910
96911     _self.__defineGetter__("fileSize", function () {
96912         if (_entry.isDirectory) {
96913             return undefined;
96914         } else {
96915             return _entry.data.length;
96916         }
96917     });
96918
96919     _self.__defineGetter__("length", function () {
96920         var _l = 0;
96921         if (_entry.isDirectory) {
96922             utils.forEach(_entry.children, function () {
96923                 _l++;
96924             });
96925             return _l;
96926         } else {
96927             return undefined;
96928         }
96929     });
96930
96931     return _self;
96932 };
96933
96934 FileStream = function (entry, mode, encoding) {
96935     var _entry = entry,
96936         _data = entry.data,
96937         _mode = mode,
96938         _position = (_mode === "a" ? _data.length : 0),
96939         _self;
96940
96941     _self = {
96942         close: function () {
96943             var _element;
96944             if (mode === "a" || mode === "w") {
96945                 dbfs.write(_entry.fullPath, _data, function () {}, function () {});
96946             }
96947             for (_element in _self) {
96948                 delete _self[_element];
96949             }
96950         },
96951         read: function (charCount) {
96952             var _count  = charCount | 0,
96953                 _substr = _data.substring(_position, _position + _count);
96954
96955             if (_position + _count > _data.length) {
96956                 _position = _data.length;
96957             } else {
96958                 _position += _count;
96959             }
96960
96961             return _substr;
96962         },
96963         readBytes: function (byteCount) {
96964             var _substr = _self.read(byteCount),
96965                 _bytes = [],
96966                 _i;
96967
96968             for (_i = 0; _i < _substr.length; _i++) {
96969                 _bytes.push(_substr.charCodeAt(_i));
96970             }
96971
96972             return _bytes;
96973         },
96974         readBase64: function (byteCount) {
96975             var _substr = _self.read(byteCount);
96976
96977             return window.atob(_substr);
96978         },
96979         write: function (stringData) {
96980             var _stringData = String(stringData),
96981                 _substr = _data.substring(0, _position);
96982
96983             _data = _substr.concat(_stringData);
96984             _position = _data.length;
96985         },
96986         writeBytes: function (byteData) {
96987             _self.write(String.fromCharCode.apply(String, byteData));
96988         },
96989         writeBase64: function (base64Data) {
96990             _self.write(window.btoa(String(base64Data)));
96991         }
96992     };
96993
96994     _self.__defineGetter__("eof", function () {
96995         return _position === _data.length;
96996     });
96997
96998     _self.__defineGetter__("position", function () {
96999         return _position;
97000     });
97001
97002     _self.__defineSetter__("position", function (value) {
97003         var _value = value | 0;
97004
97005         if (_value >= 0 && _value <= _data.length) {
97006             _position = _value;
97007         } else {
97008             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
97009         }
97010     });
97011
97012     _self.__defineGetter__("bytesAvailable", function () {
97013         return (_data.length - _position) || -1;
97014     });
97015
97016     return _self;
97017 };
97018
97019 FileFilter = function (name, startModified, endModified, startCreated, endCreated) {
97020     var _self = {
97021         name: name,
97022         startModified: utils.copy(startModified),
97023         endModified: utils.copy(endModified),
97024         endCreated: utils.copy(endCreated)
97025     };
97026
97027     return _self;
97028 };
97029
97030 FileSystemStorage = function (label, type, state) {
97031     var _self = {
97032         label: label,
97033         type: type,
97034         state: state
97035     };
97036
97037     return _self;
97038 };
97039
97040 module.exports = {
97041     maxPathLength: _maxPathLength,
97042     resolve: function (srcLocation, onSuccess, onError, accessMode) {
97043         function _resolve() {
97044             var _mode = accessMode ? String(accessMode) : _defaultMode;
97045
97046             if (_mode === "r" || _mode === "rw") {
97047                 _resolveAsync(onSuccess, onError, String(srcLocation), _mode);
97048                 return null;
97049             } else {
97050                 if (onError) {
97051                     setTimeout(function () {
97052                         onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
97053                     }, 1);
97054                 }
97055             }
97056             return undefined;
97057         }
97058
97059         return tizen1_utils.validateTypeMismatch(onSuccess, onError, "resolve", _resolve);
97060     },
97061
97062     getStorage: function (label, onSuccess, onError) {
97063         var storage = null, _label = String(label);
97064
97065         _storages.some(function (value) {
97066             if (value.label === _label) {
97067                 storage = utils.copy(value);
97068                 setTimeout(function () {
97069                     onSuccess(storage);
97070                 }, 1);
97071                 return true;
97072             }
97073         });
97074
97075         if (!storage) {
97076             if(onError) {
97077                 setTimeout(function () {
97078                     onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
97079                 }, 1);
97080
97081             } else {
97082                 throw new WebAPIException(errorcode.NOT_FOUND_ERR);
97083             }
97084         }
97085     },
97086
97087     listStorages: function (onSuccess, onError) {
97088         function _listStorages() {
97089             setTimeout(function () {
97090                 onSuccess(utils.copy(_storages));
97091             }, 1);
97092         }
97093
97094         return tizen1_utils.validateTypeMismatch(onSuccess, onError, "listStorages", _listStorages);
97095     },
97096
97097     addStorageStateChangeListener: function(onSuccess, onError) {
97098         function _addStorageStateChangeListener() {
97099             var watchId = (new Date()).getTime() || 0;
97100                 _observers[watchId] = function(storage) {//storage is which state is changed
97101                 onSuccess(storage);
97102             };
97103
97104             // This event should be triggered from outside
97105             event.on("StateChange", _observers[watchId]);
97106             return Number(watchId);
97107         }
97108
97109         return tizen1_utils.validateTypeMismatch(onSuccess, onError, "addStorageStateChangeListener", _addStorageStateChangeListener);
97110     },
97111
97112     removeStorageStateChangeListener: function (watchId) {
97113         if (!_observers[watchId])
97114             return;
97115
97116         event.deleteEventHandler("StateChange", _observers[watchId]);
97117         delete _observers[watchId];
97118     },
97119
97120     handleSubFeatures: function (subFeatures) {
97121         function setSecurity(_security) {
97122             return function (method) {
97123                 _security[method] = true;
97124             };
97125         }
97126
97127         for (var subFeature in subFeatures) {
97128             if (_security[subFeature].length === 0) {
97129                 _security.all = true;
97130                 return;
97131             }
97132             _security.all = false;
97133             utils.forEach(_security[subFeature], setSecurity);
97134         }
97135     }
97136 };
97137
97138
97139 });
97140 define('ripple/platform/tizen/2.0/geoBackend_local', function (require, exports, module) {
97141 /*
97142  *  Copyright 2012 Intel Corporation.
97143  *
97144  * Licensed under the Apache License, Version 2.0 (the "License");
97145  * you may not use this file except in compliance with the License.
97146  * You may obtain a copy of the License at
97147  *
97148  * http://www.apache.org/licenses/LICENSE-2.0
97149  *
97150  * Unless required by applicable law or agreed to in writing, software
97151  * distributed under the License is distributed on an "AS IS" BASIS,
97152  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
97153  * See the License for the specific language governing permissions and
97154  * limitations under the License.
97155  */
97156
97157 var db = require('ripple/db'),
97158     utils = require('ripple/utils'),
97159     lbs = require('ripple/platform/tizen/2.0/lbs_utils'),
97160     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
97161     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
97162     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
97163     PendingObject = require('ripple/platform/tizen/2.0/pendingObject'),
97164     PendingOperation = require('ripple/platform/tizen/2.0/pendingoperation'),
97165     GeocodeResult = require('ripple/platform/tizen/2.0/GeocodeResult'),
97166     _GEO_OBJECTS = "tizen1.0-geocode-objects",
97167     _get, _save, _geoList_init, GeoEntry,
97168     _checkAddressType, _transAddressStr,
97169     _geocodeByString, _findCoordsByString, _geocodeByAddress,
97170     _reverseGeocodeBySimple, _reverseGeocodeByGeo, _checkCoordsType,
97171     _geoList = [],
97172     _PENDING_TIME = 10;
97173
97174 function _get() {
97175     var geoList = [],
97176         data = db.retrieveObject(_GEO_OBJECTS);
97177
97178     utils.forEach(data, function (geo) {
97179         geoList.push(geo);
97180     });
97181     return geoList;
97182 }
97183
97184 function _save() {
97185     db.saveObject(_GEO_OBJECTS, _geoList);
97186 }
97187
97188 function _geoList_init() {
97189     var entry;
97190     _geoList = _get();
97191
97192     /* Put some default data if database is empty */
97193     if (_geoList.length === 0) {
97194         entry = new GeoEntry(new lbs.StructuredAddress({
97195             country : "UK",
97196             region : "London",
97197             county : "Lambeth",
97198             city : "London",
97199             street : "Westminster Bridge Road",
97200             streetNumber : "1",
97201             premises : "Riverside Building",
97202             additionalInformation : "London Eye",
97203             postalCode : "SE1 7PB"
97204         }),
97205             new lbs.GeoCoordinates({
97206             latitude : 51.510452,
97207             longitude : -0.119820,
97208             altitude : 0,
97209             accuracy : 0,
97210             altitudeAccuracy : 0,
97211             heading : 0,
97212             speed : 0
97213         }));
97214         _geoList.push(entry);
97215         entry = new GeoEntry(new lbs.StructuredAddress({
97216             country : "UK",
97217             city : "London",
97218             street : "Baker Street",
97219             streetNumber : "221B",
97220             postalCode : "NW1 6XE"
97221         }),
97222             new lbs.GeoCoordinates({
97223             latitude : 51.524552,
97224             longitude : -0.158615,
97225             altitude : 0,
97226             accuracy : 0,
97227             altitudeAccuracy : 0,
97228             heading : 0,
97229             speed : 0
97230         }));
97231         _geoList.push(entry);
97232         entry = new GeoEntry(new lbs.StructuredAddress({
97233             country : "US",
97234             region : "OR",
97235             city : "Portland",
97236             street : "SE Water Ave",
97237             streetNumber : "1945",
97238             additionalInformation : "OMSI",
97239         }),
97240             new lbs.GeoCoordinates({
97241             latitude : 45.508490,
97242             longitude : -122.665953,
97243             altitude : 0,
97244             accuracy : 0,
97245             altitudeAccuracy : 0,
97246             heading : 0,
97247             speed : 0
97248         }));
97249         _geoList.push(entry);
97250         entry = new GeoEntry(new lbs.StructuredAddress({
97251             country : "US",
97252             region : "OR",
97253             city : "Portland",
97254             street : "NW Pittock Drive",
97255             streetNumber : "3229",
97256             additionalInformation : "Pittock Mansion",
97257         }),
97258             new lbs.GeoCoordinates({
97259             latitude : 45.531365,
97260             longitude : -122.716255,
97261             altitude : 0,
97262             accuracy : 0,
97263             altitudeAccuracy : 0,
97264             heading : 0,
97265             speed : 0
97266         }));
97267         _geoList.push(entry);
97268         entry = new GeoEntry(new lbs.StructuredAddress({
97269             region : "OR",
97270             city : "Hillsboro",
97271             street : "NE 25th St",
97272             streetNumber : "2111",
97273             postalCode : "97124"
97274         }),
97275             new lbs.GeoCoordinates({
97276             latitude : 45.543479,
97277             longitude : -122.9621601,
97278             altitude : 0,
97279             accuracy : 0,
97280             altitudeAccuracy : 0,
97281             heading : 0,
97282             speed : 0
97283         }));
97284         _geoList.push(entry);
97285         _save();
97286     }
97287 }
97288
97289 function _pendingOperate(operate) {
97290     var pendingObj, pendingOperation, i, argumentVector = [];
97291
97292     for (i = 0; i < arguments.length - 1; i++)
97293         argumentVector[i] = arguments[i + 1];
97294
97295     pendingObj = new PendingObject();
97296
97297     pendingObj.pendingID = window.setTimeout(function () {
97298         pendingObj.setCancelFlag(false);
97299         operate.apply(this, argumentVector);
97300     }, _PENDING_TIME);
97301
97302     pendingOperation = new PendingOperation(pendingObj);
97303
97304     return pendingOperation;
97305 }
97306
97307 function GeoEntry(addr, coord) {
97308     var _self;
97309     _self = {
97310         address : addr || null,
97311         coordinate : coord || null
97312     };
97313     return _self;
97314 }
97315
97316 function SortMode() {
97317     var _self;
97318     _self = {
97319         attributeName : "",
97320         order : "ASC"
97321     };
97322     return _self;
97323 }
97324
97325 function _transAddressStr(addr) {
97326     var str = "";
97327     if (addr.additionalInformation !== null && addr.additionalInformation !== undefined)
97328         str = str + addr.additionalInformation + ", ";
97329     if (addr.premises !== null && addr.premises !== undefined)
97330         str = str + addr.premises + ", ";
97331     if (addr.streetNumber !== null && addr.streetNumber !== undefined)
97332         str = str + addr.streetNumber + " ";
97333     if (addr.street !== null && addr.street !== undefined)
97334         str = str + addr.street + ", ";
97335     if (addr.city !== null && addr.city !== undefined)
97336         str = str + addr.city + ", ";
97337     if (addr.county !== null && addr.county !== undefined)
97338         str = str + addr.county + ", ";
97339     if (addr.region !== null && addr.region !== undefined)
97340         str = str + addr.region + ", ";
97341     if (addr.country !== null && addr.country !== undefined)
97342         str = str + addr.country + ", ";
97343     if (addr.postalCode !== null && addr.postalCode !== undefined)
97344         str = str + addr.postalCode;
97345
97346     if (str.lastIndexOf(", ") === str.length - 2)
97347         str = str.slice(0, -2);
97348     return str;
97349 }
97350
97351 function _concatAddress(addr) {
97352     var str = "";
97353     if (addr.additionalInformation !== null && addr.additionalInformation !== undefined)
97354         str = str + addr.additionalInformation + " ";
97355     if (addr.premises !== null && addr.premises !== undefined)
97356         str = str + addr.premises + " ";
97357     if (addr.streetNumber !== null && addr.streetNumber !== undefined)
97358         str = str + addr.streetNumber + " ";
97359     if (addr.street !== null && addr.street !== undefined)
97360         str = str + addr.street + " ";
97361     if (addr.city !== null && addr.city !== undefined)
97362         str = str + addr.city + " ";
97363     if (addr.county !== null && addr.county !== undefined)
97364         str = str + addr.county + " ";
97365     if (addr.region !== null && addr.region !== undefined)
97366         str = str + addr.region + " ";
97367     if (addr.country !== null && addr.country !== undefined)
97368         str = str + addr.country + " ";
97369     if (addr.postalCode !== null && addr.postalCode !== undefined)
97370         str = str + addr.postalCode;
97371
97372     return str;
97373 }
97374
97375 function _findCoordsByString(address) {
97376     var array = [], reg, str, searchAddr, pieces, i;
97377     if (address.length === 0)
97378         return array;
97379
97380     pieces = address.split(",");
97381     searchAddr = "";
97382     for (i = 0; i < pieces.length; i++) {
97383         searchAddr = searchAddr + pieces[i];
97384     }
97385     reg = new RegExp(searchAddr, "i");
97386
97387     utils.forEach(_geoList, function (item) {
97388         str = _concatAddress(item.address);
97389         if (str.search(reg) !== -1)
97390             array.push(new GeocodeResult(item.coordinate.latitude, item.coordinate.longitude));
97391     });
97392
97393     return array;
97394 }
97395
97396 function _geocodeByString(address, successCB, errorCB, options) {
97397     var array;
97398     array = _findCoordsByString(address);
97399     successCB(array);
97400 }
97401
97402 function _findCoordsByAddress(addr) {
97403     var array = [], select = false, i;
97404     for (i = 0; i < _geoList.length; i++) {
97405         select = false;
97406         if (addr.country !== null && addr.country !== undefined) {
97407             if (addr.country === _geoList[i].address.country)
97408                 select = true;
97409             else
97410                 continue;
97411         }
97412
97413         if (addr.region !== null && addr.region !== undefined) {
97414             if (addr.region === _geoList[i].address.region)
97415                 select = true;
97416             else
97417                 continue;
97418         }
97419
97420         if (addr.county !== null && addr.county !== undefined) {
97421             if (addr.county === _geoList[i].address.county)
97422                 select = true;
97423             else
97424                 continue;
97425         }
97426
97427         if (addr.city !== null && addr.city !== undefined) {
97428             if (addr.city === _geoList[i].address.city)
97429                 select = true;
97430             else
97431                 continue;
97432         }
97433
97434         if (addr.street !== null && addr.street !== undefined) {
97435             if (addr.street === _geoList[i].address.street)
97436                 select = true;
97437             else
97438                 continue;
97439         }
97440
97441         if (addr.streetNumber !== null && addr.streetNumber !== undefined) {
97442             if (addr.streetNumber === _geoList[i].address.streetNumber)
97443                 select = true;
97444             else
97445                 continue;
97446         }
97447
97448         if (addr.premises !== null && addr.premises !== undefined) {
97449             if (addr.premises === _geoList[i].address.premises)
97450                 select = true;
97451             else
97452                 continue;
97453         }
97454
97455         if (addr.additionalInformation !== null &&
97456             addr.additionalInformation !== undefined) {
97457             if (addr.additionalInformation === _geoList[i].address.additionalInformation)
97458                 select = true;
97459             else
97460                 continue;
97461         }
97462
97463         if (addr.postalCode !== null && addr.postalCode !== undefined) {
97464             if (addr.postalCode === _geoList[i].address.postalCode)
97465                 select = true;
97466             else
97467                 continue;
97468         }
97469
97470         if (select === true) {
97471             array.push(new GeocodeResult(_geoList[i].coordinate.latitude, _geoList[i].coordinate.longitude));
97472         }
97473     }
97474
97475     return array;
97476 }
97477
97478 function _geocodeByAddress(address, successCB, errorCB, options) {
97479     var array;
97480     array = _findCoordsByAddress(address);
97481     successCB(array);
97482 }
97483
97484 function _checkAddressType(address) {
97485     var str;
97486     if (typeof address === "string") {
97487         str = "string";
97488     } else if (typeof address === "object") {
97489         str = "StructuredAddress";
97490     } else {
97491         str = "typeMismatch";
97492     }
97493     return str;
97494 }
97495
97496 function _checkCoordsType(coord) {
97497     var str;
97498     /* SimpleCoordinates is a subset of GeoCoordinates.
97499        SimpleCoordinates includes latitude, longitude as mandatory fields only.
97500        GeoCoordinates not only includes latitude, longitude as mandatory fields
97501        but also at least includes one more other optional fields */
97502     if (typeof coord !== "object") {
97503         str = "typeMismatch";
97504     } else if (typeof coord.latitude === "number" &&
97505                 typeof coord.longitude === "number") {
97506         str = "simpleCoordinates";
97507         if (typeof coord.altitude === "number" ||
97508             typeof coord.accuracy === "number" ||
97509             typeof coord.altitudeAccuracy === "number" ||
97510             typeof coord.heading === "number" ||
97511             typeof coord.speed === "number") {
97512             str = "geoCoordinates";
97513         }
97514     } else {
97515         str = "typeMismatch";
97516     }
97517
97518     return str;
97519 }
97520
97521 function _findReverseGeocode(coords, options) {
97522     var array = [], _isStructured = false, i;
97523     if (options !== null && options !== undefined) {
97524         if (options.resultType === "STRUCTURED") {
97525             _isStructured = true;
97526         }
97527     }
97528     for (i = 0; i < _geoList.length; i++) {
97529         if (_geoList[i].coordinate.latitude === coords.latitude &&
97530             _geoList[i].coordinate.longitude === coords.longitude) {
97531             if (coords.altitude) {
97532                 if (_geoList[i].coordinate.altitude !== coords.altitude)
97533                     continue;
97534             }
97535             if (coords.accuracy) {
97536                 if (_geoList[i].coordinate.accuracy !== coords.accuracy)
97537                     continue;
97538             }
97539             if (coords.altitudeAccuracy) {
97540                 if (_geoList[i].coordinate.altitudeAccuracy !== coords.altitudeAccuracy)
97541                     continue;
97542             }
97543             if (coords.heading) {
97544                 if (_geoList[i].coordinate.heading !== coords.heading)
97545                     continue;
97546             }
97547             if (coords.speed) {
97548                 if (_geoList[i].coordinate.speed !== coords.speed)
97549                     continue;
97550             }
97551
97552             if (_isStructured === true) {
97553                 array.push(new lbs.StructuredAddress(_geoList[i].address));
97554             } else {
97555                 array.push(_transAddressStr(_geoList[i].address));
97556             }
97557         }
97558     }
97559     return array;
97560 }
97561
97562 function _reverseGeocodeByGeo(coordinates, successCB, errorCB, options) {
97563     var array, coord;
97564     coord = new lbs.GeoCoordinates(coordinates);
97565     array = _findReverseGeocode(coord, options);
97566     return successCB(array);
97567 }
97568
97569 function _reverseGeocodeBySimple(coordinates, successCB, errorCB, options) {
97570     var array, coord;
97571     coord = new lbs.GeoCoordinates({
97572             latitude : coordinates.latitude,
97573             longitude : coordinates.longitude
97574         });
97575     array = _findReverseGeocode(coord, options);
97576     return successCB(array);
97577 }
97578
97579 module.exports = function (prop) {
97580     var _self = new lbs.LocationServiceProvider(prop);
97581     _geoList_init();
97582
97583     _self.geocode = function (address, successCB, errorCB, options) {
97584         function _geocode() {
97585             var ret;
97586
97587             ret = _pendingOperate(function () {
97588                 /* address: its type is AbstractAddress.
97589                    It could be StructuredAddress or String */
97590                 if (_checkAddressType(address) === "string") {
97591                     _geocodeByString(address, successCB, errorCB, options);
97592                 } else if (_checkAddressType(address) === "StructuredAddress") {
97593                     _geocodeByAddress(address, successCB, errorCB, options);
97594                 } else {
97595                     throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
97596                 }
97597             });
97598         }
97599
97600         tizen1_utils.validateTypeMismatch(successCB, errorCB, "geocode", _geocode);
97601     };
97602
97603     _self.reverseGeocode = function (coordinates, successCB, errorCB, options) {
97604         function _reverseGeocode() {
97605             var ret;
97606
97607             ret = _pendingOperate(function () {
97608                 /* coordinates: Its type is AbstractCoordinates.
97609                    It could be SimpleCoordinates or GeoCoordinates */
97610                 if (_checkCoordsType(coordinates) === "simpleCoordinates") {
97611                     _reverseGeocodeBySimple(coordinates, successCB, errorCB, options);
97612                 } else if (_checkCoordsType(coordinates) === "geoCoordinates") {
97613                     _reverseGeocodeByGeo(coordinates, successCB, errorCB, options);
97614                 } else {
97615                     throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
97616                 }
97617             });
97618         }
97619
97620         tizen1_utils.validateTypeMismatch(successCB, errorCB, "reverseGeocode", _reverseGeocode);
97621     };
97622
97623     return _self;
97624 };
97625
97626
97627 });
97628 define('ripple/platform/tizen/2.0/geoBackend_nominatim', function (require, exports, module) {
97629 /*
97630  *  Copyright 2012 Intel Corporation.
97631  *
97632  * Licensed under the Apache License, Version 2.0 (the "License");
97633  * you may not use this file except in compliance with the License.
97634  * You may obtain a copy of the License at
97635  *
97636  * http://www.apache.org/licenses/LICENSE-2.0
97637  *
97638  * Unless required by applicable law or agreed to in writing, software
97639  * distributed under the License is distributed on an "AS IS" BASIS,
97640  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
97641  * See the License for the specific language governing permissions and
97642  * limitations under the License.
97643  */
97644
97645 var lbs = require('ripple/platform/tizen/2.0/lbs_utils'),
97646     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
97647     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
97648     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
97649     GeocodeResult = require('ripple/platform/tizen/2.0/GeocodeResult');
97650
97651 function _concatAddrString(addr) {
97652     var ret = "", i, pieces;
97653     if (typeof addr === "string") {
97654         pieces = addr.split(" ");
97655         for (i = 0; i < pieces.length; i++) {
97656             ret = ret + pieces[i] + "+";
97657         }
97658     } else if (typeof addr === "object") {
97659         if (addr.premises !== null && addr.premises !== undefined) {
97660             ret = ret + addr.premises + "+";
97661         }
97662         if (addr.streetNumber !== null && addr.streetNumber !== undefined) {
97663             ret = ret + addr.streetNumber + "+";
97664         }
97665         if (addr.street !== null && addr.street !== undefined) {
97666             ret = ret + addr.street + "+";
97667         }
97668         if (addr.city !== null && addr.city !== undefined) {
97669             ret = ret + addr.city + "+";
97670         }
97671         if (addr.county !== null && addr.county !== undefined) {
97672             ret = ret + addr.county + "+";
97673         }
97674         if (addr.region !== null && addr.region !== undefined) {
97675             ret = ret + addr.region + "+";
97676         }
97677         if (addr.postalCode !== null && addr.postalCode !== undefined) {
97678             ret = ret + addr.postalCode + "+";
97679         }
97680         if (addr.country !== null && addr.country !== undefined) {
97681             ret = ret + addr.country + "+";
97682         }
97683     } else {
97684         return undefined;
97685     }
97686     ret = ret.slice(0, -1);
97687     return ret;
97688 }
97689
97690 module.exports = function (prop) {
97691     var _self = new lbs.LocationServiceProvider(prop);
97692
97693     _self.geocode = function (address, successCB, errorCB, options) {
97694         function _geocode() {
97695             var i, searchStr, coordinates = [], result;
97696
97697             searchStr = _concatAddrString(address);
97698             if (searchStr === undefined) {
97699                 throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
97700             }
97701             searchStr = "http://nominatim.openstreetmap.org/search?q=" + searchStr + "&format=json&polygon=1&addressdetails=1";
97702
97703             /* use nominatim online geo service. (http://nominatim.openstreetmap.org) */
97704             $.getJSON(searchStr, function (data) {
97705                 for (i = 0; i < data.length; i++) {
97706                     result = new GeocodeResult(parseFloat(data[i].lat), parseFloat(data[i].lon));
97707                     coordinates.push(result);
97708                 }
97709                 successCB(coordinates);
97710             }).error(function () {
97711                 if (errorCB) {
97712                     setTimeout(function () {
97713                         errorCB(new WebAPIError(errorcode.NETWORK_ERR));
97714                     }, 1);
97715                 }
97716             });
97717         }
97718
97719         tizen1_utils.validateTypeMismatch(successCB, errorCB, "geocode", _geocode);
97720     };
97721
97722     _self.reverseGeocode = function (coordinates, successCB, errorCB, options) {
97723         function _reverseGeocode() {
97724             var searchStr = "";
97725             if (typeof coordinates !== "object" ||
97726                 typeof coordinates.latitude !== "number" ||
97727                 typeof coordinates.longitude !== "number") {
97728                 throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
97729             }
97730             searchStr = "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
97731                         coordinates.latitude + "&lon=" + coordinates.longitude + "&zoom=18&addressdetails=1";
97732
97733             /* use nominatim online geo service. (http://nominatim.openstreetmap.org) */
97734             $.getJSON(searchStr, function (data) {
97735                 var addr;
97736
97737                 if (options && options.resultType === "STRUCTURED") {
97738                     addr = new lbs.StructuredAddress({
97739                         country : data.address.country,
97740                         region : data.address.state,
97741                         county : data.address.county,
97742                         city : data.address.city,
97743                         street : data.address.road,
97744                         streetNumber : data.address.streetNumber,
97745                         postalCode : data.address.postcode
97746                     });
97747                 } else {
97748                     addr = data.display_name;
97749                 }
97750                 successCB([addr]);
97751             }).error(function () {
97752                 if (errorCB) {
97753                     setTimeout(function () {
97754                         errorCB(new WebAPIError(errorcode.NETWORK_ERR));
97755                     }, 1);
97756                 }
97757             });
97758         }
97759
97760         tizen1_utils.validateTypeMismatch(successCB, errorCB, "reverseGeocode", _reverseGeocode);
97761     };
97762
97763     return _self;
97764 };
97765
97766
97767 });
97768 define('ripple/platform/tizen/2.0/geocoder', function (require, exports, module) {
97769 /*
97770  *  Copyright 2012 Intel Corporation.
97771  *
97772  * Licensed under the Apache License, Version 2.0 (the "License");
97773  * you may not use this file except in compliance with the License.
97774  * You may obtain a copy of the License at
97775  *
97776  * http://www.apache.org/licenses/LICENSE-2.0
97777  *
97778  * Unless required by applicable law or agreed to in writing, software
97779  * distributed under the License is distributed on an "AS IS" BASIS,
97780  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
97781  * See the License for the specific language governing permissions and
97782  * limitations under the License.
97783  */
97784
97785 var SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
97786     ProviderLocal = require('ripple/platform/tizen/2.0/geoBackend_local'),
97787     ProviderNominatim = require('ripple/platform/tizen/2.0/geoBackend_nominatim'), // Nominatim geocode service
97788     _getProviders,
97789     _providers,
97790     _self;
97791
97792 function _initialize() {
97793     _providers = [new ProviderNominatim({name : "Nominatim", connectivity : "ONLINE"})
97794                   /* ,new ProviderLocal({name : "Tizen Database", connectivity : "OFFLINE"}) */];
97795 }
97796
97797 _initialize();
97798
97799 _self = {
97800     getDefaultProvider : function () {
97801         return _providers[0];
97802     },
97803     getProviders : function () {
97804         return _providers;
97805     }
97806 };
97807
97808 module.exports = _self;
97809
97810 });
97811 define('ripple/platform/tizen/2.0/lbs_utils', function (require, exports, module) {
97812 /*
97813  *  Copyright 2012 Intel Corporation.
97814  *
97815  * Licensed under the Apache License, Version 2.0 (the "License");
97816  * you may not use this file except in compliance with the License.
97817  * You may obtain a copy of the License at
97818  *
97819  * http://www.apache.org/licenses/LICENSE-2.0
97820  *
97821  * Unless required by applicable law or agreed to in writing, software
97822  * distributed under the License is distributed on an "AS IS" BASIS,
97823  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
97824  * See the License for the specific language governing permissions and
97825  * limitations under the License.
97826  */
97827
97828 var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
97829     _self;
97830
97831 function CoordinateProperties(prop) {
97832     var _self;
97833     _self = {
97834         latitude : prop.latitude || 0,
97835         longitude : prop.longitude || 0,
97836         altitude : prop.altitude || 0,
97837         accuracy : prop.accuracy || 0,
97838         altitudeAccuracy : prop.altitudeAccuracy || 0,
97839         heading : prop.heading || 0,
97840         speed : prop.speed || 0
97841     };
97842     return _self;
97843 }
97844
97845 function _checkAddressProperties(p, dst) {
97846     if (p.country !== null && p.country !== undefined)
97847         dst.country = String(p.country);
97848     if (p.region !== null && p.region !== undefined)
97849         dst.region = String(p.region);
97850     if (p.county !== null && p.county !== undefined)
97851         dst.county = String(p.county);
97852     if (p.city !== null && p.city !== undefined)
97853         dst.city = String(p.city);
97854     if (p.street !== null && p.street !== undefined)
97855         dst.street = String(p.street);
97856     if (p.streetNumber !== null && p.streetNumber !== undefined)
97857         dst.streetNumber = String(p.streetNumber);
97858     if (p.premises !== null && p.premises !== undefined)
97859         dst.premises = String(p.premises);
97860     if (p.additionalInformation !== null &&
97861         p.additionalInformation !== undefined)
97862         dst.additionalInformation = String(p.additionalInformation);
97863     if (p.postalCode !== null && p.postalCode !== undefined)
97864         dst.postalCode = String(p.postalCode);
97865 }
97866
97867 function AddressProperties(prop) {
97868     var _self;
97869     _self = {
97870         country : null,
97871         region : null,
97872         county : null,
97873         city : null,
97874         street : null,
97875         streetNumber : null,
97876         premises : null,
97877         additionalInformation : null,
97878         postalCode : null
97879     };
97880     if (prop) {
97881         if (_checkAddressProperties(prop, _self) === false)
97882             return undefined;
97883     }
97884     return _self;
97885 }
97886
97887 _self = {
97888     LocationServiceProvider : function (prop) {
97889         var _self;
97890         _self = {
97891             name : "",
97892             metaData : Object,
97893             attribution : "",
97894             supportedOptions : [],
97895             setOptions : function (options, successCB, errorCB) {},
97896             connectivity : "" // "ONLINE" "OFFLINE" "HYBRID"
97897         };
97898
97899         if (prop.name !== null && prop.name !== undefined)
97900             _self.name = String(prop.name);
97901         if (prop.metaData !== null && prop.metaData !== undefined)
97902             _self.metaData = prop.metaData;
97903
97904         if (prop.attribution !== null && prop.attribution !== undefined)
97905             _self.attribution = String(prop.attribution);
97906
97907         if (prop.supportedOptions !== null && prop.supportedOptions !== undefined)
97908             _self.supportedOptions = [prop.supportedOptions];
97909
97910         if (prop.setOptions !== null && prop.setOptions !== undefined)
97911             _self.setOptions = prop.setOptions;
97912
97913         if (prop.connectivity !== null && prop.connectivity !== undefined)
97914             _self.connectivity = String(prop.connectivity);
97915
97916         return _self;
97917     },
97918
97919     GeoCoordinates : function (prop) {
97920         var _self = new CoordinateProperties(prop);
97921         if (tizen1_utils.isEmptyObject(_self)) {
97922             return undefined;
97923         }
97924
97925         return _self;
97926     },
97927
97928     StructuredAddress : function (prop) {
97929         var _self;
97930         _self = new AddressProperties(prop);
97931         if (tizen1_utils.isEmptyObject(_self)) {
97932             return undefined;
97933         }
97934
97935         return _self;
97936     }
97937 };
97938
97939 module.exports = _self;
97940
97941 });
97942 define('ripple/platform/tizen/2.0/map', function (require, exports, module) {
97943 /*
97944  *  Copyright 2012 Intel Corporation
97945  *
97946  * Licensed under the Apache License, Version 2.0 (the "License");
97947  * you may not use this file except in compliance with the License.
97948  * You may obtain a copy of the License at
97949  *
97950  * http://www.apache.org/licenses/LICENSE-2.0
97951  *
97952  * Unless required by applicable law or agreed to in writing, software
97953  * distributed under the License is distributed on an "AS IS" BASIS,
97954  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
97955  * See the License for the specific language governing permissions and
97956  * limitations under the License.
97957  */
97958
97959 var lbs = require('ripple/platform/tizen/2.0/lbs_utils'),
97960     mapProviders = [],
97961     MapStyle,
97962     MapProvider,
97963     _self;
97964
97965 function _initialize() {
97966     // EPSG:3857 is a Spherical Mercator projection coordinate system popularized by web services such as Google and later OpenStreetMap
97967     // mapStyles are from http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
97968     var projection = "EPSG:3857",
97969         mapStyle1 = new MapStyle("Mapnik", "http://b.tile.openstreetmap.org/${z}/${x}/${y}.png"),
97970         mapStyle2 = new MapStyle("Cycle", "http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png");
97971
97972     mapProviders = [new MapProvider({name: "OpenStreetMap", connectivity: "ONLINE"}, projection, [mapStyle1, mapStyle2])];
97973 }
97974
97975 _self = {
97976     getDefaultProvider: function () {
97977         return mapProviders[0];
97978     },
97979     getProviders: function () {
97980         return mapProviders;
97981     }
97982 };
97983
97984 MapStyle = function (name, url) {
97985     return {
97986         name: name,
97987         url: url
97988     };
97989 };
97990
97991 MapProvider = function (prop, projection, mapStyles) {
97992     var mapProvider = new lbs.LocationServiceProvider(prop);
97993
97994     mapProvider.__defineGetter__("projection", function () {
97995         return projection;
97996     });
97997
97998     mapProvider.__defineGetter__("mapStyles", function () {
97999         return mapStyles;
98000     });
98001
98002     return mapProvider;
98003 };
98004
98005 _initialize();
98006
98007 module.exports = _self;
98008
98009 });
98010 define('ripple/platform/tizen/2.0/messaging', function (require, exports, module) {
98011 /*
98012  *  Copyright 2012 Intel Corporation.
98013  *
98014  * Licensed under the Apache License, Version 2.0 (the "License");
98015  * you may not use this file except in compliance with the License.
98016  * You may obtain a copy of the License at
98017  *
98018  * http://www.apache.org/licenses/LICENSE-2.0
98019  *
98020  * Unless required by applicable law or agreed to in writing, software
98021  * distributed under the License is distributed on an "AS IS" BASIS,
98022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
98023  * See the License for the specific language governing permissions and
98024  * limitations under the License.
98025  */
98026
98027 var _self,
98028     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
98029     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
98030     MessagingService = require('ripple/platform/tizen/2.0/MessagingService'),
98031     t = require('ripple/platform/tizen/2.0/typedef'),
98032     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
98033     TIZEN_MESSAGING_SMS = "messaging.sms",
98034     TIZEN_MESSAGING_MMS = "messaging.mms",
98035     TIZEN_MESSAGING_EMAIL = "messaging.email",
98036     _security_check = {read: false, write: false},
98037     _sms_service = null,
98038     _mms_service = null,
98039     _email_service = null;
98040
98041 _self = function () {
98042     this.getMessageServices = function (messageServiceType, onSuccess, onError) {
98043         var service;
98044
98045         if (!(new TypeCoerce(t.MessageServiceTag)).match(messageServiceType)) {
98046             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
98047         }
98048         if (!(new TypeCoerce(t.MessageServiceArraySuccessCallback)).match(onSuccess)) {
98049             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
98050         }
98051         if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
98052             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
98053         }
98054
98055         switch (messageServiceType) {
98056         case "messaging.sms":
98057             if (_sms_service === null) {
98058                 _sms_service = [new MessagingService("Tizen SMS Service 1", TIZEN_MESSAGING_SMS, _security_check), new MessagingService("Tizen SMS Service 2", TIZEN_MESSAGING_SMS, _security_check)];
98059             }
98060             service = _sms_service;
98061             break;
98062         case "messaging.mms":
98063             if (_mms_service === null) {
98064                 _mms_service = [new MessagingService("Tizen MMS Service", TIZEN_MESSAGING_MMS, _security_check)];
98065             }
98066             service = _mms_service;
98067             break;
98068         case "messaging.email":
98069             if (_email_service === null) {
98070                 _email_service = [new MessagingService("Tizen Email Service", TIZEN_MESSAGING_EMAIL, _security_check)];
98071             }
98072             service = _email_service;
98073             break;
98074         default:
98075             throw (new WebAPIException(errorcode.INVALID_VALUES_ERR));
98076         }
98077         setTimeout(function () {
98078             onSuccess(service);
98079         }, 1);
98080     };
98081     this.handleSubFeatures = function (subFeatures) {
98082         if (subFeatures.hasOwnProperty('http://tizen.org/privilege/messaging.read')) {
98083             _security_check.read = true;
98084         }
98085         if (subFeatures.hasOwnProperty('http://tizen.org/privilege/messaging.write')) {
98086             _security_check.write = true;
98087         }
98088     };
98089 };
98090
98091 module.exports = _self;
98092
98093 });
98094 define('ripple/platform/tizen/2.0/msg_utils', function (require, exports, module) {
98095 /*
98096  *  Copyright 2012 Intel Corporation.
98097  *
98098  * Licensed under the Apache License, Version 2.0 (the "License");
98099  * you may not use this file except in compliance with the License.
98100  * You may obtain a copy of the License at
98101  *
98102  * http://www.apache.org/licenses/LICENSE-2.0
98103  *
98104  * Unless required by applicable law or agreed to in writing, software
98105  * distributed under the License is distributed on an "AS IS" BASIS,
98106  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
98107  * See the License for the specific language governing permissions and
98108  * limitations under the License.
98109  */
98110
98111
98112 var db = require('ripple/db'),
98113     utils = require('ripple/utils'),
98114     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
98115     MessageBody = require('ripple/platform/tizen/2.0/MessageBody'),
98116     _TIZEN_MESSAGE_DB_KEY = "tizen_db_messages",
98117     MessageElement = function (_type, _id) {
98118         return {
98119             type: _type,
98120             id: _id,
98121             msg: {},
98122             conv: {}
98123         };
98124     },
98125
98126     _conversationCount = function (msg, cid, rst) {
98127         var old_time = new Date(0), t;
98128
98129         utils.forEach(msg.msg, function (o) {
98130             if (o.priv.conversationId === cid &&
98131                 o.priv.messageStatus !== "DRAFT") {
98132                 rst.cnt += 1;
98133                 t = new Date(o.priv.timestamp);
98134                 if (t > old_time) {
98135                     rst.lastid = o.priv.id;
98136                     old_time = t;
98137                 }
98138                 if (o.isRead === false) {
98139                     rst.unread++;
98140                 }
98141             }
98142         });
98143     },
98144
98145     _updateConversation = function (msg, cid) {
98146         var privConv = {}, lastm, rst = {};
98147
98148         rst.cnt = 0;
98149         rst.unread = 0;
98150         rst.lastid = "";
98151         _conversationCount(msg, cid, rst);
98152         if (rst.cnt === 0) {
98153             if (msg.conv[cid] !== undefined) {
98154                 delete msg.conv[cid];
98155             }
98156             return;
98157         }
98158         lastm = msg.msg[rst.lastid];
98159
98160         privConv.id = cid;
98161         privConv.type = msg.type;
98162         privConv.timestamp = new Date(lastm.priv.timestamp);
98163         privConv.messageCount = rst.cnt;
98164         privConv.unreadMessages = rst.unread;
98165         privConv.preview = lastm.body.plainBody;
98166         privConv.subject = lastm.subject;
98167         privConv.isRead = lastm.isRead;
98168         privConv.from = lastm.priv.from;
98169         privConv.to = lastm.to.slice(0);
98170         privConv.cc = lastm.cc.slice(0);
98171         privConv.bcc = lastm.bcc.slice(0);
98172         privConv.lastMessageId = rst.lastid;
98173         msg.conv[cid] = privConv;
98174     };
98175
98176 module.exports = {
98177     conversationCount: _conversationCount,
98178     setMsg: function (m, newm) {
98179         if ((m.to === null) || (m.to === undefined)) {
98180             newm.to = [];
98181         } else {
98182             if (tizen1_utils.isValidArray(m.to)) {
98183                 newm.to = m.to.slice(0);
98184             } else {
98185                 return false;
98186             }
98187         }
98188
98189         if ((m.cc === null) || (m.cc === undefined)) {
98190             newm.cc = [];
98191         } else {
98192             if (tizen1_utils.isValidArray(m.cc)) {
98193                 newm.cc = m.cc.slice(0);
98194             } else {
98195                 return false;
98196             }
98197         }
98198
98199         if ((m.bcc === null) || (m.bcc === undefined)) {
98200             newm.bcc = [];
98201         } else {
98202             if (tizen1_utils.isValidArray(m.bcc)) {
98203                 newm.bcc = m.bcc.slice(0);
98204             } else {
98205                 return false;
98206             }
98207         }
98208
98209         if ((m.body === null) || (m.body === undefined)) {
98210             if (m.htmlBody === null || m.htmlBody === undefined) {
98211                 m.htmlBody = "";
98212             }
98213             if (m.plainBody === null || m.plainBody === undefined) {
98214                 m.plainBody = "";
98215             }
98216             if (typeof m.plainBody !== 'string' || typeof m.htmlBody !== 'string') {
98217                 return false;
98218             }
98219             m.body = new MessageBody(null, true, m.plainBody, m.htmlBody, []);
98220         } else {
98221             if (typeof m.body.plainBody !== 'string' || typeof m.body.htmlBody !== 'string') {
98222                 return false;
98223             }
98224             m.body = new MessageBody(null, true, m.body.plainBody, m.body.htmlBody, []);
98225         }
98226         newm.body = utils.copy(m.body);
98227
98228         if (typeof m.isRead === 'boolean') {
98229             newm.isRead = m.isRead;
98230         } else {
98231             newm.isRead = false;
98232         }
98233
98234         if (typeof m.isHighPriority === 'boolean') {
98235             newm.isHighPriority = m.isHighPriority;
98236         } else {
98237             newm.isHighPriority = false;
98238         }
98239
98240         if ((m.subject === null) || (m.subject === undefined)) {
98241             newm.subject = "";
98242         } else {
98243             newm.subject = String(m.subject);
98244         }
98245
98246         if ((m.inResponseTo === null) || (m.inResponseTo === undefined)) {
98247             newm.inResponseTo = null;
98248         } else {
98249             newm.inResponseTo = String(m.inResponseTo);
98250         }
98251
98252         if ((m.attachments === null) || (m.attachments === undefined)) {
98253             newm.attachments = [];
98254         } else {
98255             newm.attachments = utils.copy(m.attachments);
98256         }
98257         return true;
98258     },
98259
98260     loadMsg: function (type, id) {
98261         var i, ret, msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || null;
98262         if (msg === null) {
98263             ret = new MessageElement(type, id);
98264         } else {
98265             for (i = 0; i < msg.length; i++) {
98266                 if (msg[i].type === type && msg[i].id === id) {
98267                     ret = msg[i];
98268                     break;
98269                 }
98270             }
98271             if (ret === undefined) {
98272                 ret = new MessageElement(type, id);
98273             } else {
98274                 /* after getting Date out of DB, Date will become
98275                    a string, so need to recast it back to Date */
98276                 for (i in ret.msg) {
98277                     ret.msg[i].priv.timestamp = new Date(ret.msg[i].priv.timestamp);
98278                 }
98279             }
98280         }
98281         return ret;
98282     },
98283
98284     delMsg: function (m) { // m is a PrivMessage
98285         var i, _msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || [];
98286         if (_msg.length === 0) {
98287             return;
98288         } else {
98289             for (i = 0; i < _msg.length; i++) {
98290                 if (_msg[i].type === m.priv.type && _msg[i].id === m.priv.serviceId) {
98291                     delete _msg[i].msg[m.priv.id];
98292                     if (m.priv.messageStatus !== "DRAFT") {
98293                         _updateConversation(_msg[i], m.priv.conversationId);
98294                     }
98295                     db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg);
98296                     return;
98297                 }
98298             }
98299         }
98300     },
98301
98302     saveMsg: function (m) { // m is a PrivMessage
98303         var i, new_msg, _msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || [];
98304         if (_msg.length === 0) {
98305             _msg = new MessageElement(m.priv.type, m.priv.serviceId);
98306             _msg.msg[m.priv.id] = m;
98307             if (m.priv.messageStatus !== "DRAFT") {
98308                 _updateConversation(_msg, m.priv.conversationId);
98309             }
98310             db.saveObject(_TIZEN_MESSAGE_DB_KEY, [_msg]);
98311         } else {
98312             for (i = 0; i < _msg.length; i++) {
98313                 if (_msg[i].type === m.priv.type && _msg[i].id === m.priv.serviceId) {
98314                     _msg[i].msg[m.priv.id] = m;
98315                     if (m.priv.messageStatus !== "DRAFT") {
98316                         _updateConversation(_msg[i], m.priv.conversationId);
98317                     }
98318                     db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg);
98319                     break;
98320                 }
98321             }
98322             if (i === _msg.length) {
98323                 new_msg = new MessageElement(m.priv.type, m.priv.serviceId);
98324                 new_msg.msg[m.priv.id] = m;
98325                 if (m.priv.messageStatus !== "DRAFT") {
98326                     _updateConversation(new_msg, m.priv.conversationId);
98327                 }
98328                 _msg.push(new_msg);
98329                 db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg);
98330             }
98331         }
98332     },
98333
98334     loadConv: function (type, id) {
98335         var i, ret;
98336         ret = this.loadMsg(type, id).conv;
98337         for (i in ret) {
98338             ret[i].timestamp = new Date(ret[i].timestamp);
98339         }
98340         return ret;
98341     }
98342 };
98343
98344 });
98345 define('ripple/platform/tizen/2.0/navigator', function (require, exports, module) {
98346 /*
98347  *  Copyright 2011 Research In Motion Limited.
98348  *  Copyright 2012 Intel Corporation.
98349  *
98350  * Licensed under the Apache License, Version 2.0 (the "License");
98351  * you may not use this file except in compliance with the License.
98352  * You may obtain a copy of the License at
98353  *
98354  * http://www.apache.org/licenses/LICENSE-2.0
98355  *
98356  * Unless required by applicable law or agreed to in writing, software
98357  * distributed under the License is distributed on an "AS IS" BASIS,
98358  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
98359  * See the License for the specific language governing permissions and
98360  * limitations under the License.
98361  */
98362 var _original = window.navigator,
98363     utils = require('ripple/utils'),
98364     devices = require('ripple/devices'),
98365     constants = require('ripple/constants'),
98366     vibration = require('ripple/platform/tizen/2.0/vibration'),
98367     _self = {};
98368
98369 (function () {
98370     var key,
98371         nav = window.navigator;
98372
98373     function _handle(obj, key) {
98374         return typeof obj[key] !== "function" ? obj[key] : function () {
98375             return obj[key].apply(obj, Array.prototype.slice.call(arguments));
98376         };
98377     }
98378
98379     for (key in nav) {
98380         _self[key] = _handle(nav, key);
98381     }
98382 }());
98383
98384 _self.__defineGetter__('userAgent', function () {
98385     var currentUserAgent = devices.getCurrentDevice().userAgent;
98386
98387     return currentUserAgent === constants.COMMON.USER_AGENT_DEFAULT ?
98388         _original.userAgent : currentUserAgent;
98389 });
98390
98391 _self.__defineGetter__('vibrate', function () {
98392     return vibration.vibrate;
98393 });
98394
98395 module.exports = _self;
98396
98397 });
98398 define('ripple/platform/tizen/2.0/networkbearerselection', function (require, exports, module) {
98399 /*
98400  *  Copyright 2013 Intel Corporation.
98401  *
98402  * Licensed under the Apache License, Version 2.0 (the "License");
98403  * you may not use this file except in compliance with the License.
98404  * You may obtain a copy of the License at
98405  *
98406  * http://www.apache.org/licenses/LICENSE-2.0
98407  *
98408  * Unless required by applicable law or agreed to in writing, software
98409  * distributed under the License is distributed on an "AS IS" BASIS,
98410  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
98411  * See the License for the specific language governing permissions and
98412  * limitations under the License.
98413  */
98414
98415 var event = require('ripple/event'),
98416     t = require('ripple/platform/tizen/2.0/typecast'),
98417     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
98418     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
98419     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
98420     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
98421     _security = {
98422         "http://tizen.org/privilege/networkbearerselection":
98423             ["requestRouteToHost", "releaseRouteToHost"]
98424     },
98425     _self;
98426
98427 _self = function () {
98428     var networkBearerSelection;
98429
98430     function requestRouteToHost(networkType, domainName, successCallback, errorCallback) {
98431         var evNetworkOpened       = "NO_" + networkType + "_" + domainName,
98432             evNetworkDisconnected = "ND_" + networkType + "_" + domainName;
98433
98434         if (!_security.requestRouteToHost) {
98435             throw new WebAPIException(errorcode.SECURITY_ERR);
98436         }
98437
98438         t.NetworkBearerSelection("requestRouteToHost", arguments);
98439         
98440         if (!domainName) {
98441             if (errorCallback) {
98442                 errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
98443             }
98444             return;
98445         }
98446
98447         event.once(evNetworkOpened, function (isOpened) {
98448             if (!isOpened)
98449                 return;
98450
98451             successCallback.onsuccess();
98452         });
98453         event.once(evNetworkDisconnected, successCallback.ondisconnected);
98454         event.trigger("NetworkRequest", [networkType, domainName]);
98455     }
98456
98457     function releaseRouteToHost(networkType, domainName, successCallback, errorCallback) {
98458         var evNetworkDisconnected = "ND_" + networkType + "_" + domainName;
98459
98460         if (!_security.releaseRouteToHost) {
98461             throw new WebAPIException(errorcode.SECURITY_ERR);
98462         }
98463
98464         t.NetworkBearerSelection("releaseRouteToHost", arguments);
98465        
98466         if (!domainName) {
98467             if (errorCallback) {
98468                 errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
98469             }
98470             return;
98471         }
98472
98473         event.once(evNetworkDisconnected, successCallback);
98474         event.trigger("NetworkRelease", [networkType, domainName]);
98475     }
98476
98477     function handleSubFeatures(subFeatures) {
98478         var i, subFeature;
98479
98480         for (subFeature in subFeatures) {
98481             for (i in _security[subFeature]) {
98482                 _security[_security[subFeature][i]] = true;
98483             }
98484         }
98485     }
98486
98487     networkBearerSelection = {
98488         requestRouteToHost: requestRouteToHost,
98489         releaseRouteToHost: releaseRouteToHost,
98490         handleSubFeatures:  handleSubFeatures
98491     };
98492
98493     return networkBearerSelection;
98494 };
98495
98496 module.exports = _self;
98497
98498 });
98499 define('ripple/platform/tizen/2.0/nfc', function (require, exports, module) {
98500 /*
98501  *  Copyright 2013 Intel Corporation
98502  *
98503  * Licensed under the Apache License, Version 2.0 (the "License");
98504  * you may not use this file except in compliance with the License.
98505  * You may obtain a copy of the License at
98506  *
98507  * http://www.apache.org/licenses/LICENSE-2.0
98508  *
98509  * Unless required by applicable law or agreed to in writing, software
98510  * distributed under the License is distributed on an "AS IS" BASIS,
98511  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
98512  * See the License for the specific language governing permissions and
98513  * limitations under the License.
98514  */
98515
98516 var db = require('ripple/db'),
98517     event = require('ripple/event'),
98518     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
98519     t = require('ripple/platform/tizen/2.0/typecast'),
98520     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
98521     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
98522     NDEFRecord = require('ripple/platform/tizen/2.0/NDEFRecordInternal'),
98523     NDEFMessage = require('ripple/platform/tizen/2.0/NDEFMessage'),
98524     NFCAdapter,
98525     NFCAdapterPrototype,
98526     NFCTag,
98527     NFCPeer,
98528     _data = {
98529         DB_NFC_TAG: "tizen1.0-nfc-tag",
98530         DB_NFC_PEER: "tizen1.0-nfc-peer",
98531         DB_NFC_OUTPUT_MESSAGE: "tizen1.0-nfc-output-message",
98532         INTERVAL: 1000,
98533         listener: {
98534             onCardEmulationChanged: null,
98535             onTagDetected: null,
98536             onPeerDetected: null,
98537             onNDEFReceived: null
98538         },
98539         pairedNFC: null,
98540         nfcAdapter: {},
98541         nfcCardEmulation: {},
98542         nfcTags: [],
98543         nfcTag: {},
98544         nfcPeer: null,
98545         isNear: false,      // Identify the device is whether near
98546         isDetectTag: false, // Identify NFC tag is detected
98547         isPeerConnected: false,
98548         connectedState: false
98549     },
98550     _security = {
98551         "http://tizen.org/privilege/nfc.admin": ["setPowered"],
98552         "http://tizen.org/privilege/nfc.common": ["getDefaultAdapter",
98553                 "setExclusiveMode", "getCachedMessage"],
98554         "http://tizen.org/privilege/nfc.p2p": ["setPeerListener",
98555                 "unsetPeerListener", "setReceiveNDEFListener",
98556                 "unsetReceiveNDEFListener", "sendNDEF"],
98557         "http://tizen.org/privilege/nfc.tag": ["setTagListener",
98558                 "unsetTagListener", "readNDEF", "writeNDEF", "transceive"]
98559     },
98560     _self;
98561
98562 _self = function () {
98563     var nfc, _exclusiveMode = false;
98564
98565     function getDefaultAdapter() {
98566         if (!_security.getDefaultAdapter) {
98567             throw new WebAPIException(errorcode.SECURITY_ERR);
98568         }
98569
98570         t.NFCManager("getDefaultAdapter", arguments);
98571
98572         if (!_data.nfcAdapter) {
98573             throw new WebAPIException(errorcode.UNKNOWN_ERR);
98574         }
98575
98576         return _data.nfcAdapter;
98577     }
98578
98579     /* API Description:
98580      *   If it gets priority and it is in foreground, system doesn't
98581      *   send app controls that are usually sent when detecting NFC Tag
98582      *   or receiving NDEF Message from the connected NFC peer-to-peer target
98583      *
98584      * Implementation detail:
98585      *   due to simulator only support single running instance and doesn't have
98586      *   other app controls which be called by design. we just put some system
98587      *   exclusive mode info on the 'System Summary' panel
98588      */
98589     function setExclusiveMode(mode) {
98590         if (!_security.setExclusiveMode) {
98591             throw new WebAPIException(errorcode.SECURITY_ERR);
98592         }
98593
98594         t.NFCManager("setExclusiveMode", arguments);
98595
98596         _exclusiveMode = mode;
98597         jQuery("#NFCExclusiveModeValue").text(_exclusiveMode);
98598     }
98599
98600     function handleSubFeatures(subFeatures) {
98601         var i, subFeature;
98602
98603         for (subFeature in subFeatures) {
98604             for (i in _security[subFeature]) {
98605                 _security[_security[subFeature][i]] = true;
98606             }
98607         }
98608     }
98609
98610     nfc = {
98611         getDefaultAdapter: getDefaultAdapter,
98612         setExclusiveMode:  setExclusiveMode,
98613         handleSubFeatures: handleSubFeatures
98614     };
98615
98616     nfc.__defineGetter__("NFC_RECORD_TNF_EMPTY", function () {
98617         return 0;
98618     });
98619
98620     nfc.__defineGetter__("NFC_RECORD_TNF_WELL_KNOWN", function () {
98621         return 1;
98622     });
98623
98624     nfc.__defineGetter__("NFC_RECORD_TNF_MIME_MEDIA", function () {
98625         return 2;
98626     });
98627
98628     nfc.__defineGetter__("NFC_RECORD_TNF_URI", function () {
98629         return 3;
98630     });
98631
98632     nfc.__defineGetter__("NFC_RECORD_TNF_EXTERNAL_RTD", function () {
98633         return 4;
98634     });
98635
98636     nfc.__defineGetter__("NFC_RECORD_TNF_UNKNOWN", function () {
98637         return 5;
98638     });
98639
98640     nfc.__defineGetter__("NFC_RECORD_TNF_UNCHANGED", function () {
98641         return 6;
98642     });
98643
98644     return nfc;
98645 };
98646
98647 NFCAdapterPrototype = function () {
98648     var nfcAdapterPrototype,
98649         interval,
98650         powered = false, // Identify the device on or off
98651         polling = false; // Identify the device is polled
98652
98653     event.trigger("nfc-power-changed", [powered]);
98654     event.on("nfc-power-setting", function (status) {
98655         updatePowerStatus(status);
98656     });
98657     event.on("nfc-attach-setting", function (type, isAttached) {
98658         var isDetectTag;
98659
98660         isDetectTag = (type === "Tag");
98661         updateIsNear(isDetectTag, isAttached);
98662     });
98663     event.on("nfc-tag-send", function (status) {
98664         var tag;
98665
98666         if (status) {
98667             tag = db.retrieveObject(_data.DB_NFC_TAG);
98668             if (tag.isSupportedNDEF) {
98669                 _data.nfcTag = new NFCTag(tag.type, tag.isSupportedNDEF,
98670                         tag.ndefSize, null, true, tag.ndefs);
98671             } else {
98672                 _data.nfcTag = new NFCTag(tag.type, tag.isSupportedNDEF,
98673                         tag.ndefSize, null, true, tag.rawData);
98674             }
98675             if (_data.listener.onTagDetected) {
98676                 _data.listener.onTagDetected.onattach(_data.nfcTag);
98677             }
98678         } else {
98679             tag = {};
98680             if (_data.listener.onTagDetected) {
98681                 _data.listener.onTagDetected.ondetach();
98682             }
98683         }
98684     });
98685     event.on("nfc-peer-send", function (status) {
98686         if (status) {
98687             if (!_data.nfcPeer) {
98688                 _data.nfcPeer = new NFCPeer(true);
98689             }
98690             _data.isPeerConnected = true;
98691             if (_data.listener.onPeerDetected) {
98692                 _data.listener.onPeerDetected.onattach(_data.nfcPeer);
98693             }
98694         } else {
98695             _data.isPeerConnected = false;
98696             if (_data.listener.onPeerDetected) {
98697                 _data.listener.onPeerDetected.ondetach();
98698             }
98699         }
98700     });
98701     event.on("nfc-peer-sending-ndef", function () {
98702         var peer, _records = [], rec, _ndef, i;
98703
98704         if (_data.isPeerConnected) {
98705             peer = db.retrieveObject(_data.DB_NFC_PEER);
98706             for (i in peer.ndef.records) {
98707                 rec = peer.ndef.records[i];
98708                 _records.push(new NDEFRecord(rec.tnf, rec.type, rec.payload,
98709                         rec.id));
98710             }
98711             _ndef = new NDEFMessage(_records);
98712             if (_data.listener.onNDEFReceived) {
98713                 _data.listener.onNDEFReceived(_ndef);
98714             }
98715         }
98716     });
98717
98718     // private
98719     function updatePowerStatus(status) {
98720         if (powered === status) {
98721             return;
98722         }
98723         if (!status) {
98724             updateIsNear(_data.isDetectTag, false);
98725             _data.listener.onTagDetected = null;
98726             _data.listener.onPeerDetected = null;
98727             _data.listener.onNDEFReceived = null;
98728             _data.listener.onCardEmulationChanged = null;
98729         }
98730         powered = status;
98731         updatePollingStatus(status);
98732
98733         event.trigger("nfc-power-changed", [powered]);
98734     }
98735
98736     function updatePollingStatus(status) {
98737         if (!powered)
98738             return;
98739         if (polling === status) {
98740             return;
98741         }
98742         polling = status;
98743         event.trigger("nfc-polling-changed", [polling]);
98744         if (polling) {
98745             interval = setInterval(poll, _data.INTERVAL);
98746         } else {
98747             clearInterval(interval);
98748         }
98749     }
98750
98751     function updateIsNear(isDetectTag, isAttached) {
98752         _data.isDetectTag = isDetectTag;
98753         _data.isNear = isAttached;
98754         if (!_data.isNear) {
98755             _data.connectedState = false;
98756             event.trigger("nfc-connectedState-changed", [false]);
98757         }
98758     }
98759
98760     function poll() {
98761         if (!_data.isNear) {
98762             return;
98763         }
98764         if (!_data.connectedState) {
98765             _data.connectedState = true;
98766             event.trigger("nfc-connectedState-changed", [true]);
98767         }
98768     }
98769
98770     // public
98771     // Turns NFC adapter on or off.
98772     function setPowered(state, successCallback, errorCallback) {
98773         if (!_security.setPowered) {
98774             throw new WebAPIException(errorcode.SECURITY_ERR);
98775         }
98776
98777         t.NFCAdapter("setPowered", arguments);
98778
98779         window.setTimeout(function () {
98780             updatePowerStatus(state);
98781             if (successCallback) {
98782                 successCallback();
98783             }
98784         }, 1);
98785     }
98786
98787     // Registers a callback function to invoke when NFC tag is detected.
98788     function setTagListener(detectCallback, tagFilter) {
98789         if (!_security.setTagListener) {
98790             throw new WebAPIException(errorcode.SECURITY_ERR);
98791         }
98792
98793         t.NFCAdapter("setTagListener", arguments);
98794
98795         //TODO: tagFilter support
98796         if (!powered) {
98797             return;
98798         }
98799         _data.listener.onTagDetected = detectCallback;
98800     }
98801
98802     // Registers a callback function to be invoked when NFC peer-to-peer target is detected.
98803     function setPeerListener(detectCallback) {
98804         if (!_security.setPeerListener) {
98805             throw new WebAPIException(errorcode.SECURITY_ERR);
98806         }
98807
98808         t.NFCAdapter("setPeerListener", arguments);
98809
98810         if (!powered) {
98811             return;
98812         }
98813         _data.listener.onPeerDetected = detectCallback;
98814     }
98815
98816     // Unregisters the listener for detecting an NFC tag.
98817     function unsetTagListener() {
98818         if (!_security.unsetTagListener) {
98819             throw new WebAPIException(errorcode.SECURITY_ERR);
98820         }
98821
98822         if (!powered || !_data.listener.onTagDetected) {
98823             return;
98824         }
98825
98826         _data.listener.onTagDetected = null;
98827     }
98828
98829     // Unregisters the listener for detecting an NFC peer-to-peer target.
98830     function unsetPeerListener() {
98831         if (!_security.unsetPeerListener) {
98832             throw new WebAPIException(errorcode.SECURITY_ERR);
98833         }
98834
98835         if (!powered || !_data.listener.onPeerDetected) {
98836             return;
98837         }
98838
98839         _data.listener.onPeerDetected = null;
98840     }
98841
98842     // Gets NDEF message cached when the tag is detected.
98843     function getCachedMessage() {
98844         if (!_security.getCachedMessage) {
98845             throw new WebAPIException(errorcode.SECURITY_ERR);
98846         }
98847
98848         t.NFCAdapter("getCachedMessage", arguments);
98849
98850         return _data.pairedNFC || new NDEFMessage([]);
98851     }
98852
98853     nfcAdapterPrototype = {
98854         setPowered:        setPowered,
98855         setTagListener:    setTagListener,
98856         setPeerListener:   setPeerListener,
98857         unsetTagListener:  unsetTagListener,
98858         unsetPeerListener: unsetPeerListener,
98859         getCachedMessage:  getCachedMessage
98860     };
98861
98862     nfcAdapterPrototype.__defineGetter__("powered", function () {
98863         return powered;
98864     });
98865
98866     return nfcAdapterPrototype;
98867 };
98868
98869 NFCAdapter = function () {
98870     this.__defineGetter__("powered", function () {
98871         return this.__proto__.powered;
98872     });
98873 };
98874
98875 NFCAdapter.prototype = new NFCAdapterPrototype();
98876
98877 NFCTag = function (type, isSupportedNDEF, ndefSize, properties, isConnected, ndefs) {
98878     var nfcTag, i, j, _ndefs, rec, _records, _ndefs_index = 0;
98879
98880     type = type || null;
98881     isSupportedNDEF = isSupportedNDEF || false;
98882     ndefSize = ndefSize || 1;
98883     properties = null;
98884     isConnected = isConnected || false;
98885
98886     _ndefs = [];
98887     for (i in ndefs) {
98888         _records = [];
98889         for (j in ndefs[i].records) {
98890             rec = ndefs[i].records[j];
98891             _records.push(new NDEFRecord(rec.tnf, rec.type, rec.payload,
98892                     rec.id));
98893         }
98894         _ndefs.push(new NDEFMessage(_records));
98895     }
98896
98897     // Reads NDEF data.
98898     function readNDEF(readCallback, errorCallback) {
98899         if (!_security.readNDEF) {
98900             throw new WebAPIException(errorcode.SECURITY_ERR);
98901         }
98902
98903         t.NFCTag("readNDEF", arguments);
98904
98905         window.setTimeout(function () {
98906             if (!_data.isNear || !isSupportedNDEF ||
98907                     (_ndefs_index >= ndefSize)) {
98908                 if (errorCallback) {
98909                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
98910                 }
98911                 return;
98912             }
98913             _data.pairedNFC = _ndefs[_ndefs_index];
98914             readCallback(_ndefs[_ndefs_index]);
98915             _ndefs_index++;
98916         }, 1);
98917     }
98918
98919     // Writes NDEF data.
98920     function writeNDEF(ndefMessage, successCallback, errorCallback) {
98921         if (!_security.writeNDEF) {
98922             throw new WebAPIException(errorcode.SECURITY_ERR);
98923         }
98924
98925         t.NFCTag("writeNDEF", arguments, true);
98926
98927         window.setTimeout(function () {
98928             if (!_data.isNear || !isSupportedNDEF) {
98929                 if (errorCallback) {
98930                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
98931                 }
98932                 return;
98933             }
98934             db.saveObject(_data.DB_NFC_OUTPUT_MESSAGE, ndefMessage);
98935             event.trigger("nfc-output-msg", []);
98936             if (successCallback) {
98937                 successCallback();
98938             }
98939         }, 1);
98940     }
98941
98942     // Access the raw format card.
98943     function transceive(data, dataCallback, errorCallback) {
98944         if (!_security.transceive) {
98945             throw new WebAPIException(errorcode.SECURITY_ERR);
98946         }
98947
98948         t.NFCTag("transceive", arguments, true);
98949
98950         window.setTimeout(function () {
98951             if (!_data.isNear || isSupportedNDEF) {
98952                 if (errorCallback) {
98953                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
98954                 }
98955                 return;
98956             }
98957             db.saveObject(_data.DB_NFC_OUTPUT_MESSAGE, data);
98958             event.trigger("nfc-output-msg", []);
98959             dataCallback(ndefs);
98960         }, 1);
98961     }
98962
98963     // Formats the detected tag that can store NDEF messages.
98964     /*
98965     function formatNDEF(successCallback, errorCallback, key) {
98966
98967         tizen1_utils.validateCallbackType(successCallback, errorCallback);
98968
98969         if (key) {
98970             tizen1_utils.validateArgumentType(key, "array",
98971                 new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
98972         }
98973
98974         if (!isConnected || !isSupportedNDEF) {
98975             if (errorCallback) {
98976                 errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
98977             }
98978             return;
98979         }
98980
98981         successCallback();
98982     }
98983     */
98984
98985     nfcTag = {
98986         readNDEF:   readNDEF,
98987         writeNDEF:  writeNDEF,
98988         transceive: transceive
98989         //formatNDEF: formatNDEF
98990     };
98991
98992     nfcTag.__defineGetter__("type", function () {
98993         return type;
98994     });
98995
98996     nfcTag.__defineGetter__("isSupportedNDEF", function () {
98997         return isSupportedNDEF;
98998     });
98999
99000     nfcTag.__defineGetter__("ndefSize", function () {
99001         return ndefSize;
99002     });
99003
99004     nfcTag.__defineGetter__("properties", function () {
99005         return properties;
99006     });
99007
99008     nfcTag.__defineGetter__("isConnected", function () {
99009         return _data.isNear;
99010     });
99011
99012     return nfcTag;
99013 };
99014
99015 NFCPeer = function (isConnected) {
99016     var nfcPeer;
99017
99018     isConnected = isConnected || false;
99019
99020     // Registers a callback function to be invoked when NDEF message is received from NFC peer-to-peer target connected.
99021     function setReceiveNDEFListener(successCallback) {
99022         if (!_security.setReceiveNDEFListener) {
99023             throw new WebAPIException(errorcode.SECURITY_ERR);
99024         }
99025
99026         t.NFCPeer("setReceiveNDEFListener", arguments);
99027
99028         if (!_data.isPeerConnected) {
99029             return;
99030         }
99031         _data.listener.onNDEFReceived = successCallback;
99032     }
99033
99034     // Unregisters the listener for receiving NDEFMessage from NFC peer-to-peer target connected.
99035     function unsetReceiveNDEFListener() {
99036         if (!_security.unsetReceiveNDEFListener) {
99037             throw new WebAPIException(errorcode.SECURITY_ERR);
99038         }
99039
99040         _data.listener.onNDEFReceived = null;
99041     }
99042
99043     // Sends data to NFC peer-to-peer target.
99044     function sendNDEF(ndefMessage, successCallback, errorCallback) {
99045         if (!_security.sendNDEF) {
99046             throw new WebAPIException(errorcode.SECURITY_ERR);
99047         }
99048
99049         t.NFCPeer("sendNDEF", arguments, true);
99050
99051         window.setTimeout(function () {
99052             if (!_data.isPeerConnected) {
99053                 if (errorCallback) {
99054                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
99055                 }
99056                 return;
99057             }
99058
99059             db.saveObject(_data.DB_NFC_OUTPUT_MESSAGE, ndefMessage);
99060             event.trigger("nfc-output-msg", []);
99061             if (successCallback) {
99062                 successCallback();
99063             }
99064         }, 1);
99065     }
99066
99067     nfcPeer = {
99068         setReceiveNDEFListener:   setReceiveNDEFListener,
99069         unsetReceiveNDEFListener: unsetReceiveNDEFListener,
99070         sendNDEF:                 sendNDEF
99071     };
99072
99073     nfcPeer.__defineGetter__("isConnected", function () {
99074         return _data.isPeerConnected;
99075     });
99076
99077     return nfcPeer;
99078 };
99079
99080 function _initialize() {
99081     _data.nfcAdapter = new NFCAdapter();
99082 }
99083
99084 _initialize();
99085
99086 module.exports = _self;
99087
99088 });
99089 define('ripple/platform/tizen/2.0/notification', function (require, exports, module) {
99090 /*
99091  *  Copyright 2013 Intel Corporation.
99092  *
99093  * Licensed under the Apache License, Version 2.0 (the "License");
99094  * you may not use this file except in compliance with the License.
99095  * You may obtain a copy of the License at
99096  *
99097  * http://www.apache.org/licenses/LICENSE-2.0
99098  *
99099  * Unless required by applicable law or agreed to in writing, software
99100  * distributed under the License is distributed on an "AS IS" BASIS,
99101  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99102  * See the License for the specific language governing permissions and
99103  * limitations under the License.
99104  */
99105
99106 var db = require('ripple/db'),
99107     utils = require('ripple/utils'),
99108     event = require('ripple/event'),
99109     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
99110     t = require('ripple/platform/tizen/2.0/typecast'),
99111     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
99112     StatusNotification = require('ripple/platform/tizen/2.0/StatusNotification'),
99113     _notificationStack,
99114     _security = {
99115         "http://tizen.org/privilege/notification": ["post", "update", "remove",
99116                 "removeAll"]
99117     },
99118     _self;
99119
99120 _self = function () {
99121     function post(notification) {
99122         var posted = {};
99123
99124         if (!_security.post) {
99125             throw new WebAPIException(errorcode.SECURITY_ERR);
99126         }
99127
99128         t.NotificationManager("post", arguments);
99129
99130         if (notification.id !== undefined) {
99131             return;
99132         }
99133         posted.id = Math.uuid(null, 16);
99134
99135         notification.__defineGetter__("id", function () {
99136             return posted.id;
99137         });
99138
99139         if (!_notificationStack[notification.id]) {
99140             posted.postedTime = new Date();
99141
99142             notification.__defineGetter__("postedTime", function () {
99143                 return posted.postedTime;
99144             });
99145
99146             _notificationStack[notification.id] = t.Notification(notification,
99147                     "+");
99148             db.saveObject("posted-notifications", _notificationStack);
99149             event.trigger("refreshNotificationUI", [], true);
99150         }
99151     }
99152
99153     function update(notification) {
99154         if (!_security.update) {
99155             throw new WebAPIException(errorcode.SECURITY_ERR);
99156         }
99157
99158         t.NotificationManager("update", arguments);
99159
99160         if (!_notificationStack[notification.id]) {
99161             throw new WebAPIException(errorcode.UNKNOWN_ERR);
99162         }
99163         _notificationStack[notification.id] = t.Notification(notification,
99164                 "+");
99165         db.saveObject("posted-notifications", _notificationStack);
99166         event.trigger("refreshNotificationUI", [], true);
99167     }
99168
99169     function remove(id) {
99170         if (!_security.remove) {
99171             throw new WebAPIException(errorcode.SECURITY_ERR);
99172         }
99173
99174         t.NotificationManager("remove", arguments);
99175
99176         if (!_notificationStack[id]) {
99177             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
99178         }
99179         delete _notificationStack[id];
99180         db.saveObject("posted-notifications", _notificationStack);
99181         event.trigger('refreshNotificationUI', [], true);
99182     }
99183
99184     function removeAll() {
99185         if (!_security.removeAll) {
99186             throw new WebAPIException(errorcode.SECURITY_ERR);
99187         }
99188
99189         _notificationStack = {};
99190         db.saveObject("posted-notifications", _notificationStack);
99191         event.trigger('refreshNotificationUI', [], true);
99192     }
99193
99194     function get(id) {
99195         var n, notification;
99196
99197         t.NotificationManager("get", arguments);
99198
99199         if (!_notificationStack[id]) {
99200             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
99201         }
99202         n = _notificationStack[id];
99203         notification = new StatusNotification(n.statusType, n.title, n);
99204
99205         notification.__defineGetter__("id", function () {
99206             return n.id;
99207         });
99208
99209         notification.__defineGetter__("postedTime", function () {
99210             return n.postedTime;
99211         });
99212
99213         return notification;
99214     }
99215
99216     function getAll() {
99217         var notifications = [];
99218
99219         utils.forEach(_notificationStack, function (n) {
99220             var notification;
99221
99222             notification = new StatusNotification(n.statusType, n.title, n);
99223
99224             notification.__defineGetter__("id", function () {
99225                 return n.id;
99226             });
99227
99228             notification.__defineGetter__("postedTime", function () {
99229                 return n.postedTime;
99230             });
99231
99232             notifications.push(notification);
99233         });
99234
99235         return notifications;
99236     }
99237
99238     function handleSubFeatures(subFeatures) {
99239         var i, subFeature;
99240
99241         for (subFeature in subFeatures) {
99242             for (i in _security[subFeature]) {
99243                 _security[_security[subFeature][i]] = true;
99244             }
99245         }
99246     }
99247
99248     var notification = {
99249         post:              post,
99250         update:            update,
99251         remove:            remove,
99252         removeAll:         removeAll,
99253         get:               get,
99254         getAll:            getAll,
99255         handleSubFeatures: handleSubFeatures
99256     };
99257
99258     return notification;
99259 };
99260
99261 function _initilize() {
99262     _notificationStack = db.retrieveObject("posted-notifications") || {};
99263
99264     utils.forEach(_notificationStack, function (n) {
99265         n.postedTime = new Date(n.postedTime);
99266     });
99267
99268     event.on("refreshNotificationStack", function () {
99269         _notificationStack = db.retrieveObject("posted-notifications");
99270     });
99271 }
99272
99273 _initilize();
99274
99275 module.exports = _self;
99276
99277 });
99278 define('ripple/platform/tizen/2.0/package', function (require, exports, module) {
99279 /*
99280  *  Copyright 2013 Intel Corporation.
99281  *
99282  * Licensed under the Apache License, Version 2.0 (the "License");
99283  * you may not use this file except in compliance with the License.
99284  * You may obtain a copy of the License at
99285  *
99286  * http://www.apache.org/licenses/LICENSE-2.0
99287  *
99288  * Unless required by applicable law or agreed to in writing, software
99289  * distributed under the License is distributed on an "AS IS" BASIS,
99290  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99291  * See the License for the specific language governing permissions and
99292  * limitations under the License.
99293  */
99294
99295 var db = require('ripple/db'),
99296     app = require('ripple/app'),
99297     event = require('ripple/event'),
99298     utils = require('ripple/utils'),
99299     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
99300     t = require('ripple/platform/tizen/2.0/typecast'),
99301     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
99302     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
99303     PackageInformation = require('ripple/platform/tizen/2.0/PackageInformation'),
99304     _security = {
99305         "http://tizen.org/privilege/packagemanager.install": ["install", "uninstall"],
99306         "http://tizen.org/privilege/package.info": ["getPackagesInfo", "getPackageInfo",
99307                     "setPackageInfoEventListener", "unsetPackageInfoEventListener"]
99308     },
99309     DB_PACKAGE_KEY = "tizen-db-package",
99310     _listeners = [],
99311     _data = {
99312         packageList: {},
99313         installedList: {}
99314     },
99315     INTERVAL = 1000, // INTERVAL = 1sec
99316     INSTALL_AMOUNT = 3072, // installation speed amount = 3072 (KB/sec)
99317     PSEUDO_PACKAGE_ID = "pseudopack00",
99318     PSEUDO_APP_ID = "pseudoapp00",
99319     _self;
99320
99321 function _get() {
99322     _data = db.retrieveObject(DB_PACKAGE_KEY);
99323 }
99324
99325 function _save() {
99326     db.saveObject(DB_PACKAGE_KEY, _data);
99327 }
99328
99329 function _exec(callback, name, id, arg1) {
99330     switch (name) {
99331     case "onprogress":
99332         callback[name](id, arg1);
99333         break;
99334     case "oncomplete":
99335         callback[name](id);
99336         break;
99337     default:
99338         break;
99339     }
99340 }
99341
99342 function _setupCurrentPackage() {
99343     var info, id, item, tizenAppId;
99344     info = app.getInfo();
99345     tizenAppId = info.tizenAppId || PSEUDO_APP_ID;
99346     id = info.tizenPackageId;
99347     if (id !== undefined) {
99348         if (_data.installedList[id]) {
99349             // already installed
99350             return;
99351         }
99352
99353         item = null;
99354         utils.forEach(_data.packageList, function (p) {
99355             if (p.id === id) {
99356                 item = p;
99357             }
99358         });
99359
99360         if (item) {
99361             _data.installedList[item.id] = new PackageInformation(
99362                 item.id, item.name, item.iconPath, item.version,
99363                 item.totalSize, item.dataSize, new Date(),
99364                 item.author, item.description, item.appIds
99365             );
99366             event.trigger("install-current-package", [_data.installedList[item.id]]);
99367         } else {
99368             _data.installedList[id] = new PackageInformation(
99369                 id, "Tizen pseudo package", "icon.png", "2.2",
99370                 8264, 50, new Date(),
99371                 "TizenDev", "This is a description which is used in tests.", [tizenAppId]
99372             );
99373             event.trigger("install-current-package", [_data.installedList[id]]);
99374         }
99375     } else {
99376         _data.installedList[PSEUDO_PACKAGE_ID] = new PackageInformation(
99377             PSEUDO_PACKAGE_ID, "Tizen pseudo package", "icon.png", "2.2",
99378             8264, 50, new Date(),
99379             "TizenDev", "This is a description which is used in tests.", [tizenAppId]
99380         );
99381         event.trigger("install-current-package", [_data.installedList[PSEUDO_PACKAGE_ID]]);
99382     }
99383 }
99384
99385 function _updatePackage(path, updateFlag) {
99386     var item, p, info;
99387
99388     if (!_data.packageList[path]) {
99389         return;
99390     }
99391     _get();
99392     p = _data.packageList[path];
99393     item = _data.installedList[p.id];
99394     utils.forEach(_listeners, function (listener) {
99395         info = new PackageInformation(
99396             item.id, item.name, item.iconPath, item.version,
99397             item.totalSize, item.dataSize, item.lastModified,
99398             item.author, item.description, item.appIds);
99399         if (!updateFlag) {
99400             listener.oninstalled(info);
99401         } else {
99402             listener.onupdated(info);
99403         }
99404     });
99405 }
99406
99407 function _initialize() {
99408     _get();
99409
99410     if (!_data)
99411         return;
99412
99413     utils.forEach(_data.installedList, function (item) {
99414         item.lastModified = new Date(item.lastModified);
99415     });
99416
99417     _setupCurrentPackage();
99418
99419     event.on("install-packge", function (path) {
99420         _updatePackage(path, false);
99421     });
99422     event.on("update-package", function (path) {
99423         _updatePackage(path, true);
99424     });
99425
99426     event.on("uninstall-package", function (id) {
99427         _get();
99428         utils.forEach(_listeners, function (listener) {
99429             listener.onuninstalled(id);
99430         });
99431     });
99432 }
99433
99434 _self = function () {
99435     var package;
99436
99437     // public
99438     function install(path, progressCallback, errorCallback) {
99439         if (!_security.install) {
99440             throw new WebAPIException(errorcode.SECURITY_ERR);
99441         }
99442
99443         t.PackageManager("install", arguments);
99444
99445         window.setTimeout(function () {
99446             var intervalId, installedSize = 0, packageSize, updateFlag = false,
99447                 item, info, progress;
99448
99449             if (!_data.packageList[path]) {
99450                 if (errorCallback) {
99451                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
99452                 }
99453                 return;
99454             }
99455             item = _data.packageList[path];
99456             if (_data.installedList[item.id]) {
99457                 updateFlag = true;
99458             }
99459             packageSize = item.totalSize;
99460             intervalId = setInterval(function () {
99461                 if (installedSize >= packageSize) {
99462                     // Install complete
99463                     _data.installedList[item.id] = new PackageInformation(
99464                         item.id, item.name, item.iconPath, item.version,
99465                         item.totalSize, item.dataSize, new Date(),
99466                         item.author, item.description, item.appIds
99467                     );
99468                     event.trigger("install-apps", [item.appIds]);
99469                     _save();
99470                     _exec(progressCallback, "oncomplete", item.id);
99471                     clearInterval(intervalId);
99472                     item = _data.installedList[item.id];
99473                     utils.forEach(_listeners, function (listener) {
99474                         info = new PackageInformation(
99475                             item.id, item.name, item.iconPath, item.version,
99476                             item.totalSize, item.dataSize, item.lastModified,
99477                             item.author, item.description, item.appIds);
99478                         if (!updateFlag) {
99479                             listener.oninstalled(info);
99480                         } else {
99481                             listener.onupdated(info);
99482                         }
99483                     });
99484                     event.trigger("installedList-updated");
99485                 } else {
99486                     installedSize += INSTALL_AMOUNT;
99487                     progress = (installedSize > packageSize) ? 100 :
99488                             Math.floor(installedSize * 100 / packageSize);
99489                     _exec(progressCallback, "onprogress", item.id, progress);
99490                 }
99491             }, INTERVAL);
99492         }, 1);
99493     }
99494
99495     function uninstall(id, progressCallback, errorCallback) {
99496         if (!_security.uninstall) {
99497             throw new WebAPIException(errorcode.SECURITY_ERR);
99498         }
99499
99500         t.PackageManager("uninstall", arguments);
99501
99502         window.setTimeout(function () {
99503             var intervalId, removedSize = 0, packageSize, item, progress;
99504
99505             if (!_data.installedList[id]) {
99506                 if (errorCallback) {
99507                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
99508                 }
99509                 return;
99510             }
99511             item = _data.installedList[id];
99512             packageSize = item.totalSize;
99513             intervalId = setInterval(function () {
99514                 if (removedSize >= packageSize) {
99515                     utils.forEach(_data.packageList, function (package) {
99516                         if (package.id === id) {
99517                             event.trigger("remove-apps", [package.appIds]);
99518                         }
99519                     });
99520                     delete _data.installedList[item.id];
99521                     _save();
99522                     _exec(progressCallback, "oncomplete", item.id);
99523                     clearInterval(intervalId);
99524                     item = _data.installedList[item.id];
99525                     utils.forEach(_listeners, function (listener) {
99526                         listener.onuninstalled(id);
99527                     });
99528                     event.trigger("installedList-updated");
99529                 } else {
99530                     removedSize += INSTALL_AMOUNT * 10;
99531                     progress = (removedSize > packageSize) ? 100 :
99532                             Math.floor(removedSize * 100 / packageSize);
99533                     _exec(progressCallback, "onprogress", item.id, progress);
99534                 }
99535             }, INTERVAL);
99536         }, 1);
99537     }
99538
99539     function getPackagesInfo(successCallback, errorCallback) {
99540         if (!_security.getPackagesInfo) {
99541             throw new WebAPIException(errorcode.SECURITY_ERR);
99542         }
99543
99544         t.PackageManager("getPackagesInfo", arguments);
99545
99546         window.setTimeout(function () {
99547             var packageArray = [];
99548
99549             utils.forEach(_data.installedList, function (item) {
99550                 var i;
99551                 i = new PackageInformation(
99552                         item.id, item.name, item.iconPath, item.version,
99553                         item.totalSize, item.dataSize, item.lastModified,
99554                         item.author, item.description, item.appIds
99555                     );
99556                 packageArray.push(i);
99557             });
99558             successCallback(packageArray);
99559         }, 1);
99560     }
99561
99562     function getPackageInfo(id) {
99563         var p, item;
99564
99565         if (!_security.getPackageInfo) {
99566             throw new WebAPIException(errorcode.SECURITY_ERR);
99567         }
99568
99569         t.PackageManager("getPackageInfo", arguments);
99570
99571         id = id || "api1pack00";
99572
99573         if (!_data.installedList[id]) {
99574             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
99575         }
99576         item = _data.installedList[id];
99577         p = new PackageInformation(item.id, item.name, item.iconPath,
99578                 item.version, item.totalSize, item.dataSize, item.lastModified,
99579                 item.author, item.description, item.appIds);
99580
99581         return p;
99582     }
99583
99584     function setPackageInfoEventListener(eventCallback) {
99585         if (!_security.setPackageInfoEventListener) {
99586             throw new WebAPIException(errorcode.SECURITY_ERR);
99587         }
99588
99589         t.PackageManager("setPackageInfoEventListener", arguments);
99590
99591         _listeners.push(eventCallback);
99592     }
99593
99594     function unsetPackageInfoEventListener() {
99595         if (!_security.unsetPackageInfoEventListener) {
99596             throw new WebAPIException(errorcode.SECURITY_ERR);
99597         }
99598
99599         t.PackageManager("unsetPackageInfoEventListener", arguments);
99600
99601         _listeners = [];
99602     }
99603
99604     function handleSubFeatures(subFeatures) {
99605         var i, subFeature;
99606
99607         for (subFeature in subFeatures) {
99608             for (i in _security[subFeature]) {
99609                 _security[_security[subFeature][i]] = true;
99610             }
99611         }
99612     }
99613
99614     package = {
99615         install:                       install,
99616         uninstall:                     uninstall,
99617         getPackagesInfo:               getPackagesInfo,
99618         getPackageInfo:                getPackageInfo,
99619         setPackageInfoEventListener:   setPackageInfoEventListener,
99620         unsetPackageInfoEventListener: unsetPackageInfoEventListener,
99621         handleSubFeatures:             handleSubFeatures
99622     };
99623
99624     return package;
99625 };
99626
99627 _initialize();
99628
99629 module.exports = _self;
99630
99631 });
99632 define('ripple/platform/tizen/2.0/pendingObject', function (require, exports, module) {
99633 /*
99634  *  Copyright 2011 Intel Corporation.
99635  *
99636  * Licensed under the Apache License, Version 2.0 (the "License");
99637  * you may not use this file except in compliance with the License.
99638  * You may obtain a copy of the License at
99639  *
99640  * http://www.apache.org/licenses/LICENSE-2.0
99641  *
99642  * Unless required by applicable law or agreed to in writing, software
99643  * distributed under the License is distributed on an "AS IS" BASIS,
99644  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99645  * See the License for the specific language governing permissions and
99646  * limitations under the License.
99647  */
99648
99649 module.exports = function (pendingObj) {
99650     var cancelFlag = true;
99651     this.setCancelFlag = function (flag) {
99652         cancelFlag = flag;
99653     };
99654     this.getCancelFlag = function () {
99655         return cancelFlag;
99656     };
99657     this.userCancel = null;
99658     this.pendingID = null;
99659 };
99660
99661 });
99662 define('ripple/platform/tizen/2.0/pendingoperation', function (require, exports, module) {
99663 /*
99664  *  Copyright 2011 Intel Corporation.
99665  *
99666  * Licensed under the Apache License, Version 2.0 (the "License");
99667  * you may not use this file except in compliance with the License.
99668  * You may obtain a copy of the License at
99669  *
99670  * http://www.apache.org/licenses/LICENSE-2.0
99671  *
99672  * Unless required by applicable law or agreed to in writing, software
99673  * distributed under the License is distributed on an "AS IS" BASIS,
99674  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99675  * See the License for the specific language governing permissions and
99676  * limitations under the License.
99677  */
99678
99679 module.exports = function (pendingObj) {
99680     var pending = true;
99681     this.cancel = function () {
99682         if (pending === true) {
99683             if (typeof (pendingObj.getCancelFlag) === "function" && pendingObj.getCancelFlag() === false) {
99684                 pending = false;
99685                 // this clearTimeout is for the case when a 3rd party is invoked to do the task, and it's finished sooner than the intended timeout. therefore, the 3rd party set CancelFlag false, and this cancel is called before timeout
99686                 clearTimeout(pendingObj.pendingID);
99687                 return false;
99688             }
99689             if (typeof (pendingObj.userCancel) === "function") {
99690                 pendingObj.userCancel();
99691             }
99692             clearTimeout(pendingObj.pendingID);
99693             pending = false;
99694             return true;
99695         } else {
99696             return false;
99697         }
99698     };
99699 };
99700
99701
99702 });
99703 define('ripple/platform/tizen/2.0/poi', function (require, exports, module) {
99704 /*
99705  *  Copyright 2012 Intel Corporation.
99706  *
99707  * Licensed under the Apache License, Version 2.0 (the "License");
99708  * you may not use this file except in compliance with the License.
99709  * You may obtain a copy of the License at
99710  *
99711  * http://www.apache.org/licenses/LICENSE-2.0
99712  *
99713  * Unless required by applicable law or agreed to in writing, software
99714  * distributed under the License is distributed on an "AS IS" BASIS,
99715  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99716  * See the License for the specific language governing permissions and
99717  * limitations under the License.
99718  */
99719
99720 var OpenMapQuestProvider = require('ripple/platform/tizen/2.0/poiBackend_openmapquest'), // opne.MapQuest.xapi service
99721     _providers,
99722     _security = {
99723         "http://tizen.org/api/poi": [],
99724         "http://tizen.org/api/poi.read": ["find"],
99725         "http://tizen.org/api/poi.write": ["add", "remove", "update"],
99726         all: true
99727     },
99728     _self;
99729
99730 function _initialize() {
99731     _providers = [new OpenMapQuestProvider({name : "MapQuest", connectivity : "ONLINE", metaData : _security})];
99732 }
99733
99734 _self = function () {
99735     var poi;
99736
99737     poi = {
99738         getDefaultProvider : function () {
99739             return _providers[0];
99740         },
99741         getProviders : function () {
99742             return _providers;
99743         },
99744         handleSubFeatures: function (subFeatures) {
99745             var i, subFeature;
99746             for (subFeature in subFeatures) {
99747                 if (_security[subFeature].length === 0) {
99748                     _security.all = true;
99749                     break;
99750                 }
99751                 _security.all = false;
99752                 for (i = 0; i < _security[subFeature].length; i++) {
99753                     _security[_security[subFeature][i]] = true;
99754                 }
99755             }
99756             _initialize();
99757         }
99758     };
99759
99760     return poi;
99761 };
99762
99763 module.exports = _self;
99764
99765 });
99766 define('ripple/platform/tizen/2.0/poiBackend_openmapquest', function (require, exports, module) {
99767 /*
99768  *  Copyright 2012 Intel Corporation.
99769  *
99770  * Licensed under the Apache License, Version 2.0 (the "License");
99771  * you may not use this file except in compliance with the License.
99772  * You may obtain a copy of the License at
99773  *
99774  * http://www.apache.org/licenses/LICENSE-2.0
99775  *
99776  * Unless required by applicable law or agreed to in writing, software
99777  * distributed under the License is distributed on an "AS IS" BASIS,
99778  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99779  * See the License for the specific language governing permissions and
99780  * limitations under the License.
99781  */
99782
99783 var lbs = require('ripple/platform/tizen/2.0/lbs_utils'),
99784     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
99785     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
99786     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
99787     POIGeometry = require('ripple/platform/tizen/2.0/POIGeometry'),
99788     SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
99789     _security;
99790
99791 function POIPublic(prop) {
99792     /* This is created for public use */
99793     var _self, i, copy, attr,  _id = null, _providerName = null;
99794     if (prop.id) {
99795         _id = prop.id;
99796     }
99797     if (prop.providerName) {
99798         _providerName = prop.providerName;
99799     }
99800     _self = {
99801         name : null,
99802         categories : [],
99803         address : null,
99804         phoneNumbers : [],
99805         geometry : null,
99806         urls : [],
99807         rating : null,
99808         tags : null,
99809         toGeoJSON : function () {
99810             throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
99811         }
99812     };
99813
99814     _self.__defineGetter__("id", function () {
99815         return _id;
99816     });
99817
99818     _self.__defineGetter__("providerName", function () {
99819         return _providerName;
99820     });
99821
99822     if (prop) {
99823         if (prop.name) {
99824             _self.name = String(prop.name);
99825         }
99826         if (tizen1_utils.isValidArray(prop.categories)) {
99827             _self.categories = [];
99828             for (i in prop.categories) {
99829                 _self.categories.push(String(prop.categories[i]));
99830             }
99831         }
99832         if (prop.address) {
99833             if (typeof prop.address === "string") {
99834                 _self.address = String(prop.address);
99835             } else if (Object.prototype.toString.call(prop.address) === "[object Object]") {
99836                 copy = prop.address.constructor();
99837                 for (attr in prop.address) {
99838                     if (prop.address.hasOwnProperty(attr)) {
99839                         copy[attr] = prop.address[attr];
99840                     }
99841                 }
99842                 _self.address = copy;
99843             }
99844         }
99845         if (tizen1_utils.isValidArray(prop.phoneNumbers)) {
99846             _self.phoneNumbers = [];
99847             for (i in prop.phoneNumbers) {
99848                 _self.phoneNumbers.push(String(prop.phoneNumbers[i]));
99849             }
99850         }
99851         if (prop.geometry) {
99852             _self.geometry = new POIGeometry(prop.geometry.position, prop.geometry.viewport, prop.geometry.wkt);
99853         }
99854         if (tizen1_utils.isValidArray(prop.urls)) {
99855             _self.urls = [];
99856             for (i in prop.urls) {
99857                 _self.urls.push(String(prop.urls[i]));
99858             }
99859         }
99860         if (typeof prop.rating === "number") {
99861             _self.rating = prop.rating;
99862         }
99863         if (Object.prototype.toString.call(prop.tags) === "[object Object]") {
99864             copy = prop.tags.constructor();
99865             for (attr in prop.tags) {
99866                 if (prop.tags.hasOwnProperty(attr)) {
99867                     copy[attr] = prop.tags[attr];
99868                 }
99869             }
99870             _self.tags = copy;
99871         }
99872     }
99873
99874     return _self;
99875 }
99876
99877 module.exports = function (prop) {
99878
99879     var _self = new lbs.LocationServiceProvider(prop);
99880
99881     if (prop.metaData) {
99882         _security = prop.metaData;
99883     }
99884
99885     _self.__defineGetter__("supportedFilterTypes", function () {
99886         return [];
99887     });
99888
99889     _self.__defineGetter__("supportedPOIFilterAttributes", function () {
99890         return [];
99891     });
99892
99893     _self.__defineGetter__("supportedCategories", function () {
99894         /* reference: http://wiki.openstreetmap.org/wiki/Map_Features#Amenity */
99895         return ["bar", "bbq", "biergarten", "cafe", "drinking_water", "fast_food", "food_court", "ice_cream",
99896                 "pub", "restaurant", "college", "kindergarten", "library", "school", "university",
99897                 "bicycle_parking", "bicycle_rental", "bus_station", "car_rental", "car_sharing", "car_wash",
99898                 "ev_charging", "ferry_terminal", "fuel", "grit_bin", "parking", "parking_entrance",
99899                 "parking_space", "taxi", "atm", "bank", "bureau_de_change", "baby_hatch", "clinic",
99900                 "dentist", "doctors", "hospital", "nursing_home", "pharmacy", "social_facility", "veterinary",
99901                 "arts_centre", "cinema", "community_centre", "fountain", "nightclub", "social_centre",
99902                 "stripclub", "studio", "swingerclub", "theatre", "bench", "brothel", "clock", "courthouse",
99903                 "crematorium", "embassy", "fire_station", "grave_yard", "hunting_stand", "marketplace",
99904                 "place_of_worship", "police", "post_box", "post_office", "prison", "public_building",
99905                 "recycling", "sauna", "shelter", "shower", "telephone", "toilets", "townhall", "vending_machine",
99906                 "waste_basket", "waste_disposal", "watering_place"];
99907     });
99908
99909     _self.__defineGetter__("capabilities", function () {
99910         /* The set is empty, indicating that this provider supports only 'find' operations */
99911         return [];
99912     });
99913
99914     _self.find = function (point, successCallback, errorCallback, options) {
99915         /* This provider only supports searching by "GeoRectBounds" due to MapQuest XAPI limitation */
99916
99917         function _find() {
99918             var searchStr, pois = [], isTypeOK = false,
99919                 id, providerName, name, categories = [], geometry;
99920
99921             if (Object.prototype.toString.call(point) === "[object Object]") {
99922                 if (point.southWest && point.northEast) {
99923                     if (typeof point.southWest.latitude === "number" &&
99924                         typeof point.southWest.longitude === "number" &&
99925                         typeof point.northEast.latitude === "number" &&
99926                         typeof point.northEast.longitude === "number") {
99927                         isTypeOK = true;
99928                     }
99929                 }
99930             }
99931
99932             if (!isTypeOK) {
99933                 throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
99934             }
99935
99936             searchStr = "http://open.mapquestapi.com/xapi/api/0.6/node";
99937             if (options && tizen1_utils.isValidArray(options.categories) &&
99938                 options.categories.length > 0 && typeof options.categories[0] === "string") {
99939                 /* xapi support single amenity only */
99940                 searchStr += "[amenity=" + options.categories[0] + "]";
99941             }
99942             searchStr += "[bbox=" + point.southWest.longitude + "," + point.southWest.latitude + "," +
99943                 point.northEast.longitude + "," + point.northEast.latitude + "]";
99944
99945             /* use Open MapQuest online xapi service. (http://open.mapquestapi.com/xapi/) */
99946             $.ajax({
99947                 type: "GET",
99948                 url: searchStr,
99949                 dataType: "xml",
99950                 timeout: 15000, /* 15 secs timeout */
99951                 success: function (xml) {
99952                     providerName = $(xml).find("osm").attr("generator");
99953                     $(xml).find("node").each(function () {
99954                         var $item = $(this);
99955                         categories = [];
99956                         id = $item.attr("id");
99957                         geometry = new POIGeometry(new SimpleCoordinates($item.attr("lat"), $item.attr("lon")));
99958                         $item.find("tag").each(function () {
99959                             if ($(this).attr("k") === "name") {
99960                                 name = $(this).attr("v");
99961                             } else if ($(this).attr("k") === "amenity") {
99962                                 categories.push($(this).attr("v"));
99963                             }
99964                         });
99965                         pois.push(new POIPublic({id: id, providerName: providerName, name: name,
99966                                                 categories: categories, geometry: geometry}));
99967                     });
99968                     successCallback(pois);
99969                 },
99970                 error: function (obj, msg) {
99971                     if (errorCallback) {
99972                         if (msg === "timeout") {
99973                             setTimeout(function () {
99974                                 errorCallback(new WebAPIError(errorcode.TIMEOUT_ERR));
99975                             }, 1);
99976                         } else {
99977                             setTimeout(function () {
99978                                 errorCallback(new WebAPIError(errorcode.NETWORK_ERR));
99979                             }, 1);
99980                         }
99981                     }
99982                 }
99983             });
99984         }
99985
99986         if (!_security.all && !_security.find) {
99987             throw new WebAPIError(errorcode.SECURITY_ERR);
99988         }
99989
99990         tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find);
99991     };
99992
99993     _self.update = function (poi, successCallback, errorCallback) {
99994         if (!_security.all && !_security.update) {
99995             throw new WebAPIError(errorcode.SECURITY_ERR);
99996         }
99997
99998         throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
99999     };
100000
100001     _self.add = function (poi, successCallback, errorCallback) {
100002         if (!_security.all && !_security.add) {
100003             throw new WebAPIError(errorcode.SECURITY_ERR);
100004         }
100005
100006         throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
100007     };
100008
100009     _self.remove = function (poi, successCallback, errorCallback) {
100010         if (!_security.all && !_security.remove) {
100011             throw new WebAPIError(errorcode.SECURITY_ERR);
100012         }
100013
100014         throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
100015     };
100016
100017     return _self;
100018 };
100019
100020 });
100021 define('ripple/platform/tizen/2.0/power', function (require, exports, module) {
100022 /*
100023  *  Copyright 2012 Intel Corporation.
100024  *
100025  * Licensed under the Apache License, Version 2.0 (the "License");
100026  * you may not use this file except in compliance with the License.
100027  * You may obtain a copy of the License at
100028  *
100029  * http://www.apache.org/licenses/LICENSE-2.0
100030  *
100031  * Unless required by applicable law or agreed to in writing, software
100032  * distributed under the License is distributed on an "AS IS" BASIS,
100033  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
100034  * See the License for the specific language governing permissions and
100035  * limitations under the License.
100036  */
100037 var event = require('ripple/event'),
100038     constants = require('ripple/constants'),
100039     deviceSettings = require('ripple/deviceSettings'),
100040     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
100041     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
100042     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
100043     _POWER_RESOURCE = constants.POWER_RESOURCE,
100044     _SCREEN_STATE = constants.POWER_RESOURCE.SCREEN.STATE,
100045     ScreenState = {"previous" : null, "current" : null},
100046     _listeners = [],
100047     _isScreenResourceOccupied = false,
100048     _originalBrightness,
100049     _isCPUAwake = false,
100050     _isScreenOn = true,
100051     _normalBrightness,
100052     _minimal_screen_state = null,
100053     _security = {
100054         "http://tizen.org/privilege/power": ["request", "setScreenBrightness", "turnScreenOn", "turnScreenOff"]
100055     },
100056     _self;
100057
100058 /**initialize**/
100059 function initState() {
100060     _normalBrightness = deviceSettings.retrieve("DISPLAY.brightness");
100061     updateResourceState();
100062 }
100063
100064 function getResourceState(value) {
100065     var state;
100066     value = Number(value);
100067     if (value <=  _SCREEN_STATE.SCREEN_OFF.MAX) {
100068         state = _SCREEN_STATE.SCREEN_OFF.NAME;
100069     } else if (value < _SCREEN_STATE.SCREEN_DIM.MAX) {
100070         state = _SCREEN_STATE.SCREEN_DIM.NAME;
100071     } else if (value < _SCREEN_STATE.SCREEN_NORMAL.MAX) {
100072         state = _SCREEN_STATE.SCREEN_NORMAL.NAME;
100073     } else {
100074         state = _SCREEN_STATE.SCREEN_BRIGHT.NAME;
100075     }
100076     return state;
100077 }
100078
100079 function updateResourceState() {
100080     var brightness, actualState;
100081     brightness = deviceSettings.retrieve("DISPLAY.brightness");
100082     actualState = getResourceState(brightness);
100083     ScreenState.previous = ScreenState.current;
100084     ScreenState.current = actualState;
100085 }
100086
100087 function callListeners(listeners, previousState, changedState) {
100088     listeners.forEach(function (listener) {
100089         setTimeout(function () {
100090             listener(previousState, changedState);
100091         }, 1);
100092     });
100093 }
100094
100095 function triggerListenerCB(stateObj) {
100096     if (stateObj.previous !== stateObj.current) {
100097         callListeners(_listeners, stateObj.previous, stateObj.current);
100098     }
100099 }
100100
100101 _self = function () {
100102     function request(resource, state) {
100103         if (!_security.request) {
100104             throw new WebAPIError(errorcode.SECURITY_ERR);
100105         }
100106         if (typeof resource !== 'string' || typeof state !== 'string') {
100107             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
100108         }
100109         //Check resource
100110         if (!_POWER_RESOURCE.hasOwnProperty(resource)) {
100111             throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
100112         }
100113         //Check state
100114         if (!_POWER_RESOURCE[resource].STATE.hasOwnProperty(state)) {
100115             throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
100116         }
100117         // Exception check: SCREEN_OFF is a state cannot be requested
100118         if (resource === "SCREEN" && state === "SCREEN_OFF") {
100119             throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
100120         }
100121         switch (resource) {
100122         case "SCREEN" :
100123             if ((_minimal_screen_state === null) ||
100124                (_minimal_screen_state === "SCREEN_DIM" && (state === "SCREEN_NORMAL" || state === "SCREEN_BRIGHT")) ||
100125                (_minimal_screen_state === "SCREEN_NORMAL" && state === "SCREEN_BRIGHT")) {
100126                 _minimal_screen_state = state;
100127             }
100128             break;
100129         case "CPU" :
100130             _isCPUAwake = true;
100131             break;
100132         default:
100133             break;
100134         }
100135     }
100136
100137     function release(resource) {
100138         switch (resource) {
100139         case "SCREEN" :
100140             if (_isScreenResourceOccupied) {
100141                 _isScreenResourceOccupied = false;
100142                 deviceSettings.persist("DISPLAY.brightness", _originalBrightness);
100143                 event.trigger("DisplayBrightnessChangedByPower", [_originalBrightness]);
100144                 updateResourceState();
100145                 triggerListenerCB(ScreenState);
100146             }
100147             _minimal_screen_state = null;
100148             break;
100149         case "CPU" :
100150             _isCPUAwake = false;
100151             break;
100152         default:
100153             if (typeof resource === "string") {
100154                 throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
100155             } else  {
100156                 throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
100157             }
100158         }
100159     }
100160
100161     function setScreenStateChangeListener(listener) {
100162         tizen1_utils.validateArgumentType(listener, "function",
100163                 new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
100164         _listeners.push(listener);
100165     }
100166
100167     function unsetScreenStateChangeListener() {
100168         _listeners = [];
100169     }
100170
100171     function getScreenBrightness() {
100172         var brightness = deviceSettings.retrieve("DISPLAY.brightness");
100173         return brightness;
100174     }
100175
100176     function setScreenBrightness(brightness) {
100177         if (!_security.setScreenBrightness) {
100178             throw new WebAPIError(errorcode.SECURITY_ERR);
100179         }
100180         if (typeof brightness !== 'number') {
100181             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
100182         }
100183         if (brightness < 0 || brightness > 1) {
100184             throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
100185         }
100186         if (!_isScreenResourceOccupied) {
100187             _originalBrightness = deviceSettings.retrieve("DISPLAY.brightness");
100188             _isScreenResourceOccupied = true;
100189         }
100190         deviceSettings.persist("DISPLAY.brightness", brightness);
100191         event.trigger("DisplayBrightnessChangedByPower", [brightness]);
100192         updateResourceState();
100193         triggerListenerCB(ScreenState);
100194     }
100195
100196     function isScreenOn() {
100197         return _isScreenOn;
100198     }
100199
100200     function restoreScreenBrightness() {
100201         if (_isScreenResourceOccupied) {
100202             _isScreenResourceOccupied = false;
100203             deviceSettings.persist("DISPLAY.brightness", _originalBrightness);
100204             event.trigger("DisplayBrightnessChangedByPower", [_originalBrightness]);
100205             updateResourceState();
100206             triggerListenerCB(ScreenState);
100207         }
100208     }
100209
100210     function turnScreenOn() {
100211         var brightness, value, flag = false;
100212         if (!_security.turnScreenOn) {
100213             throw new WebAPIError(errorcode.SECURITY_ERR);
100214         }
100215         brightness = deviceSettings.retrieve("DISPLAY.brightness");
100216         switch (_minimal_screen_state) {
100217         case "SCREEN_DIM":
100218             if (brightness <= _SCREEN_STATE.SCREEN_OFF.VALUE) {
100219                 if (!_isScreenResourceOccupied) {
100220                     _originalBrightness = brightness;
100221                     _isScreenResourceOccupied = true;
100222                 }
100223                 value = _SCREEN_STATE.SCREEN_DIM.VALUE;
100224                 flag = true;
100225             }
100226             break;
100227         case "SCREEN_NORMAL":
100228             if (brightness < _SCREEN_STATE.SCREEN_NORMAL.MIN) {
100229                 if (!_isScreenResourceOccupied) {
100230                     _originalBrightness = brightness;
100231                     _isScreenResourceOccupied = true;
100232                 }
100233                 value = _normalBrightness;
100234                 flag = true;
100235             }
100236             break;
100237         case "SCREEN_BRIGHT":
100238             if (brightness < _SCREEN_STATE.SCREEN_BRIGHT.MIN) {
100239                 if (!_isScreenResourceOccupied) {
100240                     _originalBrightness = brightness;
100241                     _isScreenResourceOccupied = true;
100242                 }
100243                 value = _SCREEN_STATE.SCREEN_BRIGHT.VALUE;
100244                 flag = true;
100245             }
100246             break;
100247         }
100248         if (flag) {
100249             deviceSettings.persist("DISPLAY.brightness", value);
100250             event.trigger("DisplayBrightnessChangedByPower", [value]);
100251             updateResourceState();
100252             triggerListenerCB(ScreenState);
100253         }
100254         _isScreenOn = true;
100255     }
100256
100257     function turnScreenOff() {
100258         if (!_security.turnScreenOff) {
100259             throw new WebAPIError(errorcode.SECURITY_ERR);
100260         }
100261         _isScreenOn = false;
100262     }
100263
100264     function handleSubFeatures(subFeatures) {
100265         var i, subFeature;
100266
100267         for (subFeature in subFeatures) {
100268             for (i in _security[subFeature]) {
100269                 _security[_security[subFeature][i]] = true;
100270             }
100271         }
100272     }
100273
100274     var power = {
100275         request: request,
100276         release: release,
100277         setScreenStateChangeListener: setScreenStateChangeListener,
100278         unsetScreenStateChangeListener: unsetScreenStateChangeListener,
100279         getScreenBrightness: getScreenBrightness,
100280         setScreenBrightness: setScreenBrightness,
100281         isScreenOn: isScreenOn,
100282         restoreScreenBrightness: restoreScreenBrightness,
100283         turnScreenOn: turnScreenOn,
100284         turnScreenOff: turnScreenOff,
100285         handleSubFeatures : handleSubFeatures
100286     };
100287
100288     return power;
100289 };
100290
100291 initState();
100292 event.on("CpuLoadChanged", function (value) {
100293     var load;
100294     if (_isCPUAwake && Number(value) === 0) {
100295         load = _POWER_RESOURCE.CPU.STATE.CPU_AWAKE.DEFAULT_VALUE;
100296         deviceSettings.persist("CPU.load", load);
100297         event.trigger("CpuLoadChangedByPower", [load]);
100298     }
100299 });
100300 event.on("DisplayBrightnessChanged", function () {
100301     _normalBrightness = deviceSettings.retrieve("DISPLAY.brightness");
100302     updateResourceState();
100303     triggerListenerCB(ScreenState);
100304 });
100305
100306 module.exports = _self;
100307
100308 });
100309 define('ripple/platform/tizen/2.0/push', function (require, exports, module) {
100310 /*
100311  *  Copyright 2013 Intel Corporation.
100312  *
100313  * Licensed under the Apache License, Version 2.0 (the "License");
100314  * you may not use this file except in compliance with the License.
100315  * You may obtain a copy of the License at
100316  *
100317  * http://www.apache.org/licenses/LICENSE-2.0
100318  *
100319  * Unless required by applicable law or agreed to in writing, software
100320  * distributed under the License is distributed on an "AS IS" BASIS,
100321  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
100322  * See the License for the specific language governing permissions and
100323  * limitations under the License.
100324  */
100325
100326 var event = require('ripple/event'),
100327     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
100328     t = require('ripple/platform/tizen/2.0/typecast'),
100329     Notification = require('ripple/platform/tizen/2.0/notification'),
100330     StatusNotification = require('ripple/platform/tizen/2.0/StatusNotification'),
100331     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
100332     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
100333     PushMessage,
100334     _data = {
100335         service: {
100336 /*          "ID_APPLICATION_0": {
100337  *              appId:          null,
100338  *              registrationId: null,
100339  *              appControl:     null,
100340  *              isRegistered:   false,
100341  *              isConnected:    false,
100342  *              onpushed:       null
100343  *          }
100344  */
100345         }
100346     },
100347     _security = {
100348         "http://tizen.org/privilege/push": ["registerService",
100349             "unregisterService", "connectService", "disconnectService",
100350             "getRegistrationId"]
100351     },
100352     _self;
100353
100354 function _initialize() {
100355     event.on("PushNotified", function (appId, pushMessage) {
100356         var appService, notificationDict, statusNotification, notification;
100357
100358         appService = _data.service[appId];
100359
100360         if (!appService)
100361             return;
100362
100363         if (appService.isConnected) {
100364             appService.onpushed(new PushMessage(pushMessage));
100365         } else {
100366             notificationDict = {
100367                 content: pushMessage.appData,
100368                 appControl: appService.appControl,
100369                 appId: appId
100370             };
100371             statusNotification = new StatusNotification("SIMPLE",
100372                 pushMessage.alertMessage, notificationDict);
100373             notification = new Notification();
100374
100375             notification.post(statusNotification);
100376         }
100377     });
100378 }
100379
100380 function _getCurrentApplicationId() {
100381     return "ID_APPLICATION_0";
100382 }
100383
100384 _self = function () {
100385     var push;
100386
100387     function registerService(appControl, successCallback, errorCallback) {
100388         if (!_security.registerService) {
100389             throw new WebAPIException(errorcode.SECURITY_ERR);
100390         }
100391
100392         t.PushManager("registerService", arguments, true);
100393
100394         window.setTimeout(function () {
100395             var appId, appService;
100396
100397             appId = _getCurrentApplicationId();
100398             appService = {
100399                 appId:          appId,
100400                 registrationId: null,
100401                 appControl:     appControl,
100402                 isRegistered:   false
100403             };
100404             _data.service[appId] = appService;
100405
100406             event.trigger("PushRequest", ["REGISTER", appService], true);
100407
100408             if (appService.registrationId === null) {
100409                 if (errorCallback) {
100410                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
100411                 }
100412                 return;
100413             }
100414
100415             appService.isRegistered = true;
100416             successCallback(appService.registrationId);
100417         }, 1);
100418     }
100419
100420     function unregisterService(successCallback, errorCallback) {
100421         if (!_security.unregisterService) {
100422             throw new WebAPIException(errorcode.SECURITY_ERR);
100423         }
100424
100425         t.PushManager("unregisterService", arguments);
100426
100427         window.setTimeout(function () {
100428             var appId;
100429
100430             appId = _getCurrentApplicationId();
100431             delete _data.service[appId];
100432             event.trigger("PushRequest", ["UNREGISTER", appId]);
100433             if (successCallback) {
100434                 successCallback();
100435             }
100436         }, 1);
100437     }
100438
100439     function connectService(notificationCallback) {
100440         var appId, appService;
100441
100442         if (!_security.connectService) {
100443             throw new WebAPIException(errorcode.SECURITY_ERR);
100444         }
100445
100446         t.PushManager("connectService", arguments);
100447
100448         appId = _getCurrentApplicationId();
100449         appService = _data.service[appId];
100450         if (!appService || !appService.isRegistered) {
100451             throw new WebAPIException(errorcode.UNKNOWN_ERR);
100452         }
100453
100454         appService.isConnected = true;
100455         appService.onpushed    = notificationCallback;
100456         event.trigger("PushRequest", ["CONNECT", appId]);
100457     }
100458
100459     function disconnectService() {
100460         var appId, appService;
100461
100462         if (!_security.disconnectService) {
100463             throw new WebAPIException(errorcode.SECURITY_ERR);
100464         }
100465
100466         t.PushManager("disconnectService", arguments);
100467
100468         appId = _getCurrentApplicationId();
100469         appService = _data.service[appId];
100470         if (!appService || !appService.isRegistered ||
100471                 !appService.isConnected) {
100472             return;
100473         }
100474
100475         appService.onpushed    = null;
100476         appService.isConnected = false;
100477         event.trigger("PushRequest", ["DISCONNECT", appId]);
100478     }
100479
100480     function getRegistrationId() {
100481         var appService;
100482
100483         if (!_security.getRegistrationId) {
100484             throw new WebAPIException(errorcode.SECURITY_ERR);
100485         }
100486
100487         t.PushManager("getRegistrationId", arguments);
100488
100489         appService = _data.service[_getCurrentApplicationId()];
100490         if (!appService || !appService.isRegistered) {
100491             return null;
100492         }
100493
100494         return appService.registrationId;
100495     }
100496
100497     function handleSubFeatures(subFeatures) {
100498         var i, subFeature;
100499
100500         for (subFeature in subFeatures) {
100501             for (i in _security[subFeature]) {
100502                 _security[_security[subFeature][i]] = true;
100503             }
100504         }
100505     }
100506
100507     push = {
100508         registerService:   registerService,
100509         unregisterService: unregisterService,
100510         connectService:    connectService,
100511         disconnectService: disconnectService,
100512         getRegistrationId: getRegistrationId,
100513         handleSubFeatures: handleSubFeatures
100514     };
100515
100516     return push;
100517 };
100518
100519 _initialize();
100520
100521 PushMessage = function (pushMessageInitDict) {
100522     var appData, alertMessage, date;
100523
100524     this.__defineGetter__("appData", function () {
100525         return appData;
100526     });
100527
100528     this.__defineGetter__("alertMessage", function () {
100529         return alertMessage;
100530     });
100531
100532     this.__defineGetter__("date", function () {
100533         return date;
100534     });
100535
100536     appData      = pushMessageInitDict.appData || "";
100537     alertMessage = pushMessageInitDict.alertMessage || "";
100538     date         = pushMessageInitDict.date || new Date();
100539 };
100540
100541 module.exports = _self;
100542
100543 });
100544 define('ripple/platform/tizen/2.0/route', function (require, exports, module) {
100545 /*
100546  *  Copyright 2012 Intel Corporation.
100547  *
100548  * Licensed under the Apache License, Version 2.0 (the "License");
100549  * you may not use this file except in compliance with the License.
100550  * You may obtain a copy of the License at
100551  *
100552  * http://www.apache.org/licenses/LICENSE-2.0
100553  *
100554  * Unless required by applicable law or agreed to in writing, software
100555  * distributed under the License is distributed on an "AS IS" BASIS,
100556  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
100557  * See the License for the specific language governing permissions and
100558  * limitations under the License.
100559  */
100560
100561 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
100562     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
100563     SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
100564     ProviderNominatim = require('ripple/platform/tizen/2.0/routeBackend_navigation'), // navigation route service
100565     _getProviders,
100566     _providers,
100567     _self;
100568
100569 function _initialize() {
100570     _providers = [new ProviderNominatim({name : "Nominatim", connectivity : "ONLINE"})];
100571 }
100572
100573 _initialize();
100574
100575 _self = {
100576     getDefaultProvider : function () {
100577         if (arguments.length !== 0) {
100578             throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
100579         }
100580         return _providers[0];
100581     },
100582     getProviders : function () {
100583         if (arguments.length !== 0) {
100584             throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
100585         }
100586         return _providers;
100587     }
100588 };
100589
100590 module.exports = _self;
100591
100592 });
100593 define('ripple/platform/tizen/2.0/routeBackend_local', function (require, exports, module) {
100594 /*
100595  *  Copyright 2012 Intel Corporation.
100596  *
100597  * Licensed under the Apache License, Version 2.0 (the "License");
100598  * you may not use this file except in compliance with the License.
100599  * You may obtain a copy of the License at
100600  *
100601  * http://www.apache.org/licenses/LICENSE-2.0
100602  *
100603  * Unless required by applicable law or agreed to in writing, software
100604  * distributed under the License is distributed on an "AS IS" BASIS,
100605  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
100606  * See the License for the specific language governing permissions and
100607  * limitations under the License.
100608  */
100609
100610 var db = require('ripple/db'),
100611     utils = require('ripple/utils'),
100612     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
100613     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
100614     SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
100615     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
100616     lbs = require('ripple/platform/tizen/2.0/lbs'),
100617     LocationServiceProvider = {},
100618     RouteWaypoint,
100619     RouteDistance,
100620     RouteDuration,
100621     RouteStep,
100622     RouteSegment,
100623     RouteRequestOptions,
100624     RouteResultSummary,
100625     RouteResult,
100626     _data = {
100627         DB_ROUTE_LOCATION_KEY: "tizen1-db-route",
100628         DB_ROUTE_COLLEAGE_KEY: "tizen2-db-route",
100629         routeProvider: {},
100630         routes: [],
100631         RouteDistanceUnit: ["M", "KM", "MI", "FT"],
100632         providers: [],
100633         path: []
100634     },
100635     _self;
100636
100637 // The RouteWaypoint object
100638 RouteWaypoint = function () {
100639     return {
100640         position: {
100641             latitude: 0,
100642             longitude: 0
100643         },
100644         isStopover: true
100645     };
100646 };
100647
100648 // The RouteDistance object
100649 RouteDistance = function () {
100650     return {
100651         text: "",
100652         value: 0,
100653         unit: "KM"
100654     };
100655 };
100656
100657 // The RouteDuration object
100658 RouteDuration = function () {
100659     return {
100660         text: "",
100661         value: 0 // The duration in a seconds
100662     };
100663 };
100664
100665 // The RouteStep object
100666 RouteStep = function () {
100667     var _self = {
100668         mode: "",        // The way of the travel, for example: car, bike, foot
100669         instruction: "", // The instruction of this step
100670         points: []       // The points of this step
100671     };
100672
100673     _self.origin      = new SimpleCoordinates(0, 0);
100674     _self.destination = new SimpleCoordinates(0, 0);
100675     _self.distance    = new RouteDistance();
100676     _self.duration    = new RouteDuration();
100677
100678     return _self;
100679 };
100680
100681 // The RouteSegment object
100682 RouteSegment = function () {
100683     var _self = {
100684         steps: []
100685     };
100686
100687     _self.origin      = new SimpleCoordinates(0, 0);
100688     _self.destination = new SimpleCoordinates(0, 0);
100689     _self.distance    = new RouteDistance();
100690     _self.duration    = new RouteDuration();
100691
100692     return _self;
100693 };
100694
100695 // The RouteRequestOptions object
100696 RouteRequestOptions = function () {
100697     return {
100698         mode: "", // CAR, BIKE
100699         unit: "KM",
100700         routeGoal: "SHORTEST",
100701         constraints: ["HIGHWAY", "TOLL", "UNPAVED"],
100702         wayPoints: [],
100703         maxResults: 1
100704     };
100705 };
100706
100707 // The RouteResultSummary object
100708 RouteResultSummary = function () {
100709     var _self = {};
100710
100711     _self.origin        = new SimpleCoordinates(0, 0);
100712     _self.destination   = new SimpleCoordinates(0, 0);
100713     _self.totalDistance = new RouteDistance();
100714     _self.totalDuration = new RouteDuration();
100715
100716     return _self;
100717 };
100718
100719 // The RouteResult object
100720 RouteResult = function () {
100721     var _self = {
100722         segments: []
100723     };
100724
100725     _self.summary = new RouteResultSummary();
100726
100727     return _self;
100728 };
100729
100730 // Floyd arithmetic in Mathematics, solving the optimal way
100731 function floyd(e, n, startIndex, endIndex) {
100732     var MAX = Infinity,
100733         a = new Array(n), i, j, k, p = new Array(n),
100734         paths, pathWay = [];
100735
100736     for (i = 1; i < n + 1; i++) {
100737         a[i] = new Array(n);
100738     }
100739     for (i = 1; i < n + 1; i++) {
100740         p[i] = new Array(n);
100741     }
100742     for (i = 1; i < n + 1; i++) {
100743         for (j = 1; j < n + 1; j++) {
100744             if (i === j || e[i][j] === "MIN") {
100745                 a[i][j] = 0;
100746             } else if (e[i][j] !== 0 && e[i][j] !== "MIN") {
100747                 a[i][j] = e[i][j];
100748             } else {
100749                 a[i][j] = MAX;
100750             }
100751             p[i][j] = 0;
100752         }
100753     }
100754     for (i = 1; i < n + 1; i++) {
100755         a[i][i] = 0;
100756     }
100757     for (k = 1; k < n + 1; k++) {
100758         for (i = 1; i < n + 1; i++) {
100759             for (j = 1; j < n + 1; j++) {
100760                 if (parseInt(a[i][k], 10) + parseInt(a[k][j], 10) < a[i][j]) {
100761                     a[i][j] = parseInt(a[i][k], 10) + parseInt(a[k][j], 10);
100762                     p[i][j] = k;
100763                 }
100764             }
100765         }
100766     }
100767     _data.path = [];
100768     paths = findPath(startIndex, endIndex, p);
100769     pathWay = [];
100770     pathWay.push(startIndex);
100771     for (i = 0; i < paths.length; i++) {
100772         pathWay.push(paths[i]);
100773     }
100774     pathWay.push(endIndex);
100775
100776     return pathWay;
100777 }
100778
100779 // Find the best way in the locations
100780 function findPath(i, j, p) {
100781     var k = p[i][j];
100782
100783     if (k === 0 || i === j) {
100784         return _data.path;
100785     }
100786     findPath(i, k, p);
100787     _data.path.push(k);
100788
100789     return findPath(k, j, p);
100790 }
100791
100792 // Find the index in the locations by string
100793 function findIndexByStr(str, locations) {
100794     for (var i in locations) {
100795         if (locations[i].name === str) {
100796             return parseInt(i, 10) + 1;
100797         }
100798     }
100799     return -1;
100800 }
100801
100802 // Find the index in the colleages by name1 and name2
100803 function findValueByStr(start, end, locations, colleages) {
100804     for (var i in colleages) {
100805         if (colleages[i].name1 === locations[start - 1].name && colleages[i].name2 === locations[end - 1].name) {
100806             return parseInt(i, 10);
100807         } else if (colleages[i].name2 === locations[start - 1].name && colleages[i].name1 === locations[end - 1].name) {
100808             return parseInt(i, 10);
100809         }
100810     }
100811     return -1;
100812 }
100813
100814 // Find the index in the locations by latitude and longitude
100815 function searchIndexBycoodinates(latitude, longitude, locations) {
100816     if (latitude !== null && longitude !== null) {
100817         for (var i in locations) {
100818             if (locations[i].latitude === latitude && locations[i].longitude === longitude) {
100819                 return parseInt(i, 10) + 1;
100820             }
100821         }
100822     }
100823     return -1;
100824 }
100825
100826 // Get the relation among the locations
100827 function getRelation(n, colleages, locations, goal) {
100828     var i, j, start, end, relation = new Array(n + 1);
100829     for (i = 1; i < n + 2; i++) {
100830         relation[i] = new Array(n + 1);
100831     }
100832     for (i = 1; i < n + 1; i++) {
100833         for (j = 1; j < n + 1; j++) {
100834             relation[i][j] = 0;
100835         }
100836     }
100837     for (i in colleages) {
100838         start = findIndexByStr(colleages[i].name1, locations);
100839         end = findIndexByStr(colleages[i].name2, locations);
100840         if (start !== -1 && end !== -1 && start !== end) {
100841             switch (goal) {
100842             case "distance":
100843                 relation[start][end] = colleages[i].distance;
100844                 relation[end][start] = colleages[i].distance;
100845                 break;
100846
100847             case "duration":
100848                 relation[start][end] = colleages[i].duration;
100849                 relation[end][start] = colleages[i].duration;
100850                 break;
100851
100852             case "simple":
100853                 relation[start][end] = 1;
100854                 relation[end][start] = 1;
100855                 break;
100856
100857             case "scenic":
100858                 if (colleages[i].addition.scenic === "SCENIC") {
100859                     relation[start][end] = 1;
100860                     relation[start][end] = 1;
100861                 } else if (colleages[i].addition.scenic === "") {
100862                     relation[start][end] = "MIN";
100863                     relation[start][end] = "MIN";
100864                 }
100865                 break;
100866
100867             case "cheap":
100868                 if (colleages[i].addition.toll === "TOLL") {
100869                     relation[start][end] = 1;
100870                     relation[end][start] = 1;
100871                 } else if (colleages[i].addition.toll === "") {
100872                     relation[start][end] = "MIN";
100873                     relation[start][end] = "MIN";
100874                 }
100875                 break;
100876
100877             case "safe":
100878                 if (colleages[i].addition.hazardous === "HAZARDOUS") {
100879                     relation[start][end] = 1;
100880                     relation[end][start] = 1;
100881                 } else if (colleages[i].addition.hazardous === "") {
100882                     relation[start][end] = "MIN";
100883                     relation[end][start] = "MIN";
100884                 }
100885                 break;
100886
100887             default:
100888                 return null;
100889             }
100890         }
100891     }
100892
100893     return relation;
100894 }
100895
100896 // Get the distance relationship among the locations
100897 function distanceRelation(n, colleages, locations) {
100898     return getRelation(n, colleages, locations, "distance");
100899 }
100900
100901 // Get the duration relationship among the locations
100902 function durationRelation(n, colleages, locations) {
100903     return getRelation(n, colleages, locations, "duration");
100904 }
100905
100906 // Get the simple relationship among the locations
100907 function simpleRelation(n, colleages, locations) {
100908     return getRelation(n, colleages, locations, "simple");
100909 }
100910
100911 // Get the cheap relationship among the locations
100912 function cheapRelation(n, colleages, locations) {
100913     return getRelation(n, colleages, locations, "cheap");
100914 }
100915
100916 // Get the safe relationship among the locations
100917 function safeRelation(n, colleages, locations) {
100918     return getRelation(n, colleages, locations, "safe");
100919 }
100920
100921 // Get the scenic relationship among the locations
100922 function scenicRelation(n, colleages, locations) {
100923     return getRelation(n, colleages, locations, "scenic");
100924 }
100925
100926 // Get the shortest way by origin, destination, locations and colleages
100927 function optimalWay(origin, destination, locations, colleages, relation) {
100928     var n = locations.length, i, steps = [], step, relations, routeLocations,
100929         originIndex, destinationIndex, startIndex, endIndex, colleageIndex,
100930         originLatitude, originLongitude, destinationLatitude, destinationLongitude,
100931         startLatitude, startLongitude, endLatitude, endLongitude,
100932         originLocation, destinationLocation, segment, result;
100933
100934     originLatitude = origin.latitude;
100935     originLongitude = origin.longitude;
100936     originIndex = searchIndexBycoodinates(originLatitude, originLongitude, locations);
100937
100938     destinationLatitude = destination.latitude;
100939     destinationLongitude = destination.longitude;
100940     destinationIndex = searchIndexBycoodinates(destinationLatitude, destinationLongitude, locations);
100941
100942     relations = relation(n, colleages, locations);
100943
100944     if (originIndex !== -1 && destinationIndex !== -1) {
100945         routeLocations = floyd(relations, n, parseInt(originIndex, 10), parseInt(destinationIndex, 10));
100946
100947         for (i = 0; i < routeLocations.length - 1; i++) {
100948             colleageIndex = findValueByStr(routeLocations[i], routeLocations[i + 1], locations, colleages);
100949
100950             if (colleageIndex !== -1) {
100951                 step = new RouteStep();
100952                 startIndex = parseInt(routeLocations[i], 10) - 1;
100953                 endIndex = parseInt(routeLocations[i + 1], 10) - 1;
100954
100955                 startLatitude = locations[startIndex].latitude;
100956                 startLongitude = locations[startIndex].longitude;
100957                 originLocation = new SimpleCoordinates(startLatitude, startLongitude);
100958
100959                 endLatitude = locations[endIndex].latitude;
100960                 endLongitude = locations[endIndex].longitude;
100961                 destinationLocation = new SimpleCoordinates(endLatitude, endLongitude);
100962
100963                 step.origin = originLocation;
100964                 step.destination = destinationLocation;
100965                 step.distance = colleages[colleageIndex].distance;
100966                 step.duration = colleages[colleageIndex].duration;
100967                 step.mode = colleages[colleageIndex].mode;
100968                 step.addition = colleages[colleageIndex].addition;
100969
100970                 steps.push(step);
100971             } else if (colleageIndex === -1) {
100972                 return null;
100973             }
100974         }
100975
100976         segment = new RouteSegment();
100977         segment.steps = steps;
100978         result = new RouteResult();
100979         result.segments[0] = segment;
100980
100981         return result;
100982     }
100983     return null;
100984 }
100985
100986 // Get the shortest way by origin, destination, locations and colleages
100987 function shortestWay(origin, destination, locations, colleages) {
100988     return optimalWay(origin, destination, locations, colleages, distanceRelation);
100989 }
100990
100991 // Get the fastest way by origin, destination, locations and colleages
100992 function fastestWay(origin, destination, locations, colleages) {
100993     return optimalWay(origin, destination, locations, colleages, durationRelation);
100994 }
100995
100996 // Get the simplest way by origin, destination, locations and colleages
100997 function simplestWay(origin, destination, locations, colleages) {
100998     return optimalWay(origin, destination, locations, colleages, simpleRelation);
100999 }
101000
101001 // Get the most scenic way by origin, destination, locations and colleages
101002 function mostScenicWay(origin, destination, locations, colleages) {
101003     return optimalWay(origin, destination, locations, colleages, scenicRelation);
101004 }
101005
101006 // Get the cheapest way by origin, destination, locations and colleages
101007 function cheapestWay(origin, destination, locations, colleages) {
101008     return optimalWay(origin, destination, locations, colleages, cheapRelation);
101009 }
101010
101011 // Get the safest way by origin, destination, locations and colleages
101012 function safestWay(origin, destination, locations, colleages) {
101013     return optimalWay(origin, destination, locations, colleages, safeRelation);
101014 }
101015
101016 // Uniquelize the array
101017 function uniquelize(array) {
101018     var temp = {}, result = [], i;
101019     for (i = array.length; i--;) {
101020         temp[array[i]] = array[i];
101021     }
101022     for (i in temp) {
101023         result.push(temp[i]);
101024     }
101025     return result;
101026 }
101027
101028 // Is it intersect between the Array a and b
101029 function intersect(a, b) {
101030     var i, j;
101031
101032     a = uniquelize(a);
101033     if (a.length === 0 && b.length === 0) {
101034         return true;
101035     }
101036     for (i in a) {
101037         for (j in b) {
101038             if (a[i] === b[j])
101039                 return true;
101040         }
101041     }
101042     return false;
101043 }
101044
101045 function getConstrains(result) {
101046     var steps = result.segments[0].steps, constrains = [];
101047
101048     utils.forEach(steps, function (item, index) {
101049         if (item.addition.highway === "HIGHWAY") {
101050             constrains.push("HIGHWAY");
101051         }
101052         if (item.addition.toll === "TOLL") {
101053             constrains.push("TOLL");
101054         }
101055         if (item.addition.bridge === "BRIDGE") {
101056             constrains.push("BRIDGE");
101057         }
101058         if (item.addition.hazardous === "HAZARDOUS") {
101059             constrains.push("HAZARDOUS");
101060         }
101061         if (item.addition.scenic === "SCENIC") {
101062             constrains.push("SCENIC");
101063         }
101064     });
101065     if (constrains.length > 0) {
101066         return uniquelize(constrains);
101067     }
101068     return constrains;
101069 }
101070
101071 module.exports = function (prop) {
101072     var _self = new lbs.LocationServiceProvider(prop);
101073     _self.find = function (origin, destination, successCallback, errorCallback, options) {
101074         function _find() {
101075             var locations, colleages, i, result = {}, emptyResult = [], modes = [], resultModes = [], constrains = [], resultconstrains = [];
101076
101077             locations = db.retrieveObject(_data.DB_ROUTE_LOCATION_KEY);
101078             colleages = db.retrieveObject(_data.DB_ROUTE_COLLEAGE_KEY);
101079
101080             modes = options.modes;
101081             constrains = options.constrains;
101082             if (locations.length > 0 && colleages.length > 0) {
101083                 switch (options.routeGoal) {
101084                 case "SHORTEST":
101085                     result = shortestWay(origin, destination, locations, colleages);
101086                     break;
101087
101088                 case "FASTEST":
101089                     result = fastestWay(origin, destination, locations, colleages);
101090                     break;
101091
101092                 case "SIMPLEST":
101093                     result = simplestWay(origin, destination, locations, colleages);
101094                     break;
101095
101096                 case "MOST_SCENIC":
101097                     result = mostScenicWay(origin, destination, locations, colleages);
101098                     break;
101099
101100                 case "CHEAPEST":
101101                     result = cheapestWay(origin, destination, locations, colleages);
101102                     break;
101103
101104                 case "SAFEST":
101105                     result = safestWay(origin, destination, locations, colleages);
101106                     break;
101107
101108                 default:
101109                     result = shortestWay(origin, destination, locations, colleages);
101110                     break;
101111                 }
101112                 if (result !== null) {
101113                     for (i in result.segments[0].steps) {
101114                         resultModes.push(result.segments[0].steps[i].mode);
101115                     }
101116                     resultconstrains = getConstrains(result);
101117                     if (intersect(resultModes, modes) && intersect(resultconstrains, constrains)) {
101118                         successCallback(result);
101119                     } else {
101120                         successCallback(null);
101121                     }
101122                 }
101123             } else {
101124                 successCallback(emptyResult);
101125             }
101126         }
101127         tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find);
101128     };
101129     return _self;
101130 };
101131
101132 });
101133 define('ripple/platform/tizen/2.0/routeBackend_navigation', function (require, exports, module) {
101134 /*
101135  *  Copyright 2012 Intel Corporation.
101136  *
101137  * Licensed under the Apache License, Version 2.0 (the "License");
101138  * you may not use this file except in compliance with the License.
101139  * You may obtain a copy of the License at
101140  *
101141  * http://www.apache.org/licenses/LICENSE-2.0
101142  *
101143  * Unless required by applicable law or agreed to in writing, software
101144  * distributed under the License is distributed on an "AS IS" BASIS,
101145  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
101146  * See the License for the specific language governing permissions and
101147  * limitations under the License.
101148  */
101149
101150 var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
101151     lbs_utils = require('ripple/platform/tizen/2.0/lbs_utils'),
101152     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
101153     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
101154     SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
101155     RouteWaypoint,
101156     RouteDistance,
101157     RouteDuration,
101158     RouteStep,
101159     RouteSegment,
101160     RouteRequestOptions,
101161     RouteResultSummary,
101162     RouteResult,
101163     _data = {
101164         positionDistance: {},
101165         positionDuration: {},
101166         routeProvider: {},
101167         routes: [],
101168         RouteDistanceUnit: ["M", "KM", "MI", "FT"],
101169         providers: [],
101170         path: []
101171     },
101172     _self;
101173
101174 // The RouteWaypoint object
101175 RouteWaypoint = function () {
101176     return {
101177         position: {
101178             latitude: 0,
101179             longitude: 0
101180         },
101181         isStopover: true
101182     };
101183 };
101184
101185 // The RouteDistance object
101186 RouteDistance = function () {
101187     return {
101188         text : "Distance",
101189         value : "0",
101190         unit : "KM "
101191     };
101192 };
101193
101194 // The RouteDuration object
101195 RouteDuration = function () {
101196     return {
101197         text : "Duration",
101198         value : "0" // The duration in a seconds
101199     };
101200 };
101201
101202 // The RouteStep object
101203 RouteStep = function () {
101204     var _self = {
101205         mode: "",        // The way of the travel, for example: car, bike, foot
101206         instruction: "", // The instruction of this step
101207         points: []       // The points of this step
101208     };
101209
101210     _self.origin      = new SimpleCoordinates(0, 0);
101211     _self.destination = new SimpleCoordinates(0, 0);
101212     _self.distance    = new RouteDistance();
101213     _self.duration    = new RouteDuration();
101214
101215     return _self;
101216 };
101217 // The RouteSegment object
101218 RouteSegment = function () {
101219     var _self = {
101220         steps: []
101221     };
101222
101223     _self.origin      = new SimpleCoordinates(0, 0);
101224     _self.destination = new SimpleCoordinates(0, 0);
101225     _self.distance    = new RouteDistance();
101226     _self.duration    = new RouteDuration();
101227
101228     return _self;
101229 };
101230
101231 // The RouteRequestOptions object
101232 RouteRequestOptions = function () {
101233     return {
101234         mode: "", // CAR, BIKE
101235         unit: "KM",
101236         routeGoal: "SHORTEST",
101237         constraints: ["HIGHWAY", "TOLL", "UNPAVED"],
101238         wayPoints: [],
101239         maxResults: 1
101240     };
101241 };
101242
101243 // The RouteResultSummary object
101244 RouteResultSummary = function () {
101245     var _self = {};
101246
101247     _self.origin        = new SimpleCoordinates(0, 0);
101248     _self.destination   = new SimpleCoordinates(0, 0);
101249     _self.totalDistance = new RouteDistance();
101250     _self.totalDuration = new RouteDuration();
101251
101252     return _self;
101253 };
101254
101255 // The RouteResult object
101256 RouteResult = function () {
101257     var _self, jsonStr, jsonObj;
101258     jsonObj = {
101259             "type" : "Point",
101260             "coordinates" : []
101261         };
101262     jsonStr = JSON.stringify(jsonObj);
101263     _self = {
101264         segments : [],
101265         toGeoJSON : function () {
101266                 return jsonStr;
101267             }
101268     };
101269     _self.summary = new RouteResultSummary();
101270     return _self;
101271 };
101272
101273 function calcDegree(distance) {
101274     return distance * Math.PI / 180.0;
101275 }
101276
101277 //calcute the distance
101278 function  calculateDistance(lat1, lat2, lon1, lon2) {
101279     var R = 6371, dLat, dLon, a, c, distance; // km
101280     dLat = calcDegree(parseFloat(lat2) - parseFloat(lat1));
101281     dLon = calcDegree(parseFloat(lon2) - parseFloat(lon1));
101282
101283     lat1 = calcDegree(lat1);
101284     lat2 = calcDegree(lat2);
101285
101286     a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
101287              Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
101288     c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
101289     distance = R * c;
101290     return distance;
101291 }
101292
101293 function calculateDuration(mode, distance) {
101294     var duration, v;
101295     switch (mode) {
101296     case "motorcar" :
101297         v = 50;
101298         duration = distance / v;
101299         break;
101300     case "bicycle" :
101301         v = 20;
101302         duration = distance / v;
101303         break;
101304     case "foot" :
101305         v = 5;
101306         duration = distance / v;
101307         break;
101308     default:
101309         duration = 0;
101310     }
101311     return duration;
101312 }
101313
101314 function optimalWay(points, mode) {
101315     var steps = [], startLatitude, startLongitude, originLocation, endLatitude, endLongitude,
101316     destinationLocation, step, distance, i, routeDistance, routeDuration;
101317     for (i = 0;i < points.length - 1;i++) {
101318         startLatitude       = points[i].lat;
101319         startLongitude      = points[i].lon;
101320         originLocation      = new SimpleCoordinates(startLatitude, startLongitude);
101321         endLatitude         = points[i + 1].lat;
101322         endLongitude        = points[i + 1].lon;
101323         destinationLocation = new SimpleCoordinates(endLatitude, endLongitude);
101324         step                = new RouteStep();
101325         step.origin         = originLocation;
101326         step.destination    = destinationLocation;
101327         distance            = calculateDistance(startLatitude, endLatitude, startLongitude, endLongitude);
101328         routeDistance       = new RouteDistance();
101329         routeDistance.value = distance;
101330         routeDistance.unit  = "km";
101331         step.distance       = routeDistance;
101332         routeDuration       = new RouteDuration();
101333         routeDuration.value = calculateDuration(mode, distance);
101334         step.duration       = routeDuration;
101335         steps.push(step);
101336     }
101337     return steps;
101338 }
101339
101340 function existInSupports(str, array) {
101341     for (var i in array) {
101342         if (str === array[i]) {
101343             return true;
101344         }
101345     }
101346     return false;
101347 }
101348
101349 function navigation(searchStr, flat, flon, tlat, tlon, v, fast) {
101350     var positions = [];
101351
101352     _data.positionDistance = {};
101353     _data.positionDuration = {};
101354     jQuery.ajax({
101355         type : "get",
101356         async : false,
101357         url : searchStr,
101358         data : {
101359             flat : flat,
101360             flon : flon,
101361             tlat : tlat,
101362             tlon : tlon,
101363             v : v,
101364             fast : fast,
101365             layer : 'mapnik',
101366             format : "geojson"
101367         },
101368         contentType : "application/json; charset=utf-8",
101369         dataType : "json",
101370         cache : false,
101371         success : function (data) {
101372             $.each(data.coordinates, function (i, item) {
101373                 var point = {};
101374                 point.lon = item[0];
101375                 point.lat = item[1];
101376                 positions.push(point);
101377             });
101378             $.each(data.properties, function (i, item) {
101379                 if (typeof item === "number") {
101380                     _data.positionDistance = new RouteDistance();
101381                     _data.positionDistance.value = item;
101382                     _data.positionDistance.unit = "km";
101383                     _data.positionDuration = new RouteDuration();
101384                     _data.positionDuration.value = calculateDuration(v, item);
101385                 }
101386             });
101387         },
101388         error : function (errorCB) {
101389             if (errorCB) {
101390                 setTimeout(function () {
101391                     errorCB(new WebAPIError(errorcode.NETWORK_ERR));
101392                 }, 1);
101393             }
101394         }
101395     });
101396     return positions;
101397 }
101398
101399
101400 function filterWaypoints(routeWaypoints) {
101401     var mathWaypoints = [], i;
101402     for (i in routeWaypoints) {
101403         if (routeWaypoints[i].position.latitude !== "" &&
101404             routeWaypoints[i].position.latitude !== undefined &&
101405             routeWaypoints[i].position.latitude !== null &&
101406             routeWaypoints[i].position.longitude !== null &&
101407             routeWaypoints[i].position.longitude !== "" &&
101408             routeWaypoints[i].position.longitude !== undefined) {
101409             mathWaypoints.push(routeWaypoints[i]);
101410         }
101411     }
101412     return mathWaypoints;
101413 }
101414
101415 module.exports = function (prop) {
101416     var _self = new lbs_utils.LocationServiceProvider(prop);
101417
101418     _self.supportedGoals       = ["SHORTEST", "FASTEST", "MOST_SCENIC", "SIMPLEST", "CHEAPEST", "SAFEST" ];
101419     _self.supportedModes       = ["motorcar", "bicycle", "foot"];
101420     _self.supportedConstraints = ["HIGHWAY", "TOLL", "UNPAVED", "BORDER", "GRAVEL_PAVING", "TUNNEL", "BRIDGE", "LEFT_TURN", "CARPOOL", "HAZARDOUS_CARGO" ];
101421     _self.supportsWayPoints    = true;
101422     _self.find = function (origin, destination, successCallback, errorCallback, options) {
101423         function _find() {
101424             var flat, flon, tlat, tlon, v, fast, searchStr, result,
101425                 routeWaypoints = [],
101426                 segmentPositions = [],
101427                 positions = [],
101428                 segments = [],
101429                 totalDistances = 0, totalDurations = 0,
101430                 k, key, segment, startPosition, endPosition,
101431                 summary, distance, duration;
101432
101433             v = options.mode;
101434             //init
101435             if (!existInSupports(v, _self.supportedModes)) {
101436                 throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
101437             }
101438             if (!existInSupports(options.routeGoal, _self.supportedGoals)) {
101439                 throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
101440             }
101441             switch (options.routeGoal) {
101442             case "SHORTEST":
101443                 fast = 0;
101444                 break;
101445
101446             case "FASTEST":
101447                 fast = 1;
101448                 break;
101449
101450             case "SIMPLEST":
101451                 break;
101452
101453             case "MOST_SCENIC":
101454                 break;
101455
101456             case "CHEAPEST":
101457                 break;
101458
101459             case "SAFEST":
101460                 break;
101461
101462             default:
101463                 fast = 0;
101464             }
101465             searchStr      = "http://www.yournavigation.org/api/dev/gosmore.php";
101466             routeWaypoints = options.wayPoints;
101467             routeWaypoints = filterWaypoints(routeWaypoints);
101468             segmentPositions.push(origin);
101469
101470             if (routeWaypoints.length > 0) {
101471                 for (k in routeWaypoints) {
101472                     segmentPositions.push(routeWaypoints[k].position);
101473                 }
101474             }
101475             segmentPositions.push(destination);
101476
101477             for (key = 0; key < segmentPositions.length - 1; key++) {
101478                 segment             = new RouteSegment();
101479                 startPosition       = segmentPositions[key];
101480                 endPosition         = segmentPositions[key + 1];
101481                 segment.origin      = startPosition;
101482                 segment.destination = endPosition;
101483                 flat                = startPosition.latitude;
101484                 flon                = startPosition.longitude;
101485                 tlat                = endPosition.latitude;
101486                 tlon                = endPosition.longitude;
101487                 positions           = navigation(searchStr, flat, flon, tlat, tlon, v, fast);
101488                 segment.steps       = optimalWay(positions, v);
101489                 segment.distance    = _data.positionDistance;
101490                 totalDistances     += _data.positionDistance.value;
101491                 segment.duration    = _data.positionDuration;
101492                 totalDurations     += _data.positionDuration.value;
101493                 segments.push(segment);
101494             }
101495             result                = new RouteResult();
101496             summary               = new RouteResultSummary();
101497             summary.origin        = segmentPositions[0];
101498             summary.destination   = segmentPositions[segmentPositions.length - 1];
101499             distance              = new RouteDistance();
101500             distance.value        = totalDistances;
101501             distance.unit         = "km";
101502             summary.totalDistance = distance;
101503             duration              = new RouteDuration();
101504             duration.value        = totalDurations;
101505             summary.totalDuration = duration;
101506             result.segments       = segments;
101507             result.summary        = summary;
101508             successCallback(result);
101509         }
101510
101511         tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find);
101512     };
101513
101514     return _self;
101515 };
101516
101517 });
101518 define('ripple/platform/tizen/2.0/sensors', function (require, exports, module) {
101519 /*
101520  *  Copyright 2012 Intel Corporation.
101521  *
101522  * Licensed under the Apache License, Version 2.0 (the "License");
101523  * you may not use this file except in compliance with the License.
101524  * You may obtain a copy of the License at
101525  *
101526  * http://www.apache.org/licenses/LICENSE-2.0
101527  *
101528  * Unless required by applicable law or agreed to in writing, software
101529  * distributed under the License is distributed on an "AS IS" BASIS,
101530  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
101531  * See the License for the specific language governing permissions and
101532  * limitations under the License.
101533  */
101534
101535 var utils = require('ripple/utils'),
101536     sensors = require('ripple/platform/tizen/2.0/spec/sensor'),
101537     _sensors = ["Accelerometer", "MagneticField", "Rotation", "Orientation"],
101538     _permission = true,
101539     _isWriteable = false,
101540     _self;
101541
101542 function SensorError(code, msg) {
101543     this.__defineGetter__("message", function () {
101544         return msg;
101545     });
101546     this.__defineGetter__("code", function () {
101547         return code;
101548     });
101549
101550     this.PERMISSION_DENIED = -100;
101551 }
101552
101553 function SensorRequest() {
101554     var _self = {
101555         result: [],
101556         error: null,
101557         readyState: "processing"
101558     };
101559
101560     this.__defineGetter__("result", function () {
101561         return _self.result;
101562     });
101563     this.__defineSetter__("result", function (resultData) {
101564         if (_isWriteable) {
101565             _self.result = utils.copy(resultData);
101566             _isWriteable = false;
101567             return;
101568         }
101569     });
101570
101571     this.__defineGetter__("error", function () {
101572         return _self.error;
101573     });
101574     this.__defineSetter__("error", function (errorData) {
101575         if (_isWriteable) {
101576             _self.error = utils.copy(errorData);
101577             _isWriteable = false;
101578             return;
101579         }
101580     });
101581
101582     this.__defineGetter__("readyState", function () {
101583         return _self.readyState;
101584     });
101585     this.__defineSetter__("readyState", function (readyStateData) {
101586         if (_isWriteable) {
101587             _self.readyState = readyStateData;
101588             _isWriteable = false;
101589             return;
101590         }
101591     });
101592 }
101593
101594 _self = {
101595     findSensors: function (type) {
101596         var sensorRequest = new SensorRequest(), index, sensorName = "";
101597
101598         setTimeout(function () {
101599             if (_permission) {
101600                 for (index = 0; index < _sensors.length; index++) {
101601                     sensorName = _sensors[index];
101602                     if (type === null || type === undefined || type === sensorName) {
101603                         _isWriteable = true;
101604                         sensorRequest.result.push(sensors[sensorName]);
101605                     }
101606                 }
101607
101608                 _isWriteable = true;
101609                 sensorRequest.readyState = "done";
101610
101611                 if (sensorRequest.onsuccess) {
101612                     sensorRequest.onsuccess();
101613                 }
101614             }
101615             else {
101616                 // error event on the request with error code PERMISSION_DENIED must be fired.
101617                 sensorRequest.error = new SensorError(-100, "permission denied!");
101618                 if (sensorRequest.onerror) {
101619                     sensorRequest.onerror();
101620                 }
101621             }
101622         }, 1);
101623
101624         return sensorRequest;
101625     }
101626 };
101627
101628 module.exports = _self;
101629
101630
101631 });
101632 define('ripple/platform/tizen/2.0/spec/config', function (require, exports, module) {
101633 /*
101634  *  Copyright 2011 Research In Motion Limited.
101635  *  Copyright 2011 Intel Corporation.
101636  *
101637  * Licensed under the Apache License, Version 2.0 (the "License");
101638  * you may not use this file except in compliance with the License.
101639  * You may obtain a copy of the License at
101640  *
101641  * http://www.apache.org/licenses/LICENSE-2.0
101642  *
101643  * Unless required by applicable law or agreed to in writing, software
101644  * distributed under the License is distributed on an "AS IS" BASIS,
101645  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
101646  * See the License for the specific language governing permissions and
101647  * limitations under the License.
101648  */
101649 var utils = require('ripple/utils'),
101650     db = require('ripple/db'),
101651     constants = require('ripple/constants');
101652
101653 module.exports = {
101654     fileName: "config.xml",
101655     validateVersion: function (configValidationObject) {
101656         var valid = true;
101657         // no xmlns:JIL in wac 2.0 spec
101658         valid = !!configValidationObject.widget.validationResult[0].attributes.xmlns.valid;
101659
101660         return valid;
101661     },
101662     extractInfo: function (configValidationObject) {
101663         if (!configValidationObject) {
101664             return null;
101665         }
101666
101667         var widgetInfo = {},
101668             configFeatures,
101669             configPreferences,
101670             preferenceName,
101671             platform, rst, i, j,
101672             settingRst = {
101673                 'screen-orientation': 'portrait',
101674                 'context-menu': 'enable',
101675                 'background-support': 'disable',
101676                 encryption: 'disable',
101677                 'install-location': 'auto',
101678                 'hwkey-event': 'enable'
101679             };
101680
101681         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
101682         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
101683         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
101684         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
101685         if (configValidationObject.widget.children.application.validationResult[0].valid) {
101686             widgetInfo.tizenAppId = configValidationObject.widget.children.application.validationResult[0].attributes.id.value;
101687             widgetInfo.tizenPackageId = configValidationObject.widget.children.application.validationResult[0].attributes.package.value;
101688         }
101689
101690         widgetInfo.features = {};
101691
101692         if (configValidationObject.widget.children.setting.hasOwnProperty('validationResult') === true) {
101693             rst = configValidationObject.widget.children.setting.validationResult;
101694             // the first one has higher priority per platform implementation
101695             for (i = rst.length -1 ; i >= 0; i--) {
101696                 if (rst[i].valid === true) {
101697                     for (j in rst[i].attributes) {
101698                         if (rst[i].attributes[j].value !== undefined) {
101699                             settingRst[j] = rst[i].attributes[j].value;
101700                         }
101701                     }
101702                 }
101703             }
101704             db.save("layout", settingRst["screen-orientation"]);
101705         }
101706
101707         configFeatures = configValidationObject.widget.children.feature.validationResult;
101708         utils.forEach(configFeatures, function (f) {
101709             if (f.valid === true) {
101710                 var feature = {id: f.attributes.name.value,
101711                          required: f.attributes.required.valid};
101712                 widgetInfo.features[feature.id] = feature;
101713             }
101714         });
101715
101716         widgetInfo.preferences = {};
101717
101718         configPreferences = configValidationObject.widget.children.preference.validationResult;
101719
101720         platform = require('ripple/platform');
101721         utils.forEach(configPreferences, function (preference) {
101722             preferenceName = preference.attributes.name.value;
101723             if (preferenceName) {
101724                 widgetInfo.preferences[preferenceName] = {
101725                     "key": preferenceName,
101726                     "value": preference.attributes.value.value || "",
101727                     "readonly": preference.attributes.readonly.value === "true"
101728                 };
101729
101730                 db.save(preferenceName,
101731                         widgetInfo.preferences[preferenceName].value,
101732                         platform.getPersistencePrefix(widgetInfo.id));
101733             }
101734         });
101735
101736         return widgetInfo;
101737     },
101738     schema: {
101739         rootElement: "widget",
101740         widget: {
101741             nodeName: "widget",
101742             required: true,
101743             occurrence: 1,
101744             helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in the configuration document and may have the following child elments: name,description,icon,author,license,content,feature and preference.The \"widget\" element MAY have following attributes: id,version,height,width, defaultlocale, xml:lang and dir",
101745             attributes: {
101746                 xmlns: {
101747                     attributeName: "xmlns",
101748                     required: true,
101749                     type: "list",
101750                     listValues: ["http://www.w3.org/ns/widgets"]
101751                 },
101752                 "xmlns:tizen": {
101753                     attributeName: "xmlns:tizen",
101754                     required: false,
101755                     type: "list",
101756                     listValues: ["http://tizen.org/ns/widgets"]
101757                 },
101758                 "xml:lang": {
101759                     attributeName: "xml:lang",
101760                     required: false,
101761                     type: "iso-language"
101762                 },
101763                 dir: {
101764                     attributeName: "dir",
101765                     required: false,
101766                     type: "list",
101767                     listValues: ["ltr", "rtl", "lro", "rlo"]
101768                 },
101769                 id: {
101770                     attributeName: "id",
101771                     required: false,
101772                     type: "string"
101773                 },
101774                 version: {
101775                     attributeName: "version",
101776                     required: false,
101777                     type: "string"
101778                 },
101779                 height: {
101780                     attributeName: "height",
101781                     required: false,
101782                     type: "integer"
101783                 },
101784                 width: {
101785                     attributeName: "width",
101786                     required: false,
101787                     type: "integer"
101788                 },
101789                 viewmodes: {
101790                     attributeName: "viewmodes",
101791                     required: false,
101792                     type: "list",
101793                     listValues: ["windowed", "floating", "fullscreen", "maximized", "minimized"]
101794                 },
101795                 defaultlocale: {
101796                     attributeName: "defaultlocale",
101797                     required: false,
101798                     type: "iso-language"
101799                 },
101800             },
101801             children: {
101802                 name: {
101803                     nodeName: "name",
101804                     required: false,
101805                     occurrence: 0,
101806                     type: "string",
101807                     attributes: {
101808                         "xml:lang": {
101809                             attributeName: "xml:lang",
101810                             required: false,
101811                             type: "iso-language",
101812                             unique: true
101813                         },
101814                         dir: {
101815                             attributeName: "dir",
101816                             required: false,
101817                             type: "list",
101818                             listValues: ["ltr", "rtl", "lro", "rlo"]
101819                         },
101820                         "short": {
101821                             attributeName: "short",
101822                             required: false,
101823                             type: "string"
101824                         }
101825                     },
101826                     children: {
101827                         span: {
101828                             nodeName: "span",
101829                             required: false,
101830                             type: "string",
101831                             attributes: {
101832                                 "xml:lang": {
101833                                     attributeName: "xml:lang",
101834                                     required: false,
101835                                     type: "iso-language",
101836                                     unique: true
101837                                 },
101838                                 dir: {
101839                                     attributeName: "dir",
101840                                     required: false,
101841                                     type: "list",
101842                                     listValues: ["ltr", "rtl", "lro", "rlo"]
101843                                 }
101844                             }
101845                         }
101846                     }
101847                 },
101848                 description: {
101849                     nodeName: "description",
101850                     required: false,
101851                     occurrence: 0,
101852                     type: "string",
101853                     attributes: {
101854                         "xml:lang": {
101855                             attributeName: "xml:lang",
101856                             required: false,
101857                             type: "iso-language",
101858                             unique: true
101859                         },
101860                         dir: {
101861                             attributeName: "dir",
101862                             required: false,
101863                             type: "list",
101864                             listValues: ["ltr", "rtl", "lro", "rlo"]
101865                         }
101866                     },
101867                     children: {
101868                         span: {
101869                             nodeName: "span",
101870                             required: false,
101871                             type: "string",
101872                             attributes: {
101873                                 "xml:lang": {
101874                                     attributeName: "xml:lang",
101875                                     required: false,
101876                                     type: "iso-language",
101877                                     unique: true
101878                                 },
101879                                 dir: {
101880                                     attributeName: "dir",
101881                                     required: false,
101882                                     type: "list",
101883                                     listValues: ["ltr", "rtl", "lro", "rlo"]
101884                                 }
101885                             }
101886                         }
101887                     }
101888                 },
101889                 author: {
101890                     nodeName: "author",
101891                     required: false,
101892                     occurrence: 0,
101893                     type: "string",
101894                     attributes: {
101895                         "xml:lang": {
101896                             attributeName: "xml:lang",
101897                             required: false,
101898                             type: "iso-language",
101899                         },
101900                         dir: {
101901                             attributeName: "dir",
101902                             required: false,
101903                             type: "list",
101904                             listValues: ["ltr", "rtl", "lro", "rlo"]
101905                         },
101906                         href: {
101907                             attributeName: "href",
101908                             required: false,
101909                             type: "regex",
101910                             regex: constants.REGEX.URL
101911                         },
101912                         email: {
101913                             attributeName: "email",
101914                             required: false,
101915                             type: "regex",
101916                             regex: constants.REGEX.EMAIL
101917                         }
101918                     },
101919                     children: {
101920                         span: {
101921                             nodeName: "span",
101922                             required: false,
101923                             type: "string",
101924                             attributes: {
101925                                 "xml:lang": {
101926                                     attributeName: "xml:lang",
101927                                     required: false,
101928                                     type: "iso-language",
101929                                     unique: true
101930                                 },
101931                                 dir: {
101932                                     attributeName: "dir",
101933                                     required: false,
101934                                     type: "list",
101935                                     listValues: ["ltr", "rtl", "lro", "rlo"]
101936                                 }
101937                             }
101938                         }
101939                     }
101940                 },
101941                 license: {
101942                     nodeName: "license",
101943                     required: false,
101944                     occurrence: 0,
101945                     type: "string",
101946                     attributes: {
101947                         "xml:lang": {
101948                             attributeName: "xml:lang",
101949                             required: false,
101950                             type: "iso-language",
101951                         },
101952                         dir: {
101953                             attributeName: "dir",
101954                             required: false,
101955                             type: "list",
101956                             listValues: ["ltr", "rtl", "lro", "rlo"]
101957                         },
101958                         href: {
101959                             attributeName: "href",
101960                             type: "regex",
101961                             required: false,
101962                             regex: constants.REGEX.URL
101963                         }
101964                     },
101965                     children: {
101966                         span: {
101967                             nodeName: "span",
101968                             required: false,
101969                             type: "string",
101970                             attributes: {
101971                                 "xml:lang": {
101972                                     attributeName: "xml:lang",
101973                                     required: false,
101974                                     type: "iso-language",
101975                                     unique: true
101976                                 },
101977                                 dir: {
101978                                     attributeName: "dir",
101979                                     required: false,
101980                                     type: "list",
101981                                     listValues: ["ltr", "rtl", "lro", "rlo"]
101982                                 }
101983                             }
101984                         }
101985                     }
101986                 },
101987                 icon: {
101988                     nodeName: "icon",
101989                     required: false,
101990                     occurrence: 0,
101991                     attributes: {
101992                         "xml:lang": {
101993                             attributeName: "xml:lang",
101994                             required: false,
101995                             type: "iso-language",
101996                         },
101997                         dir: {
101998                             attributeName: "dir",
101999                             required: false,
102000                             type: "list",
102001                             listValues: ["ltr", "rtl", "lro", "rlo"]
102002                         },
102003                         src: {
102004                             attributeName: "src",
102005                             required: true,
102006                             type: "string"
102007                         },
102008                         width: {
102009                             attributeName: "width",
102010                             required: false,
102011                             type: "integer"
102012                         },
102013                         height: {
102014                             attributeName: "height",
102015                             required: false,
102016                             type: "integer"
102017                         }
102018                     }
102019                 },
102020                 content: {
102021                     nodeName: "content",
102022                     required: false,
102023                     occurrence: 1,
102024                     attributes: {
102025                         "xml:lang": {
102026                             attributeName: "xml:lang",
102027                             required: false,
102028                             type: "iso-language",
102029                             unique: true
102030                         },
102031                         dir: {
102032                             attributeName: "dir",
102033                             required: false,
102034                             type: "list",
102035                             listValues: ["ltr", "rtl", "lro", "rlo"]
102036                         },
102037                         src: {
102038                             attributeName: "src",
102039                             required: true,
102040                             type: "string"
102041                         },
102042                         encoding: {
102043                             attributeName: "encoding",
102044                             required: false,
102045                             type: "string"
102046                         },
102047                         type: {
102048                             attributeName: "type",
102049                             required: false,
102050                             type: "string"
102051                         }
102052                     }
102053                 },
102054                 setting: {
102055                     nodeName: "tizen:setting",
102056                     required: false,
102057                     occurrence: 0,
102058                     attributes: {
102059                         'screen-orientation': {
102060                             attributeName: "screen-orientation",
102061                             required: false,
102062                             type: "list",
102063                             listValues: ['portrait', 'landscape', 'auto']
102064                         },
102065                         'context-menu': {
102066                             attributeName: "context-menu",
102067                             required: false,
102068                             type: "list",
102069                             listValues: ['enable', 'disable']
102070                         },
102071                         'background-support': {
102072                             attributeName: "background-support",
102073                             required: false,
102074                             type: "list",
102075                             listValues: ['enable', 'disable']
102076                         },
102077                         'encryption': {
102078                             attributeName: "encryption",
102079                             required: false,
102080                             type: "list",
102081                             listValues: ['enable', 'disable']
102082                         },
102083                         'install-location': {
102084                             attributeName: "install-location",
102085                             required: false,
102086                             type: "list",
102087                             listValues: ['auto', 'internal-only', 'perfer-external']
102088                         },
102089                         'hwkey-event': {
102090                             attributeName: "hwkey-event",
102091                             required: false,
102092                             type: "list",
102093                             listValues: ['enable', 'disable']
102094                         }
102095                     }
102096                 },
102097                 application: {
102098                     nodeName: "tizen:application",
102099                     required: true,
102100                     occurrence: 1,
102101                     attributes: {
102102                         id: {
102103                             attributeName: "id",
102104                             required: true,
102105                             type: "string"
102106                         },
102107                         required_version: {
102108                             attributeName: "required_version",
102109                             required: true,
102110                             type: "list",
102111                             listValues: ['1.0', '2.0', '2.1', '2.2']
102112                         },
102113                         package: {
102114                             attributeName: "package",
102115                             required: false,
102116                             type: "string"
102117                         }
102118                     }
102119                 },
102120                 "tizen:content": {
102121                     nodeName: "tizen:content",
102122                     required: false,
102123                     occurrence: 1,
102124                     attributes: {
102125                         src: {
102126                             attributeName: "src",
102127                             required: true,
102128                             type: "string"
102129                         }
102130                     }
102131                 },
102132                 control: {
102133                     nodeName: "tizen:app-control",
102134                     required: false,
102135                     occurrence: 0,
102136                     children: {
102137                         src: {
102138                             nodeName: "tizen:src",
102139                             required: true,
102140                             occurence: 0,
102141                             attributes: {
102142                                 name: {
102143                                     attributeName: "name",
102144                                     required: false,
102145                                     type: "string"
102146                                 }
102147                             }
102148                         },
102149                         operation: {
102150                             nodeName: "tizen:operation",
102151                             required: true,
102152                             occurence: 0,
102153                             attributes: {
102154                                 name: {
102155                                     attributeName: "name",
102156                                     required: false,
102157                                     type: "string"
102158                                 }
102159                             }
102160                         },
102161                         uri: {
102162                             nodeName: "tizen:uri",
102163                             required: false,
102164                             occurence: 0,
102165                             attributes: {
102166                                 name: {
102167                                     attributeName: "name",
102168                                     required: false,
102169                                     type: "string"
102170                                 }
102171                             }
102172                         },
102173                         mime: {
102174                             nodeName: "tizen:mime",
102175                             required: false,
102176                             occurence: 0,
102177                             attributes: {
102178                                 name: {
102179                                     attributeName: "name",
102180                                     required: false,
102181                                     type: "string"
102182                                 }
102183                             }
102184                         }
102185                     }
102186                 },
102187                 "app-widget": {
102188                     nodeName: "tizen:app-widget",
102189                     required: false,
102190                     occurrence: 0,
102191                     attributes: {
102192                         id: {
102193                             attributeName: "id",
102194                             required: true,
102195                             type: "string"
102196                         },
102197                         primary: {
102198                             attributeName: "primary",
102199                             required: true,
102200                             type: "list",
102201                             listValues: ['true', 'false']
102202                         },
102203                         "auto-launch": {
102204                             attributeName: "auto-launch",
102205                             required: false,
102206                             type: "list",
102207                             listValues: ['true', 'false']
102208                         },
102209                         "update-period": {
102210                             attributeName: "update-period",
102211                             required: false,
102212                             type: "integer"
102213                         }
102214                     },
102215                     children: {
102216                         "box-label": {
102217                             nodeName: "tizen:box-label",
102218                             required: true,
102219                             occurence: 1
102220                         },
102221                         "box-icon": {
102222                             nodeName: "tizen:box-icon",
102223                             required: true,
102224                             occurence: 1,
102225                             attributes: {
102226                                 src: {
102227                                     attributeName: "src",
102228                                     required: true,
102229                                     type: "string"
102230                                 }
102231                             }
102232                         },
102233                         "box-content": {
102234                             nodeName: "tizen:box-content",
102235                             required: true,
102236                             occurence: 1,
102237                             attributes: {
102238                                 src: {
102239                                     attributeName: "src",
102240                                     required: true,
102241                                     type: "string"
102242                                 },
102243                                 "mouse-event": {
102244                                     attributeName: "mouse-event",
102245                                     required: false,
102246                                     type: "string"
102247                                 },
102248                                 "touch-event": {
102249                                     attributeName: "touch-event",
102250                                     required: false,
102251                                     type: "string"
102252                                 }
102253                             },
102254                             children: {
102255                                 "box-size": {
102256                                     nodeName: "tizen:box-size",
102257                                     required: false,
102258                                     occurence: 1,
102259                                     attributes: {
102260                                         "preview": {
102261                                             attributeName: "preview",
102262                                             required: false,
102263                                             type: "string"
102264                                         }
102265                                     }
102266                                 },
102267                                 pd: {
102268                                     nodeName: "tizen:pd",
102269                                     required: false,
102270                                     occurence: 1,
102271                                     attributes: {
102272                                         "src": {
102273                                             attributeName: "src",
102274                                             required: true,
102275                                             type: "string"
102276                                         },
102277                                         "width": {
102278                                             attributeName: "width",
102279                                             required: true,
102280                                             type: "integer"
102281                                         },
102282                                         "height": {
102283                                             attributeName: "height",
102284                                             required: true,
102285                                             type: "integer"
102286                                         }
102287                                     }
102288                                 }
102289                             }
102290                         }
102291                     }
102292                 },
102293                 account: {
102294                     nodeName: "tizen:account",
102295                     required: false,
102296                     occurrence: 0,
102297                     attributes: {
102298                         "multiple-account-support": {
102299                             attributeName: "multiple-account-support",
102300                             required: true,
102301                             type: "list",
102302                             listValues: ['true', 'false']
102303                         }
102304                     },
102305                     children: {
102306                         icon: {
102307                             nodeName: "tizen:icon",
102308                             required: false,
102309                             occurence: 1,
102310                             attributes: {
102311                                 section: {
102312                                     attributeName: "section",
102313                                     required: true,
102314                                     type: "string"
102315                                 }
102316                             }
102317                         },
102318                         "display-name": {
102319                             nodeName: "tizen:display-name",
102320                             required: false,
102321                             occurence: 1,
102322                             attributes: {
102323                                 "xml:lang": {
102324                                     attributeName: "xml:lang",
102325                                     required: false,
102326                                     type: "string"
102327                                 }
102328                             }
102329                         },
102330                         capability: {
102331                             nodeName: "capability",
102332                             required: false,
102333                             occurence: 1
102334                         }
102335                     }
102336                 },
102337                 feature: {
102338                     nodeName: "tizen:privilege",
102339                     required: false,
102340                     occurrence: 0,
102341                     attributes: {
102342                         "xml:lang": {
102343                             attributeName: "xml:lang",
102344                             required: false,
102345                             type: "iso-language",
102346                         },
102347                         dir: {
102348                             attributeName: "dir",
102349                             required: false,
102350                             type: "list",
102351                             listValues: ["ltr", "rtl", "lro", "rlo"]
102352                         },
102353                         name: {
102354                             attributeName: "name",
102355                             required: true,
102356                             type: "list",
102357                             listValues: ["http://www.w3.org/TR/battery-status/",
102358                                          "http://www.w3.org/TR/geolocation-API/",
102359                                          "http://www.w3.org/TR/touch-events/",
102360                                          "http://www.w3.org/TR/vibration/",
102361                                          "http://tizen.org/privilege/tizen",
102362                                          "http://tizen.org/privilege/alarm",
102363                                          "http://tizen.org/privilege/application.launch",
102364                                          "http://tizen.org/privilege/appmanager.kill", "http://tizen.org/privilege/appmanager.certificate",
102365                                          "http://tizen.org/privilege/bluetoothmanager", "http://tizen.org/privilege/bluetooth.admin",
102366                                          "http://tizen.org/privilege/bluetooth.gap", "http://tizen.org/privilege/bluetooth.spp",
102367                                          "http://tizen.org/privilege/bookmark.read", "http://tizen.org/privilege/bookmark.write",
102368                                          "http://tizen.org/privilege/calendar.read", "http://tizen.org/privilege/calendar.write",
102369                                          "http://tizen.org/privilege/callhistory.read", "http://tizen.org/privilege/callhistory.write",
102370                                          "http://tizen.org/privilege/contact.read", "http://tizen.org/privilege/contact.write",
102371                                          "http://tizen.org/privilege/content.read", "http://tizen.org/privilege/content.write",
102372                                          "http://tizen.org/privilege/datacontrol.consumer",
102373                                          "http://tizen.org/privilege/datasync",
102374                                          "http://tizen.org/privilege/download",
102375                                          "http://tizen.org/privilege/filesystem.read", "http://tizen.org/privilege/filesystem.write",
102376                                          "http://tizen.org/privilege/messaging.read", "http://tizen.org/privilege/messaging.write",
102377                                          "http://tizen.org/privilege/networkbearerselection",
102378                                          "http://tizen.org/privilege/nfc.common", "http://tizen.org/privilege/nfc.admin",
102379                                          "http://tizen.org/privilege/nfc.tag", "http://tizen.org/privilege/nfc.p2p",
102380                                          "http://tizen.org/privilege/notification",
102381                                          "http://tizen.org/privilege/packagemanager.install", "http://tizen.org/privilege/package.info",
102382                                          "http://tizen.org/privilege/power",
102383                                          "http://tizen.org/privilege/push",
102384                                          "http://tizen.org/privilege/setting",
102385                                          "http://tizen.org/privilege/system", "http://tizen.org/privilege/systemmanager",
102386                                          "http://tizen.org/privilege/time"]
102387                         },
102388                         required: {
102389                             attributeName: "required",
102390                             type: "boolean",
102391                             required: false
102392                         }
102393                     },
102394                     children: {
102395                         param: {
102396                             nodeName: "param",
102397                             required: false,
102398                             occurrence: 0,
102399                             attributes: {
102400                                 "xml:lang": {
102401                                     attributeName: "xml:lang",
102402                                     required: false,
102403                                     type: "iso-language",
102404                                 },
102405                                 dir: {
102406                                     attributeName: "dir",
102407                                     required: false,
102408                                     type: "list",
102409                                     listValues: ["ltr", "rtl", "lro", "rlo"]
102410                                 },
102411                                 name: {
102412                                     attributeName: "name",
102413                                     required: true,
102414                                     type: "string",
102415                                 },
102416                                 value: {
102417                                     attributeName: "value",
102418                                     required: true,
102419                                     type: "string",
102420                                 }
102421                             }
102422                         }
102423                     }
102424                 },
102425                 preference: {
102426                     nodeName: "preference",
102427                     required: false,
102428                     occurrence: 0,
102429                     attributes: {
102430                         "xml:lang": {
102431                             attributeName: "xml:lang",
102432                             required: false,
102433                             type: "iso-language",
102434                         },
102435                         dir: {
102436                             attributeName: "dir",
102437                             required: false,
102438                             type: "list",
102439                             listValues: ["ltr", "rtl", "lro", "rlo"]
102440                         },
102441                         name: {
102442                             attributeName: "name",
102443                             required: true,
102444                             type: "string"
102445                         },
102446                         value: {
102447                             type: "string",
102448                             required: false,
102449                             attributeName: "value"
102450                         },
102451                         readonly: {
102452                             attributeName: "readonly",
102453                             type: "boolean",
102454                             required: false
102455                         }
102456                     }
102457                 }
102458             }
102459         }
102460     }
102461 };
102462
102463 });
102464 define('ripple/platform/tizen/2.0/spec/device', function (require, exports, module) {
102465 /*
102466  *  Copyright 2011 Intel Corporation.
102467  *
102468  * Licensed under the Apache License, Version 2.0 (the "License");
102469  * you may not use this file except in compliance with the License.
102470  * You may obtain a copy of the License at
102471  *
102472  * http://www.apache.org/licenses/LICENSE-2.0
102473  *
102474  * Unless required by applicable law or agreed to in writing, software
102475  * distributed under the License is distributed on an "AS IS" BASIS,
102476  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
102477  * See the License for the specific language governing permissions and
102478  * limitations under the License.
102479  */
102480 var event = require('ripple/event'),
102481     utils = require('ripple/utils'),
102482     StorageTypeTable = {
102483         "UNKNOWN": "UNKNOWN",
102484         "INTERNAL": "INTERNAL",
102485         "MMC": "MMC",
102486         "USB_HOST": "USB_HOST"
102487     },
102488     NetworkTypeTable = {
102489         "NONE": "NONE",
102490         "2G": "2G",
102491         "2.5G": "2.5G",
102492         "3G": "3G",
102493         "4G": "4G",
102494         "WIFI": "WIFI",
102495         "ETHERNET": "ETHERNET",
102496         "UNKNOWN": "UNKNOWN"
102497     },
102498     LocaleTable = {
102499         "eng_USA": "eng_USA",
102500         "eng_CAN": "eng_CAN",
102501         "deu_DEU": "deu_DEU",
102502         "jpn_JPN": "jpn_JPN",
102503         "zho_CHN": "zho_CHN",
102504         "UNKNOWN": "UNKNOWN"
102505     },
102506     SimStateTable = {
102507         "ABSENT": "ABSENT",
102508         "INITIALIZING": "INITIALIZING",
102509         "READY": "READY",
102510         "PIN_REQUIRED": "PIN_REQUIRED",
102511         "PUK_REQUIRED":"PUK_REQUIRED",
102512         "NETWORK_LOCKED": "NETWORK_LOCKED",
102513         "SIM_LOCKED": "SIM_LOCKED",
102514         "UNKNOWN": "UNKNOWN"
102515     };
102516
102517 function deviceStatusEventTrigger(setting) {
102518     event.trigger("DeviceStatusChanged", [setting]);
102519 }
102520
102521 module.exports = {
102522     "Config": {
102523         "vibratingMode": {
102524             "name": "Vibrator",
102525             "control": {
102526                 "type": "checkbox",
102527                 "value": true
102528             },
102529             "callback": function (setting) {
102530                 event.trigger("VibratingModeChanged", [setting]);
102531             }
102532         },
102533         "lockScreen": {
102534             "name": "Lock Screen",
102535             "control": {
102536                 "type": "checkbox",
102537                 "value": false
102538             },
102539             "callback": function (setting) {
102540                 event.trigger("LockScreenChanged", [setting]);
102541             }
102542         }
102543     },
102544     "DEVICE_ORIENTATION": {
102545         "status": {
102546             "name": "Status",
102547             "control": {
102548                 "type": "label",
102549                 "innertext": "PORTRAIT_PRIMARY",
102550                 "value": "PORTRAIT_PRIMARY"
102551             },
102552             "event": "LayoutChanged"
102553         },
102554         "isAutoRotation": {
102555             "name": "Is Auto Rotation",
102556             "control": {
102557                 "type": "label",
102558                 "value": false
102559             }
102560         }
102561     },
102562     "CPU": {
102563         "load": {
102564             "name": "Load",
102565             "control": {
102566                 "type": "number",
102567                 "value": 0.1
102568             },
102569             "event": "CpuLoadChanged",
102570             "callback": function (setting) {
102571                 if (setting > 1) setting = 1;
102572                 if (setting < 0) setting = 0;
102573                 event.trigger("CpuLoadChanged", [setting]);
102574             }
102575         }
102576     },
102577     "STORAGE": {
102578         "type": {
102579             "name": "Type",
102580             "control": {
102581                 "type": "select",
102582                 "value": StorageTypeTable["INTERNAL"]
102583             },
102584             "options": (function () {
102585                 var optionList = {};
102586                 utils.forEach(StorageTypeTable, function (key, value) {
102587                     optionList[key] = StorageTypeTable[value];
102588                 });
102589
102590                 return optionList;
102591             }())
102592         },
102593         "capacity": {
102594             "name": "Capacity(bytes)",
102595             "control": {
102596                 "type": "label",
102597                 "value": 16000000000
102598             },
102599         },
102600         "availableCapacity": {
102601             "name": "AvailableCapacity(bytes)",
102602             "control": {
102603                 "type": "number",
102604                 "value": 12000000000
102605             },
102606             "callback": function (setting) {
102607                 event.trigger("AvailCapacityChanged", [setting]);
102608             }
102609         },
102610         "isRemovable": {
102611             "name": "IsRemovable",
102612             "control": {
102613                 "type": "checkbox",
102614                 "value": true
102615             }
102616         }
102617     },
102618     "BUILD": {
102619         "model": {
102620             "name": "Model",
102621             "control": {
102622                 "type": "label",
102623                 "innertext": "tizen-2.2 build",
102624                 "value": "tizen-2.2 build"
102625             }
102626         },
102627         "manufacturer": {
102628             "name": "Manufacturer",
102629             "control": {
102630                 "type": "label",
102631                 "innertext": "Tizen",
102632                 "value": "Tizen"
102633             }
102634         },
102635         "buildVersion": {
102636             "name": "Build Version",
102637             "control": {
102638                 "type": "label",
102639                 "innertext": "TIZEN_WEB_SIMULATOR_000001",
102640                 "value": "TIZEN_WEB_SIMULATOR_000001"
102641             }
102642         }
102643     },
102644     "LOCALE": {
102645         "language": {
102646             "name": "Language",
102647             "control": {
102648                 "type": "select",
102649                 "value": LocaleTable["eng_USA"]
102650             },
102651             "options": (function () {
102652                 var optionList = {};
102653                 utils.forEach(LocaleTable, function (key, value) {
102654                     optionList[key] = LocaleTable[value];
102655                 });
102656
102657                 return optionList;
102658             }())
102659         },
102660         "country": {
102661             "name": "Country",
102662             "control": {
102663                 "type": "select",
102664                 "value": LocaleTable["eng_USA"]
102665             },
102666             "options": (function () {
102667                 var optionList = {};
102668                 utils.forEach(LocaleTable, function (key, value) {
102669                     optionList[key] = LocaleTable[value];
102670                 });
102671
102672                 return optionList;
102673             }())
102674         }
102675     },
102676     "DISPLAY": {
102677         "resolutionWidth": {
102678             "name": "Resolution Width(pixels)",
102679             "control": {
102680                 "type": "label",
102681                 "value": 0
102682             }
102683         },
102684         "resolutionHeight": {
102685             "name": "Resolution Height(pixels)",
102686             "control": {
102687                 "type": "label",
102688                 "value": 0
102689             }
102690         },
102691         "dotsPerInchWidth": {
102692             "name": "DPI-X",
102693             "control": {
102694                 "type": "label",
102695                 "value": 0
102696             }
102697         },
102698         "dotsPerInchHeight": {
102699             "name": "DPI-Y",
102700             "control": {
102701                 "type": "label",
102702                 "value": 0
102703             }
102704         },
102705         "physicalWidth": {
102706             "name": "Physical Width(millimeters)",
102707             "control": {
102708                 "type": "label",
102709                 "value": 0
102710             }
102711         },
102712         "physicalHeight": {
102713             "name": "Physical Height(millimeters)",
102714             "control": {
102715                 "type": "label",
102716                 "value": 0
102717             }
102718         },
102719         "brightness": {
102720             "name": "Brightness",
102721             "control": {
102722                 "type": "number",
102723                 "value": 1
102724             },
102725             "event": "DisplayBrightnessChanged",
102726             "callback": function (setting) {
102727                 if (setting > 1) setting = 1;
102728                 if (setting < 0) setting = 0;
102729                 event.trigger("DisplayBrightnessChanged", [setting]);
102730             }
102731         }
102732     },
102733     "NETWORK": {
102734         "networkType": {
102735             "name": "Network Type",
102736             "control" : {
102737                 "type": "select",
102738                 "value": NetworkTypeTable["NONE"]
102739             },
102740             "options": (function () {
102741                 var optionList = {};
102742                 utils.forEach(NetworkTypeTable, function (key, value) {
102743                     optionList[key] = NetworkTypeTable[value];
102744                 });
102745
102746                 return optionList;
102747             }())
102748         }
102749     },
102750     "WIFI_NETWORK": {
102751         "status": {
102752             "name": "Status",
102753             "control": {
102754                 "type": "checkbox",
102755                 "value": false
102756             },
102757             "event": "WiFiNetworkStatusChanged",
102758             "callback": function (setting) {
102759                 event.trigger("WiFiNetworkStatusChanged", [setting]);
102760             }
102761         },
102762         "ssid": {
102763             "name": "SSID",
102764             "control": {
102765                 "type": "text",
102766                 "value": "Tizen WiFi"
102767             }
102768         },
102769         "ipAddress": {
102770             "name": "IP Address",
102771             "control": {
102772                 "type": "text",
102773                 "value": "192.168.0.1"
102774             }
102775         },
102776         "ipv6Address": {
102777             "name": "IPv6 Address",
102778             "control": {
102779                 "type": "text",
102780                 "value": "2001:db8:85a3:0:0:0:70:7334"
102781             }
102782         },
102783         "signalStrength": {
102784             "name": "Signal Strength",
102785             "control": {
102786                 "type": "select",
102787                 "value": 0
102788             },
102789             "options": (function () {
102790                 var i,
102791                     optionList = {};
102792
102793                 for (i = 0; i <= 10; i++) {
102794                     optionList[i] = i;
102795                 }
102796
102797                 return optionList;
102798             }())
102799         }
102800     },
102801     "CELLULAR_NETWORK": {
102802         "status": {
102803             "name": "Status",
102804             "control": {
102805                 "type": "checkbox",
102806                 "value": true
102807             },
102808             "event": "CellularNetworkStatusChanged",
102809             "callback": function (setting) {
102810                 event.trigger("CellularNetworkStatusChanged", [setting]);
102811             }
102812         },
102813         "apn": {
102814             "name": "APN",
102815             "control": {
102816                 "type": "text",
102817                 "value": "Tizen"
102818             }
102819         },
102820         "ipAddress": {
102821             "name": "IP Address",
102822             "control": {
102823                 "type": "text",
102824                 "value": "10.0.2.16"
102825             }
102826         },
102827         "ipv6Address": {
102828             "name": "IPv6 Address",
102829             "control": {
102830                 "type": "text",
102831                 "value": "2001:db8:85a3:0:0:0:70:7334"
102832             }
102833         },
102834         "mcc": {
102835             "name": "MCC",
102836             "control": {
102837                 "type": "number",
102838                 "value": 460
102839             }
102840         },
102841         "mnc": {
102842             "name": "MNC",
102843             "control": {
102844                 "type": "number",
102845                 "value": 0
102846             }
102847         },
102848         "cellId": {
102849             "name": "Cell ID",
102850             "control": {
102851                 "type": "number",
102852                 "value": 0
102853             }
102854         },
102855         "lac": {
102856             "name": "LAC",
102857             "control": {
102858                 "type": "number",
102859                 "value": 0
102860             }
102861         },
102862         "isRoaming": {
102863             "name": "Roaming",
102864             "control": {
102865                 "type": "checkbox",
102866                 "value": true
102867             }
102868         },
102869         "isFlightMode": {
102870             "name": "Flight Mode",
102871             "control": {
102872                 "type": "checkbox",
102873                 "value": false
102874             },
102875             "callback": function (setting) {
102876                 event.trigger("FlightModeChanged", [setting]);
102877             }
102878         },
102879         "imei": {
102880             "name": "IMEI",
102881             "control": {
102882                 "type": "text",
102883                 "value": "012417005203000"
102884             }
102885         }
102886     },
102887     "SIM": {
102888         "state": {
102889             "name": "State",
102890             "control": {
102891                 "type": "select",
102892                 "value": SimStateTable["READY"]
102893             },
102894             "options": (function () {
102895                 var optionList = {};
102896                 utils.forEach(SimStateTable, function (key, value) {
102897                     optionList[key] = SimStateTable[value];
102898                 });
102899
102900                 return optionList;
102901             }())
102902         },
102903         "operatorName": {
102904             "name": "Operator Name",
102905             "control": {
102906                 "type": "text",
102907                 "value": "Tizen"
102908             }
102909         },
102910         "msisdn": {
102911             "name": "MSISDN",
102912             "control": {
102913                 "type": "text",
102914                 "value": "088123456789"
102915             }
102916         },
102917         "iccid": {
102918             "name": "ICCID",
102919             "control": {
102920                 "type": "text",
102921                 "value": "123000MFSSYYGXXXXXXP"
102922             }
102923         },
102924         "mcc": {
102925             "name": "MCC",
102926             "control": {
102927                 "type": "number",
102928                 "value": 460
102929             }
102930         },
102931         "mnc": {
102932             "name": "MNC",
102933             "control": {
102934                 "type": "number",
102935                 "value": 0
102936             }
102937         },
102938         "msin": {
102939             "name": "MSIN",
102940             "control": {
102941                 "type": "text",
102942                 "value": "H1 H2 H3 S 12345"
102943             }
102944         },
102945         "spn": {
102946             "name": "SPN",
102947             "control": {
102948                 "type": "text",
102949                 "value": "TizenSPN"
102950             }
102951         }
102952     },
102953     "PERIPHERAL": {
102954         "isVideoOutputOn": {
102955             "name": "Video Output",
102956             "control": {
102957                 "type": "checkbox",
102958                 "value": false
102959             }
102960         }
102961     }
102962 };
102963
102964
102965 });
102966 define('ripple/platform/tizen/2.0/spec/sensor', function (require, exports, module) {
102967 /*
102968  *  Copyright 2012 Intel Corporation.
102969  *
102970  * Licensed under the Apache License, Version 2.0 (the "License");
102971  * you may not use this file except in compliance with the License.
102972  * You may obtain a copy of the License at
102973  *
102974  * http://www.apache.org/licenses/LICENSE-2.0
102975  *
102976  * Unless required by applicable law or agreed to in writing, software
102977  * distributed under the License is distributed on an "AS IS" BASIS,
102978  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
102979  * See the License for the specific language governing permissions and
102980  * limitations under the License.
102981  */
102982 var event = require('ripple/event');
102983
102984 function sensorStatusEventTrigger(setting) {
102985     event.trigger("SensorStatusChanged", [setting]);
102986 }
102987
102988 module.exports = {
102989     "Accelerometer": {
102990         "resolution": 0.039239998906850815,
102991         "minDelay": 20,
102992         "range": 20.051639556884766,
102993         "name": "Accelerometer",
102994         "type": "Accelerometer"
102995     },
102996     "MagneticField": {
102997         "x": {
102998             "name": "X",
102999             "control": {
103000                 "type": "range",
103001                 "value": 100.0000000000000000,
103002                 "min": 0.0000000000000000,
103003                 "max": 200.0000000000000000,
103004                 "step": 0.0000000000000001
103005             },
103006             "callback": function (setting) {
103007                 event.trigger("MagneticField-xChanged", [setting]);
103008             }
103009         },
103010
103011         "y": {
103012             "name": "Y",
103013             "control": {
103014                 "type": "range",
103015                 "value": 100.0000000000000000,
103016                 "min": 0.0000000000000000,
103017                 "max": 200.0000000000000000,
103018                 "step": 0.0000000000000001
103019             },
103020             "callback": function (setting) {
103021                 event.trigger("MagneticField-yChanged", [setting]);
103022             }
103023         },
103024
103025         "z": {
103026             "name": "Z",
103027             "control": {
103028                 "type": "range",
103029                 "value": 100.0000000000000000,
103030                 "min": 0.0000000000000000,
103031                 "max": 200.0000000000000000,
103032                 "step": 0.0000000000000001
103033             },
103034             "callback": function (setting) {
103035                 event.trigger("MagneticField-zChanged", [setting]);
103036             }
103037         },
103038
103039         "resolution": 1,
103040         "minDelay": 20,
103041         "range": 359,
103042         "name": "MagneticField",
103043         "type": "MagneticField"
103044     },
103045     "Rotation": {
103046         "resolution": 1,
103047         "minDelay": 20,
103048         "range": 359,
103049         "name": "Rotation",
103050         "type": "Rotation"
103051     },
103052     "Orientation": {
103053         "resolution": 1,
103054         "minDelay": 20,
103055         "range": 359,
103056         "name": "Orientation",
103057         "type": "Orientation"
103058     }
103059 };
103060
103061 });
103062 define('ripple/platform/tizen/2.0/spec/ui', function (require, exports, module) {
103063 /*
103064  *  Copyright 2011 Intel Corporation.
103065  *
103066  * Licensed under the Apache License, Version 2.0 (the "License");
103067  * you may not use this file except in compliance with the License.
103068  * You may obtain a copy of the License at
103069  *
103070  * http://www.apache.org/licenses/LICENSE-2.0
103071  *
103072  * Unless required by applicable law or agreed to in writing, software
103073  * distributed under the License is distributed on an "AS IS" BASIS,
103074  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
103075  * See the License for the specific language governing permissions and
103076  * limitations under the License.
103077  */
103078 module.exports = {
103079     plugins: [
103080         "sensors",
103081         "communication",
103082         "geoView",
103083         "widgetConfig",
103084         "deviceSettings",
103085         "application",
103086         "network",
103087         "power",
103088         "download",
103089         "notifications",
103090         "package"
103091     ]
103092 };
103093
103094 });
103095 define('ripple/platform/tizen/2.0/spec', function (require, exports, module) {
103096 /*
103097  *  Copyright 2012 Intel Corporation.
103098  *
103099  * Licensed under the Apache License, Version 2.0 (the "License");
103100  * you may not use this file except in compliance with the License.
103101  * You may obtain a copy of the License at
103102  *
103103  * http://www.apache.org/licenses/LICENSE-2.0
103104  *
103105  * Unless required by applicable law or agreed to in writing, software
103106  * distributed under the License is distributed on an "AS IS" BASIS,
103107  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
103108  * See the License for the specific language governing permissions and
103109  * limitations under the License.
103110  */
103111
103112 module.exports = {
103113
103114     id: "tizen",
103115     version: "2.2",
103116     name: "TIZEN",
103117
103118     persistencePrefix: "tizen1-",
103119
103120     config: require('ripple/platform/tizen/2.0/spec/config'),
103121     ui: require('ripple/platform/tizen/2.0/spec/ui'),
103122     device: require('ripple/platform/tizen/2.0/spec/device'),
103123     sensor: require('ripple/platform/tizen/2.0/spec/sensor'),
103124     DeviceMotionEvent: require('ripple/platform/tizen/2.0/DeviceMotionEvent'),
103125     DeviceOrientationEvent: require('ripple/platform/tizen/2.0/DeviceOrientationEvent'),
103126
103127     objects: {
103128         Coordinates: {
103129             path: "w3c/1.0/Coordinates"
103130         },
103131         Position: {
103132             path: "w3c/1.0/Position"
103133         },
103134         PositionError: {
103135             path: "w3c/1.0/PositionError"
103136         },
103137         SensorConnection: {
103138             path: "w3c/1.0/SensorConnection"
103139         },
103140         navigator: {
103141             path: "tizen/2.0/navigator",
103142             children: {
103143                 geolocation: {
103144                     path: "wac/2.0/geolocation"
103145                 },
103146                 battery: {
103147                     path: "tizen/2.0/battery"
103148                 }
103149             }
103150         },
103151         tizen: {
103152             feature: "http://tizen.org/privilege/tizen",
103153             children: {
103154                 AlarmAbsolute: {
103155                     path: "tizen/2.0/AlarmAbsolute"
103156                 },
103157                 AlarmRelative: {
103158                     path: "tizen/2.0/AlarmRelative"
103159                 },
103160                 ApplicationControl: {
103161                     path: "tizen/2.0/ApplicationControl"
103162                 },
103163                 ApplicationControlData: {
103164                     path: "tizen/2.0/ApplicationControlData"
103165                 },
103166                 AttributeFilter: {
103167                     path: "tizen/2.0/AttributeFilter"
103168                 },
103169                 AttributeRangeFilter: {
103170                     path: "tizen/2.0/AttributeRangeFilter"
103171                 },
103172                 BookmarkFolder: {
103173                     path: "tizen/2.0/BookmarkFolder"
103174                 },
103175                 BookmarkItem: {
103176                     path: "tizen/2.0/BookmarkItem"
103177                 },
103178                 CalendarAlarm: {
103179                     path: "tizen/2.0/CalendarAlarm"
103180                 },
103181                 CalendarAttendee: {
103182                     path: "tizen/2.0/CalendarAttendee"
103183                 },
103184                 CalendarEvent: {
103185                     path: "tizen/2.0/CalendarEvent"
103186                 },
103187                 CalendarEventId: {
103188                     path: "tizen/2.0/CalendarEventId"
103189                 },
103190                 CalendarRecurrenceRule: {
103191                     path: "tizen/2.0/CalendarRecurrenceRule"
103192                 },
103193                 CalendarTask: {
103194                     path: "tizen/2.0/CalendarTask"
103195                 },
103196                 CompositeFilter: {
103197                     path: "tizen/2.0/CompositeFilter"
103198                 },
103199                 Contact: {
103200                     path: "tizen/2.0/ContactBase"
103201                 },
103202                 ContactAddress: {
103203                     path: "tizen/2.0/ContactAddress"
103204                 },
103205                 ContactAnniversary: {
103206                     path: "tizen/2.0/ContactAnniversary"
103207                 },
103208                 ContactEmailAddress: {
103209                     path: "tizen/2.0/ContactEmailAddress"
103210                 },
103211                 ContactGroup: {
103212                     path: "tizen/2.0/ContactGroup"
103213                 },
103214                 ContactName: {
103215                     path: "tizen/2.0/ContactName"
103216                 },
103217                 ContactOrganization: {
103218                     path: "tizen/2.0/ContactOrganization"
103219                 },
103220                 ContactPhoneNumber: {
103221                     path: "tizen/2.0/ContactPhoneNumber"
103222                 },
103223                 ContactRef: {
103224                     path: "tizen/2.0/ContactRef"
103225                 },
103226                 ContactWebSite: {
103227                     path: "tizen/2.0/ContactWebSite"
103228                 },
103229                 DownloadRequest: {
103230                     path: "tizen/2.0/DownloadRequest"
103231                 },
103232                 Message: {
103233                     path: "tizen/2.0/Message"
103234                 },
103235                 NDEFMessage: {
103236                     path: "tizen/2.0/NDEFMessage"
103237                 },
103238                 NDEFRecord: {
103239                     path: "tizen/2.0/NDEFRecord"
103240                 },
103241                 NDEFRecordMedia: {
103242                     path: "tizen/2.0/NDEFRecordMedia"
103243                 },
103244                 NDEFRecordText: {
103245                     path: "tizen/2.0/NDEFRecordText"
103246                 },
103247                 NDEFRecordURI: {
103248                     path: "tizen/2.0/NDEFRecordURI"
103249                 },
103250                 NotificationDetailInfo: {
103251                     path: "tizen/2.0/NotificationDetailInfo"
103252                 },
103253                 SimpleCoordinates: {
103254                     path: "tizen/2.0/SimpleCoordinates"
103255                 },
103256                 SortMode: {
103257                     path: "tizen/2.0/SortMode"
103258                 },
103259                 StatusNotification: {
103260                     path: "tizen/2.0/StatusNotification"
103261                 },
103262                 SyncInfo: {
103263                     path: "tizen/2.0/SyncInfo"
103264                 },
103265                 SyncServiceInfo: {
103266                     path: "tizen/2.0/SyncServiceInfo"
103267                 },
103268                 SyncProfileInfo: {
103269                     path: "tizen/2.0/SyncProfileInfo"
103270                 },
103271                 TZDate: {
103272                     path: "tizen/2.0/TZDate"
103273                 },
103274                 TimeDuration: {
103275                     path: "tizen/2.0/TimeDuration"
103276                 },
103277                 alarm: {
103278                     path: "tizen/2.0/alarm",
103279                     feature: "http://tizen.org/privilege/alarm",
103280                     handleSubfeatures: true
103281                 },
103282                 application: {
103283                     path: "tizen/2.0/application",
103284                     feature: "http://tizen.org/privilege/application.launch|http://tizen.org/privilege/appmanager.kill|http://tizen.org/privilege/appmanager.certificate",
103285                     handleSubfeatures: true
103286                 },
103287                 bluetooth: {
103288                     path: "tizen/2.0/bluetooth",
103289                     feature: "http://tizen.org/privilege/bluetoothmanager|http://tizen.org/privilege/bluetooth.admin|http://tizen.org/privilege/bluetooth.gap|http://tizen.org/privilege/bluetooth.spp",
103290                     handleSubfeatures: true
103291                 },
103292                 bookmark: {
103293                     path: "tizen/2.0/bookmark",
103294                     feature: "http://tizen.org/privilege/bookmark.read|http://tizen.org/privilege/bookmark.write",
103295                     handleSubfeatures: true
103296                 },
103297                 callhistory: {
103298                     path: "tizen/2.0/callHistory",
103299                     feature: "http://tizen.org/privilege/callhistory|http://tizen.org/privilege/callhistory.read|http://tizen.org/privilege/callhistory.write",
103300                     handleSubfeatures: true
103301                 },
103302                 calendar: {
103303                     path: "tizen/2.0/calendar",
103304                     feature: "http://tizen.org/privilege/calendar.read|http://tizen.org/privilege/calendar.write",
103305                     handleSubfeatures: true
103306                 },
103307                 contact: {
103308                     path: "tizen/2.0/contact",
103309                     feature: "http://tizen.org/privilege/contact.read|http://tizen.org/privilege/contact.write",
103310                     handleSubfeatures: true
103311                 },
103312                 content: {
103313                     path: "tizen/2.0/content",
103314                     feature: "http://tizen.org/privilege/content.read|http://tizen.org/privilege/content.write",
103315                     handleSubfeatures: true
103316                 },
103317                 datacontrol: {
103318                     path: "tizen/2.0/datacontrol",
103319                     feature: "http://tizen.org/privilege/datacontrol.consumer",
103320                     handleSubfeatures: true
103321                 },
103322                 datasync: {
103323                     path: "tizen/2.0/datasync",
103324                     feature: "http://tizen.org/privilege/datasync",
103325                     handleSubfeatures: true
103326                 },
103327                 download: {
103328                     path: "tizen/2.0/download",
103329                     feature: "http://tizen.org/privilege/download",
103330                     handleSubfeatures: true
103331                 },
103332                 filesystem: {
103333                     path: "tizen/2.0/filesystem",
103334                     feature: "http://tizen.org/privilege/filesystem.read|http://tizen.org/privilege/filesystem.write"
103335                 },
103336                 messaging: {
103337                     path: "tizen/2.0/messaging",
103338                     feature: "http://tizen.org/privilege/messaging.send|http://tizen.org/privilege/messaging.read|http://tizen.org/privilege/messaging.write",
103339                     handleSubfeatures: true
103340                 },
103341                 networkbearerselection: {
103342                     path: "tizen/2.0/networkbearerselection",
103343                     feature: "http://tizen.org/privilege/networkbearerselection",
103344                     handleSubfeatures: true
103345                 },
103346                 nfc: {
103347                     path: "tizen/2.0/nfc",
103348                     feature: "http://tizen.org/privilege/nfc.common|http://tizen.org/privilege/nfc.admin|http://tizen.org/privilege/nfc.tag|http://tizen.org/privilege/nfc.p2p",
103349                     handleSubfeatures: true
103350                 },
103351                 notification: {
103352                     path: "tizen/2.0/notification",
103353                     feature: "http://tizen.org/privilege/notification",
103354                     handleSubfeatures: true
103355                 },
103356                 package: {
103357                     path: "tizen/2.0/package",
103358                     feature: "http://tizen.org/privilege/packagemanager.install|http://tizen.org/privilege/package.info",
103359                     handleSubfeatures: true
103360                 },
103361                 power: {
103362                     path: "tizen/2.0/power",
103363                     feature: "http://tizen.org/privilege/power",
103364                     handleSubfeatures: true
103365                 },
103366                 push: {
103367                     path: "tizen/2.0/push",
103368                     feature: "http://tizen.org/privilege/push",
103369                     handleSubfeatures: true
103370                 },
103371                 systeminfo: {
103372                     path: "tizen/2.0/systeminfo",
103373                     feature: "http://tizen.org/privilege/system|http://tizen.org/privilege/systemmanager",
103374                     handleSubfeatures: true
103375                 },
103376                 systemsetting: {
103377                     path: "tizen/2.0/systemsetting",
103378                     feature: "http://tizen.org/privilege/setting",
103379                     handleSubfeatures: true
103380                 },
103381                 time: {
103382                     path: "tizen/2.0/time",
103383                     feature: "http://tizen.org/privilege/time",
103384                     handleSubfeatures: true
103385                 }
103386             }
103387         }
103388     }
103389 };
103390
103391 });
103392 define('ripple/platform/tizen/2.0/syncml-js-lib/adapter', function (require, exports, module) {
103393 // -*- coding: utf-8 -*-
103394 //-----------------------------------------------------------------------------
103395 // file: $Id$
103396 // lib:  syncml-js.adapter
103397 // auth: griffin <griffin@uberdev.org>
103398 // date: 2012/10/22
103399 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
103400 //-----------------------------------------------------------------------------
103401
103402 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
103403     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
103404     storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store');
103405
103406
103407 var _self = (function () {
103408
103409     var exports = {};
103410
103411     //---------------------------------------------------------------------------
103412     exports.Adapter = common.Base.extend({
103413
103414         // //-------------------------------------------------------------------------
103415         // constructor: function(context, options, devInfo) {
103416
103417         //-------------------------------------------------------------------------
103418         normUri: function(uri) {
103419             return common.normpath(uri);
103420         },
103421
103422         //-------------------------------------------------------------------------
103423         getStores: function() {
103424             return _.values(this._stores);
103425         },
103426
103427         //-------------------------------------------------------------------------
103428         getStore: function(uri) {
103429             return this._stores[this.normUri(uri)];
103430         },
103431
103432         //-------------------------------------------------------------------------
103433         addStore: function(store, cb) {
103434             var self = this;
103435             if ( store instanceof storemod.Store )
103436             {
103437                 store.uri = self.normUri(store.uri);
103438                 store._a  = self;
103439             }
103440             else
103441                 store = new storemod.Store(this, store);
103442             store._updateModel(function(err) {
103443                 if ( err )
103444                 return cb(err);
103445             self._stores[store.uri] = store;
103446
103447             // TODO: remove this sensitivity...
103448             if ( ! self.isLocal )
103449                 return cb();
103450
103451             self._save(self._c._txn(), function(err) {
103452                 if ( err )
103453                 return cb(err);
103454             cb(null, store);
103455             });
103456             });
103457         },
103458
103459         //-------------------------------------------------------------------------
103460         removeStore: function(uri, cb) {
103461             var self = this;
103462             if ( ! self.isLocal )
103463                 // todo: implement
103464                 return cb(new common.LogicalError(
103465                             'cannot remove remote store "' + uri + '": remote peer responsibility'));
103466             if ( ! self._stores[uri] )
103467                 return cb(new common.InternalError(
103468                             'cannot remove store "' + uri + '": no such store'));
103469             delete self._stores[uri];
103470             var model = self._getModel();
103471             model.stores = _.filter(model.stores, function(store) {
103472                 return store.uri != uri;
103473             });
103474             _.each(model.peers, function(peer) {
103475                 peer.routes = _.filter(peer.routes, function(route) {
103476                     return route.localUri != uri;
103477                 });
103478                 _.each(peer.stores, function(store) {
103479                     if ( store.binding && store.binding.uri == uri )
103480                     store.binding = null;
103481                 });
103482             });
103483             return cb();
103484         },
103485
103486         //-------------------------------------------------------------------------
103487         _isMapper: function() {
103488             // indicates whether or not this adapter is capable of mapping
103489             // items. in the standard SyncML peer model, only the server
103490             // ever does mapping, but in the dream-land of syncml-js, all
103491             // peers can be mappers, or even better, implements an extension
103492             // "is-uuid/adopted" that does not require mapping. so, since
103493             // that is just a dream-land for now, this will try to identify
103494             // if this adapter represents a server...
103495             // todo: enhance syncml-js so that it is not needed!...
103496             if ( ! this.isLocal )
103497                 return this.url && this.url.length > 0;
103498             return this.devInfo && this.devInfo.devType == constant.DEVTYPE_SERVER;
103499         },
103500
103501         //-------------------------------------------------------------------------
103502         describe: function(stream, cb) {
103503             var self = this;
103504             if ( self.url )
103505                 stream.writeln('URL: ' + self.url);
103506             stream.writeln('Device ID: ' + self.devID);
103507             var s1 = stream.indented();
103508             var s2 = s1.indented();
103509
103510             var describe_stores = function(cb) {
103511                 var stores = self.getStores();
103512                 if ( stores.length <= 0 )
103513                 {
103514                     stream.writeln('Data stores: (none)');
103515                     return cb();
103516                 }
103517                 stream.writeln('Data stores:');
103518                 common.cascade(stores, function(store, cb) {
103519                     s1.writeln(( store.displayName || store.uri ) + ':');
103520                     store.describe(s2, cb);
103521                 }, cb);
103522             };
103523
103524             var describe_peers = function(cb) {
103525                 if ( ! self.getPeers )
103526                     return cb();
103527                 var peers = self.getPeers();
103528                 if ( peers.length <= 0 )
103529                 {
103530                     stream.writeln('Known peers: (none)');
103531                     return cb();
103532                 }
103533                 stream.writeln('Known peers:');
103534                 common.cascade(peers, function(peer, cb) {
103535                     s1.writeln(( peer.displayName || peer.url ) + ':');
103536                     peer.describe(s2, cb);
103537                 }, cb);
103538             }
103539
103540             describe_stores(function(err) {
103541                 if ( err )
103542                 return cb(err);
103543             describe_peers(cb);
103544             });
103545         }
103546
103547     });
103548
103549     return exports;
103550
103551     })();
103552
103553     module.exports = _self;
103554
103555 });
103556 define('ripple/platform/tizen/2.0/syncml-js-lib/agent', function (require, exports, module) {
103557 // -*- coding: utf-8 -*-
103558 //-----------------------------------------------------------------------------
103559 // file: $Id$
103560 // lib:  syncml-js.agent
103561 // auth: griffin <griffin@uberdev.org>
103562 // date: 2012/10/22
103563 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
103564 //-----------------------------------------------------------------------------
103565
103566 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common');
103567
103568 var _self = (function () {
103569
103570     var exports = {};
103571
103572     //---------------------------------------------------------------------------
103573     exports.Agent = common.Base.extend({
103574
103575         //-------------------------------------------------------------------------
103576         constructor: function(options) {
103577             options = _.defaults(options, {
103578                 hierarchicalSync: false
103579             });
103580             this.hierarchicalSync = options.hierarchicalSync;
103581         },
103582
103583         //-------------------------------------------------------------------------
103584         dumpItem: function(item, stream, contentType, version, cb) {
103585             return this.dumpsItem(
103586                 item, contentType, version,
103587                 function(err, data, new_contentType, new_version) {
103588                     if ( err ) {
103589                         return cb(err);
103590                     }
103591                     stream.write(data, function(err) {
103592                         if ( err ) {
103593                             return cb(err);
103594                         }
103595                         cb(null, new_contentType, new_version);
103596                     });
103597                 });
103598         },
103599
103600         //-------------------------------------------------------------------------
103601         loadItem: function(stream, contentType, version, cb) {
103602             var self = this;
103603             stream.read(function(err, data) {
103604                 if ( err ) {
103605                     cb(err);
103606                 }
103607                 self.loadsItem(data, contentType, version, cb);
103608             });
103609         },
103610
103611         //-------------------------------------------------------------------------
103612         deleteAllItems: function(cb) {
103613             var self = this;
103614             self.getAllItems(function(err, items) {
103615                 if ( err ) {
103616                     return cb(err);
103617                 }
103618                 common.cascade(items, function(e, cb) {
103619                     self.deleteItem(e, cb);
103620                 }, cb);
103621             });
103622         },
103623
103624         // TODO: add documentation about all expected methods...
103625
103626         getAllItems: function(cb) {
103627             // cb(null, LIST)
103628             return cb(new common.NotImplementedError());
103629         },
103630
103631         dumpsItem: function(item, contentType, version, cb) {
103632             // cb(null, DATA [, NEW-CONTENTTYPE [, NEW-VERSION]])
103633             return cb(new common.NotImplementedError());
103634         },
103635
103636         loadsItem: function(data, contentType, version, cb) {
103637             // cb(null, ITEM)
103638             return cb(new common.NotImplementedError());
103639         },
103640
103641         addItem: function(item, cb) {
103642             // cb(null, ITEM)
103643             return cb(new common.NotImplementedError());
103644         },
103645
103646         getItem: function(itemID, cb) {
103647             // cb(null, ITEM)
103648             return cb(new common.NotImplementedError());
103649         },
103650
103651         replaceItem: function(item, reportChanges, cb) {
103652             // cb(null [, CSPEC])
103653             return cb(new common.NotImplementedError());
103654         },
103655
103656         deleteItem: function(itemID, cb) {
103657             // cb(null)
103658             return cb(new common.NotImplementedError());
103659         },
103660
103661         getContentTypes: function() {
103662             throw new common.NotImplementedError();
103663         },
103664
103665         matchItem: function(item, cb) {
103666             this.getAllItems(function(err, list) {
103667                 if ( err ) {
103668                     return cb(err);
103669                 }
103670                 var match = _.find(list, function(cur) {
103671                     return cur.compare && cur.compare(item) == 0;
103672                 });
103673                 return cb(null, match);
103674             });
103675         }
103676
103677     // TODO: mergeItems()
103678
103679     });
103680
103681     return exports;
103682
103683 })();
103684
103685 module.exports = _self;
103686
103687 });
103688 define('ripple/platform/tizen/2.0/syncml-js-lib/base64', function (require, exports, module) {
103689 // -*- coding: utf-8 -*-
103690 //-----------------------------------------------------------------------------
103691 // file: $Id$
103692 //-----------------------------------------------------------------------------
103693
103694 var _self = (function() {
103695
103696     // shamelessly scrubbed from:
103697     //   http://www.webtoolkit.info/javascript-base64.html
103698
103699     /**
103700      *
103701      *  Base64 encode / decode
103702      *  http://www.webtoolkit.info/
103703      *
103704      **/
103705
103706     var Base64 = {
103707
103708         // private property
103709         _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
103710
103711       // public method for encoding
103712       encode : function (input) {
103713           var output = "";
103714           var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
103715           var i = 0;
103716
103717           input = Base64._utf8_encode(input);
103718
103719           while (i < input.length) {
103720
103721               chr1 = input.charCodeAt(i++);
103722               chr2 = input.charCodeAt(i++);
103723               chr3 = input.charCodeAt(i++);
103724
103725               enc1 = chr1 >> 2;
103726               enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
103727               enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
103728               enc4 = chr3 & 63;
103729
103730               if (isNaN(chr2)) {
103731                   enc3 = enc4 = 64;
103732               } else if (isNaN(chr3)) {
103733                   enc4 = 64;
103734               }
103735
103736               output = output +
103737                   this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
103738                   this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
103739
103740           }
103741
103742           return output;
103743       },
103744
103745       // public method for decoding
103746       decode : function (input) {
103747           var output = "";
103748           var chr1, chr2, chr3;
103749           var enc1, enc2, enc3, enc4;
103750           var i = 0;
103751
103752           input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
103753
103754           while (i < input.length) {
103755
103756               enc1 = this._keyStr.indexOf(input.charAt(i++));
103757               enc2 = this._keyStr.indexOf(input.charAt(i++));
103758               enc3 = this._keyStr.indexOf(input.charAt(i++));
103759               enc4 = this._keyStr.indexOf(input.charAt(i++));
103760
103761               chr1 = (enc1 << 2) | (enc2 >> 4);
103762               chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
103763               chr3 = ((enc3 & 3) << 6) | enc4;
103764
103765               output = output + String.fromCharCode(chr1);
103766
103767               if (enc3 != 64) {
103768                   output = output + String.fromCharCode(chr2);
103769               }
103770               if (enc4 != 64) {
103771                   output = output + String.fromCharCode(chr3);
103772               }
103773
103774           }
103775
103776           output = Base64._utf8_decode(output);
103777
103778           return output;
103779
103780       },
103781
103782       // private method for UTF-8 encoding
103783       _utf8_encode : function (string) {
103784           string = string.replace(/\r\n/g,"\n");
103785           var utftext = "";
103786
103787           for (var n = 0; n < string.length; n++) {
103788
103789               var c = string.charCodeAt(n);
103790
103791               if (c < 128) {
103792                   utftext += String.fromCharCode(c);
103793               }
103794               else if((c > 127) && (c < 2048)) {
103795                   utftext += String.fromCharCode((c >> 6) | 192);
103796                   utftext += String.fromCharCode((c & 63) | 128);
103797               }
103798               else {
103799                   utftext += String.fromCharCode((c >> 12) | 224);
103800                   utftext += String.fromCharCode(((c >> 6) & 63) | 128);
103801                   utftext += String.fromCharCode((c & 63) | 128);
103802               }
103803
103804           }
103805
103806           return utftext;
103807       },
103808
103809       // private method for UTF-8 decoding
103810       _utf8_decode : function (utftext) {
103811           var string = "";
103812           var i = 0;
103813           var c = c1 = c2 = 0;
103814
103815           while ( i < utftext.length ) {
103816
103817               c = utftext.charCodeAt(i);
103818
103819               if (c < 128) {
103820                   string += String.fromCharCode(c);
103821                   i++;
103822               }
103823               else if((c > 191) && (c < 224)) {
103824                   c2 = utftext.charCodeAt(i+1);
103825                   string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
103826                   i += 2;
103827               }
103828               else {
103829                   c2 = utftext.charCodeAt(i+1);
103830                   c3 = utftext.charCodeAt(i+2);
103831                   string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
103832                   i += 3;
103833               }
103834
103835           }
103836
103837           return string;
103838       }
103839
103840     };
103841
103842     return Base64;
103843
103844 })();
103845
103846 module.exports = _self;
103847
103848 });
103849 define('ripple/platform/tizen/2.0/syncml-js-lib/codec', function (require, exports, module) {
103850 // -*- coding: utf-8 -*-
103851 //-----------------------------------------------------------------------------
103852 // file: $Id$
103853 // auth: metagriffin <metagriffin@uberdev.org>
103854 // date: 2012/10/13
103855 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
103856 //-----------------------------------------------------------------------------
103857
103858 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
103859     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
103860     _self;
103861
103862 _self = (function () {
103863
103864     var exports = {};
103865
103866     //---------------------------------------------------------------------------
103867     exports.Codec = common.Base.extend({
103868
103869         encode: function(xtree, cb) {
103870             throw new common.NotImplementedError();
103871         },
103872
103873         decode: function(contentType, data, cb) {
103874             throw new common.NotImplementedError();
103875         },
103876     }, {
103877
103878         factory: function(codec) {
103879             // todo: should this be converted to callback-based?...
103880             if ( codec == constant.CODEC_XML )
103881         return new exports.XmlCodec()
103882         // TODO
103883         // if ( codec == constant.CODEC_WBXML )
103884         //   return exports.WbxmlCodec()
103885         throw new common.UnknownCodec('unknown or unimplemented codec "' + codec + '"')
103886         },
103887
103888             autoEncode: function(xtree, codecName, cb) {
103889                 exports.Codec.factory(codecName).encode(xtree, cb);
103890             },
103891
103892             autoDecode: function(contentType, data, cb) {
103893                 if ( contentType.indexOf(constant.TYPE_SYNCML + '+') != 0 )
103894                     return cb('unknown or unimplemented content type "' + contentType + '"');
103895                 var ct = contentType.slice((constant.TYPE_SYNCML + '+').length).split(';')[0];
103896                 exports.Codec.factory(ct).decode(contentType, data, function(err, tree) {
103897                     if ( err )
103898                     return cb(err);
103899                 return cb(null, tree, ct);
103900                 });
103901             },
103902     });
103903
103904     //---------------------------------------------------------------------------
103905     exports.XmlCodec = exports.Codec.extend({
103906
103907         name: constant.CODEC_XML,
103908
103909         encode: function(xtree, cb) {
103910             // todo: really enforce this charset...
103911             var ctype = constant.TYPE_SYNCML + '+' + this.name + '; charset=UTF-8';
103912             var ret = ET.tostring(xtree);
103913             if ( ret.charAt(0) == '<' && ret.charAt(1) == '?' )
103914     {
103915         var idx = ret.indexOf('?>');
103916         if ( idx >= 0 )
103917         ret = ret.substr(0, idx + 2).replace(/'/g, '"') + ret.substr(idx + 2);
103918     }
103919     cb(null, ctype, ret);
103920         },
103921
103922         decode: function(contentType, data, cb) {
103923             var expCT = constant.TYPE_SYNCML + '+' + this.name;
103924             if ( contentType.indexOf(expCT) != 0 )
103925         cb(new common.ProtocolError(
103926                 'received unexpected content-type "' + contentType + '" (expected "'
103927                     + expCT + '")'));
103928             try
103929             {
103930                 return cb(null, ET.parse(data).getroot());
103931             }
103932             catch(e)
103933             {
103934                 return cb(new common.ProtocolError('could not parse XML: ' + e, e));
103935             }
103936         }
103937
103938     });
103939
103940     //---------------------------------------------------------------------------
103941     // TODO: implement wbxml...
103942     // exports.WbXmlCodec = exports.Codec.extend({
103943     //   encode: function(xtree, cb) {
103944     //   },
103945     //   decode: function(contentType, data, cb) {
103946     //   }
103947     // });
103948
103949     return exports;
103950
103951 })();
103952
103953 module.exports = _self;
103954
103955 });
103956 define('ripple/platform/tizen/2.0/syncml-js-lib/common', function (require, exports, module) {
103957 // -*- coding: utf-8 -*-
103958 //-----------------------------------------------------------------------------
103959 // file: $Id$
103960 // auth: metagriffin <metagriffin@uberdev.org>
103961 // date: 2012/10/13
103962 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
103963 //-----------------------------------------------------------------------------
103964
103965 var constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
103966     _self;
103967
103968 _self = (function () {
103969     var exports = {};
103970
103971     //---------------------------------------------------------------------------
103972     // object inheritance helper routines shamelessly scrubbed from backbone.js
103973
103974     // The self-propagating extend function that Backbone classes use.
103975     var extend = exports.extend = function (protoProps, classProps) {
103976         var child = inherits(this, protoProps, classProps);
103977         child.extend = this.extend;
103978         return child;
103979     };
103980
103981     // Shared empty constructor function to aid in prototype-chain creation.
103982     var ctor = function(){};
103983
103984     // Helper function to correctly set up the prototype chain, for subclasses.
103985     // Similar to `goog.inherits`, but uses a hash of prototype properties and
103986     // class properties to be extended.
103987     var inherits = function(parent, protoProps, staticProps) {
103988         var child;
103989
103990         // The constructor function for the new subclass is either defined by you
103991         // (the "constructor" property in your `extend` definition), or defaulted
103992         // by us to simply call the parent's constructor.
103993         if (protoProps && protoProps.hasOwnProperty('constructor')) {
103994             child = protoProps.constructor;
103995         } else {
103996             child = function(){ parent.apply(this, arguments); };
103997         }
103998
103999         // Inherit class (static) properties from parent.
104000         _.extend(child, parent);
104001
104002         // Set the prototype chain to inherit from `parent`, without calling
104003         // `parent`'s constructor function.
104004         ctor.prototype = parent.prototype;
104005         child.prototype = new ctor();
104006
104007         // Add prototype properties (instance properties) to the subclass,
104008         // if supplied.
104009         if (protoProps) _.extend(child.prototype, protoProps);
104010
104011         // Add static properties to the constructor function, if supplied.
104012         if (staticProps) _.extend(child, staticProps);
104013
104014         // Correctly set child's `prototype.constructor`.
104015         child.prototype.constructor = child;
104016
104017         // Set a convenience property in case the parent's prototype is needed later.
104018         child.__super__ = parent.prototype;
104019
104020         return child;
104021     };
104022
104023     //-----------------------------------------------------------------------------
104024     exports.Base = function() {};
104025     exports.Base.extend = extend;
104026
104027     //-----------------------------------------------------------------------------
104028     var SyncmlError = exports.Base.extend({
104029         constructor: function(msg, exception, attrs) {
104030             this.message = this.name;
104031             if ( msg != undefined )
104032         this.message += ': ' + msg;
104033     this.exception = exception;
104034     if ( attrs )
104035         _.extend(this, attrs);
104036         },
104037         toString: function() {
104038             return this.message;
104039         }
104040     });
104041
104042     //---------------------------------------------------------------------------
104043     exports.Stream = exports.Base.extend({
104044
104045         writeln: function(data) {
104046             if ( data == undefined )
104047         return;
104048     return this.write(data + '\n');
104049         },
104050
104051         indented: function(indent) {
104052             return new exports.IndentStream(this, indent || this._indent);
104053         }
104054
104055     });
104056
104057     _.extend(exports, {
104058
104059         //---------------------------------------------------------------------------
104060         // exceptions
104061         SyncmlError:           SyncmlError.extend({name: 'SyncmlError'}),
104062         TypeError:             SyncmlError.extend({name: 'TypeError'}),
104063         NotImplementedError:   SyncmlError.extend({name: 'NotImplementedError'}),
104064         ProtocolError:         SyncmlError.extend({name: 'ProtocolError'}),
104065         InternalError:         SyncmlError.extend({name: 'InternalError'}),
104066         ConflictError:         SyncmlError.extend({name: 'ConflictError'}),
104067         FeatureNotSupported:   SyncmlError.extend({name: 'FeatureNotSupported'}),
104068         LogicalError:          SyncmlError.extend({name: 'LogicalError'}),
104069         CredentialsRequired:   SyncmlError.extend({name: 'CredentialsRequired'}),
104070         InvalidCredentials:    SyncmlError.extend({name: 'InvalidCredentials'}),
104071         InvalidContext:        SyncmlError.extend({name: 'InvalidContext'}),
104072         InvalidAdapter:        SyncmlError.extend({name: 'InvalidAdapter'}),
104073         InvalidStore:          SyncmlError.extend({name: 'InvalidStore'}),
104074         InvalidContentType:    SyncmlError.extend({name: 'InvalidContentType'}),
104075         InvalidAgent:          SyncmlError.extend({name: 'InvalidAgent'}),
104076         InvalidContent:        SyncmlError.extend({name: 'InvalidContent'}),
104077         InvalidItem:           SyncmlError.extend({name: 'InvalidItem'}),
104078         UnknownCodec:          SyncmlError.extend({name: 'UnknownCodec'}),
104079         NoSuchRoute:           SyncmlError.extend({name: 'NoSuchRoute'}),
104080         UnknownAuthType:       SyncmlError.extend({name: 'UnknownAuthType'}),
104081         UnknownFormatType:     SyncmlError.extend({name: 'UnknownFormatType'}),
104082
104083         //---------------------------------------------------------------------------
104084         // UUID generation
104085         makeID: function() {
104086             // shamelessly scrubbed from:
104087             //   http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
104088             // (adjusted to remove the dashes)
104089             // todo: see some of those links on how to make this more "robust"...
104090             return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
104091                 var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
104092                 return v.toString(16);
104093             });
104094         },
104095
104096         //-------------------------------------------------------------------------
104097         synctype2alert: function(type) {
104098             return constant.SyncTypeToAlert[type];
104099         },
104100
104101         //-------------------------------------------------------------------------
104102         alert2synctype: function(alert) {
104103             for ( var key in constant.SyncTypeToAlert )
104104             {
104105                 if ( constant.SyncTypeToAlert[key] == alert )
104106                     return exports.int(key);
104107             }
104108             return null;
104109         },
104110
104111         //-------------------------------------------------------------------------
104112         mode2string: function(code) {
104113             switch ( code )
104114             {
104115                 case constant.ALERT_TWO_WAY:                       return 'two-way';
104116                 case constant.ALERT_SLOW_SYNC:                     return 'slow-sync';
104117                 case constant.ALERT_ONE_WAY_FROM_CLIENT:           return 'one-way-from-client';
104118                 case constant.ALERT_REFRESH_FROM_CLIENT:           return 'refresh-from-client';
104119                 case constant.ALERT_ONE_WAY_FROM_SERVER:           return 'one-way-from-server';
104120                 case constant.ALERT_REFRESH_FROM_SERVER:           return 'refresh-from-server';
104121                 case constant.ALERT_TWO_WAY_BY_SERVER:             return 'two-way-by-server';
104122                 case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER: return 'one-way-from-client-by-server';
104123                 case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER: return 'refresh-from-client-by-server';
104124                 case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER: return 'one-way-from-server-by-server';
104125                 case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER: return 'refresh-from-server-by-server';
104126                 default: return 'UNKNOWN';
104127             }
104128         },
104129
104130         //-------------------------------------------------------------------------
104131         state2string: function(state) {
104132             switch ( state )
104133             {
104134                 case constant.ITEM_OK:           return 'ok';
104135                 case constant.ITEM_ADDED:        return 'added';
104136                 case constant.ITEM_MODIFIED:     return 'modified';
104137                 case constant.ITEM_DELETED:      return 'deleted';
104138                 case constant.ITEM_SOFTDELETED:  return 'soft-deleted';
104139                 default: return 'UNKNOWN';
104140             }
104141         },
104142
104143         //-------------------------------------------------------------------------
104144         oneWay: function(mode) {
104145             switch ( mode )
104146             {
104147                 case constant.ALERT_TWO_WAY:
104148                 case constant.ALERT_SLOW_SYNC:
104149                     return false;
104150                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
104151                 case constant.ALERT_REFRESH_FROM_CLIENT:
104152                 case constant.ALERT_ONE_WAY_FROM_SERVER:
104153                 case constant.ALERT_REFRESH_FROM_SERVER:
104154                     return true;
104155                     // case constant.ALERT_TWO_WAY_BY_SERVER:
104156                     // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER:
104157                     // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER:
104158                     // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER:
104159                     // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER:
104160                 default:
104161                     throw new exports.InternalError('invalid mode "' + mode + '"');
104162             }
104163         },
104164
104165         //-------------------------------------------------------------------------
104166         oneWayIn: function(session, mode) {
104167             switch ( mode )
104168             {
104169                 case constant.ALERT_TWO_WAY:
104170                 case constant.ALERT_SLOW_SYNC:
104171                     return false;
104172                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
104173                 case constant.ALERT_REFRESH_FROM_CLIENT:
104174                     return !! session.isServer;
104175                 case constant.ALERT_ONE_WAY_FROM_SERVER:
104176                 case constant.ALERT_REFRESH_FROM_SERVER:
104177                     return ! session.isServer;
104178                     // case constant.ALERT_TWO_WAY_BY_SERVER:
104179                     // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER:
104180                     // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER:
104181                     // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER:
104182                     // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER:
104183                 default:
104184                     throw new exports.InternalError('invalid mode "' + mode + '"');
104185             }
104186         },
104187
104188         //-------------------------------------------------------------------------
104189         oneWayOut: function(session, mode) {
104190             switch ( mode )
104191             {
104192                 case constant.ALERT_TWO_WAY:
104193                 case constant.ALERT_SLOW_SYNC:
104194                     return false;
104195                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
104196                 case constant.ALERT_REFRESH_FROM_CLIENT:
104197                     return ! session.isServer;
104198                 case constant.ALERT_ONE_WAY_FROM_SERVER:
104199                 case constant.ALERT_REFRESH_FROM_SERVER:
104200                     return !! session.isServer;
104201                     // case constant.ALERT_TWO_WAY_BY_SERVER:
104202                     // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER:
104203                     // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER:
104204                     // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER:
104205                     // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER:
104206                 default:
104207                     throw new exports.InternalError('invalid mode "' + mode + '"');
104208             }
104209         },
104210
104211         //-------------------------------------------------------------------------
104212         cascade: function(list, iterator, cb) {
104213             if ( ! cb && iterator )
104214             {
104215                 cb = iterator;
104216                 iterator = null;
104217             }
104218             if ( ! list )
104219                 return cb();
104220             var cur = 0;
104221             var next = function() {
104222                 if ( cur >= list.length )
104223                     return cb();
104224                 var curcb = function(err) {
104225                     if ( err )
104226                         return cb(err);
104227                     cur += 1;
104228                     var args = [];
104229                     for ( var idx=1 ; idx<arguments.length ; idx++ )
104230                         args.push(arguments[idx]);
104231                     return next.apply(null, args);
104232                 };
104233                 var func = iterator || list[cur];
104234                 var args = [];
104235                 if ( iterator )
104236                     args.push(list[cur]);
104237                 for ( var idx=0 ; idx<arguments.length ; idx++ )
104238                     args.push(arguments[idx]);
104239                 args.push(curcb);
104240                 return func.apply(null, args);
104241             };
104242             return next();
104243         },
104244
104245         //-------------------------------------------------------------------------
104246         ts: function() {
104247             return Math.floor((new Date()).getTime() / 1000);
104248         },
104249
104250         //-------------------------------------------------------------------------
104251         j: function(obj) {
104252             return JSON.stringify(obj);
104253         },
104254
104255         //-------------------------------------------------------------------------
104256         noop: function(cb) {
104257             return cb();
104258         },
104259
104260         //-------------------------------------------------------------------------
104261         platformBits: function() {
104262
104263             // TODO: implement this!...
104264
104265             return 32;
104266         },
104267
104268         //-------------------------------------------------------------------------
104269         getMaxMemorySize: function(context) {
104270
104271             // Returns the maximum size of a memory object. By default this
104272             // is, set to ``sys.maxint``, however the `context` may override
104273             // this behavior.
104274
104275             // NOTE: currently, this is being hardcoded to a maximum of 2GB for
104276             //       compatibility with funambol servers, which croak above that
104277             //       value.
104278
104279             // TODO: allow the context to control this, or implement auto-detect to
104280             //       determine what the remote peer can support...
104281
104282             return Math.min(Math.pow(2, exports.platformBits() - 1) - 1,
104283                     Math.pow(2, 31) - 1);
104284         },
104285
104286         //-------------------------------------------------------------------------
104287         normpath: function(path) {
104288             if ( path == undefined )
104289                 return null;
104290             if ( path.length <= 0 )
104291                 return '';
104292             if ( path.indexOf('/') < 0 )
104293                 path = path.replace('\\', '/');
104294             var ret = [];
104295             var plist = path.split('/');
104296             for ( var idx=0 ; idx<plist.length ; idx++ )
104297             {
104298                 var item = plist[idx];
104299                 if ( item.length <= 0 || item == '.' )
104300                     continue;
104301                 if ( item != '..' || ret.length <= 0 || ret[ret.length - 1] == '..' )
104302                 {
104303                     ret.push(item);
104304                     continue;
104305                 }
104306                 ret.pop();
104307             }
104308             ret = ret.join('/');
104309             if ( path.charAt(0) != '/' )
104310                 return ret;
104311             return '/' + ret;
104312         },
104313
104314         //-------------------------------------------------------------------------
104315         int: function(str, defval) {
104316             if ( ! str )
104317                 return defval;
104318             return parseInt(str, 10);
104319         },
104320
104321         //-------------------------------------------------------------------------
104322         cmp: function(a, b) {
104323             if ( a < b )
104324                 return -1;
104325             if ( a > b )
104326                 return 1;
104327             return 0;
104328         },
104329
104330         //-------------------------------------------------------------------------
104331         // partially emulates python's string.split() method
104332         splitn: function(str, sep, limit) {
104333             var ret = str.split(sep);
104334             if ( ret.length <= ( limit + 1 ) )
104335                 return ret;
104336             var tmp = ret.slice(0, limit);
104337             tmp.push(ret.slice(limit).join(sep));
104338             return tmp;
104339         },
104340
104341         //-------------------------------------------------------------------------
104342         prettyJson: function(obj, indent) {
104343             indent = indent || '';
104344             var ret = '';
104345             if ( _.isArray(obj) )
104346             {
104347                 if ( obj.length <= 0 )
104348                     return '[]';
104349                 ret = '[\n' + indent;
104350                 _.each(obj, function(el, idx) {
104351                     ret += '  ' + exports.prettyJson(el, indent + '  ');
104352                     if ( idx + 1 < obj.length )
104353                     ret += ',';
104354                 ret += '\n' + indent;
104355                 });
104356                 return ret + ']';
104357             }
104358             if ( _.isObject(obj) )
104359             {
104360                 var keys = _.keys(obj);
104361                 if ( keys.length <= 0 )
104362                     return '{}';
104363                 keys.sort();
104364                 ret = '{\n' + indent;
104365                     _.each(keys, function(key, idx) {
104366                         ret += '  ' + exports.prettyJson(key)
104367                         + ': ' + exports.prettyJson(obj[key], indent + '  ');
104368                     if ( idx + 1 < keys.length )
104369                         ret += ',';
104370                     ret += '\n' + indent;
104371                     });
104372                     return ret + ( indent.length <= 0 ? '}\n' : '}' );
104373             }
104374             return JSON.stringify(obj);
104375         },
104376
104377         //-------------------------------------------------------------------------
104378         urlEncode: function(dat) {
104379             return ( dat == undefined ? dat : encodeURIComponent(dat) );
104380         },
104381
104382         //-------------------------------------------------------------------------
104383         /*
104384            rmfr: function(path, cb) {
104385            fs.stat(path, function(err, stats) {
104386            if ( err && err.code == 'ENOENT' )
104387            return cb();
104388            if ( err )
104389            return cb(err);
104390            if ( ! stats.isDirectory() )
104391            return fs.unlink(path, cb);
104392            fs.readdir(path, function(err, files) {
104393            exports.cascade(files, function(file, cb) {
104394            var curpath = pathmod.join(path, file);
104395            return exports.rmfr(curpath, cb);
104396            }, function(err) {
104397            if ( err )
104398            return cb(err);
104399            fs.rmdir(path, cb);
104400            });
104401            });
104402            });
104403            },
104404            */
104405         //-------------------------------------------------------------------------
104406         /*
104407            makedirs: function(path, cb) {
104408         // node sucks. i can't believe it doesn't provide a fs.makedirs(). wtf.
104409         // clean up the path
104410         path = pathmod.normalize(path.split(/[\\\/]/).join('/'));
104411         var paths = path.split('/');
104412         paths = _.map(paths, function(p, idx) {
104413         return paths.slice(0, idx + 1).join('/');
104414         });
104415         if ( path.charAt(0) == '/' )
104416         paths.shift();
104417         exports.cascade(paths, function(path, cb) {
104418         fs.stat(path, function(err, stats) {
104419         if ( err && err.code == 'ENOENT' )
104420         return fs.mkdir(path, cb);
104421         if ( err )
104422         return cb(err);
104423         if ( stats.isDirectory() )
104424         return cb();
104425         // this probably won't work, but let's get the error anyhow...
104426         return fs.mkdir(path, cb);
104427         });
104428         }, cb);
104429         },
104430         */
104431
104432         //-------------------------------------------------------------------------
104433         StringStream: exports.Stream.extend({
104434
104435             constructor: function(initData) {
104436                 this._data = initData || '';
104437             },
104438
104439         write: function(data) {
104440             if ( data == undefined )
104441             return;
104442         this._data += data;
104443         },
104444
104445         getData: function() {
104446             return this._data;
104447         }
104448
104449         }),
104450
104451         //-------------------------------------------------------------------------
104452         IndentStream: exports.Stream.extend({
104453
104454             //-----------------------------------------------------------------------
104455             constructor: function(stream, indent, options) {
104456                 options = options || {};
104457                 this._stream    = stream;
104458                 this._indent    = indent || '  ';
104459                 this._cleared   = true;
104460                 this._stayBlank = !! options.stayBlank;
104461             },
104462
104463         //-----------------------------------------------------------------------
104464         write: function(data) {
104465             var self = this;
104466             if ( data == undefined )
104467             return;
104468         // if ( ! data || ! data.length || data.length <= 0 )
104469         //   return;
104470         var lines = data.split('\n');
104471         if ( self._cleared )
104472             self._stream.write(self._indent);
104473         self._cleared = false;
104474         for ( var idx=0 ; idx<lines.length ; idx++ )
104475         {
104476             var line = lines[idx];
104477             if ( line == '' )
104478             {
104479                 if ( idx + 1 >= lines.length )
104480                     self._cleared = true;
104481                 else
104482                 {
104483                     if ( idx != 0 && ! self._stayBlank )
104484                         self._stream.write(self._indent);
104485                 }
104486             }
104487             else
104488             {
104489                 if ( idx != 0 || self._cleared )
104490                     self._stream.write(self._indent);
104491                 self._stream.write(line);
104492             }
104493             if ( idx + 1 < lines.length )
104494                 self._stream.write('\n');
104495         }
104496         }
104497
104498         })
104499
104500     });
104501
104502     return exports;
104503 })();
104504
104505 module.exports = _self;
104506
104507 });
104508 define('ripple/platform/tizen/2.0/syncml-js-lib/constant', function (require, exports, module) {
104509 // -*- coding: utf-8 -*-
104510 //-----------------------------------------------------------------------------
104511 // file: $Id$
104512 // desc: SyncML constants
104513 // auth: metagriffin <metagriffin@uberdev.org>
104514 // date: 2012/10/13
104515 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
104516 //-----------------------------------------------------------------------------
104517
104518 var _self = {
104519     // SyncML versions
104520     SYNCML_VERSION_1_0                      : 'SyncML/1.0',
104521     SYNCML_VERSION_1_1                      : 'SyncML/1.1',
104522     SYNCML_VERSION_1_2                      : 'SyncML/1.2',
104523     SYNCML_DTD_VERSION_1_0                  : '1.0',
104524     SYNCML_DTD_VERSION_1_1                  : '1.1',
104525     SYNCML_DTD_VERSION_1_2                  : '1.2',
104526
104527     // SyncML alert/sync codes
104528     ALERT_DISPLAY                           : 100,
104529     ALERT_TWO_WAY                           : 200,
104530     ALERT_SLOW_SYNC                         : 201,
104531     ALERT_ONE_WAY_FROM_CLIENT               : 202,
104532     ALERT_REFRESH_FROM_CLIENT               : 203,
104533     ALERT_ONE_WAY_FROM_SERVER               : 204,
104534     ALERT_REFRESH_FROM_SERVER               : 205,
104535     ALERT_TWO_WAY_BY_SERVER                 : 206,
104536     ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER     : 207,
104537     ALERT_REFRESH_FROM_CLIENT_BY_SERVER     : 208,
104538     ALERT_ONE_WAY_FROM_SERVER_BY_SERVER     : 209,
104539     ALERT_REFRESH_FROM_SERVER_BY_SERVER     : 210,
104540     // alert codes 211-220 are reserved for future use
104541
104542     // SyncML SyncCap SyncTypes
104543     SYNCTYPE_AUTO                           : null,
104544     SYNCTYPE_TWO_WAY                        : 1,
104545     SYNCTYPE_SLOW_SYNC                      : 2,
104546     SYNCTYPE_ONE_WAY_FROM_CLIENT            : 3,
104547     SYNCTYPE_REFRESH_FROM_CLIENT            : 4,
104548     SYNCTYPE_ONE_WAY_FROM_SERVER            : 5,
104549     SYNCTYPE_REFRESH_FROM_SERVER            : 6,
104550     SYNCTYPE_SERVER_ALERTED                 : 7,
104551
104552     // Special syncml-js SyncTypes
104553     SYNCTYPE_DISCOVER                       : 'discover',
104554
104555     // SyncML synctype-to-alertcode mapping
104556     // taking advantage of the fact that 1..7 maps to 200..206
104557     // (more or less... "7" is a bit "nebulous"...)
104558     SyncTypeToAlert: _.object(_.map(_.range(7), function(i) {
104559         return [ i + 1, i + 200 ];
104560     })),
104561
104562     // Conflict handling policies
104563     POLICY_ERROR                            : 1,
104564     POLICY_CLIENT_WINS                      : 2,
104565     POLICY_SERVER_WINS                      : 3,
104566
104567     // SyncML XML namespaces
104568     NAMESPACE_SYNCML_1_0                    : 'syncml:syncml1.0',
104569     NAMESPACE_SYNCML_1_1                    : 'syncml:syncml1.1',
104570     NAMESPACE_SYNCML_1_2                    : 'syncml:syncml1.2',
104571     NAMESPACE_METINF                        : 'syncml:metinf',
104572     NAMESPACE_DEVINF                        : 'syncml:devinf',
104573     NAMESPACE_AUTH_BASIC                    : 'syncml:auth-basic',
104574     NAMESPACE_AUTH_MD5                      : 'syncml:auth-md5',
104575     NAMESPACE_FILTER_CGI                    : 'syncml:filtertype-cgi',
104576
104577     // Commonly used content-types
104578     TYPE_TEXT_PLAIN                         : 'text/plain',
104579     TYPE_VCARD_V21                          : 'text/x-vcard',
104580     TYPE_VCARD_V30                          : 'text/vcard',
104581     TYPE_VCALENDAR                          : 'text/x-vcalendar',
104582     TYPE_ICALENDAR                          : 'text/calendar',
104583     TYPE_MESSAGE                            : 'text/message',
104584     TYPE_SYNCML                             : 'application/vnd.syncml',
104585     TYPE_SYNCML_DEVICE_INFO                 : 'application/vnd.syncml-devinf',
104586     TYPE_SYNCML_ICALENDAR                   : 'application/vnd.syncml-xcal',
104587     TYPE_SYNCML_EMAIL                       : 'application/vnd.syncml-xmsg',
104588     TYPE_SYNCML_BOOKMARK                    : 'application/vnd.syncml-xbookmark',
104589     TYPE_SYNCML_RELATIONAL_OBJECT           : 'application/vnd.syncml-xrelational',
104590     TYPE_OMADS_FOLDER                       : 'application/vnd.omads-folder',
104591     TYPE_OMADS_FILE                         : 'application/vnd.omads-file',
104592     TYPE_OMADS_EMAIL                        : 'application/vnd.omads-email',
104593     TYPE_SQL                                : 'application/sql',
104594     TYPE_LDAP                               : 'text/directory',
104595     TYPE_EMAIL                              : 'message/rfc2822',
104596     TYPE_EMAIL_822                          : 'message/rfc822',
104597     TYPE_SIF_CONTACT                        : 'text/x-s4j-sifc',
104598     TYPE_SIF_NOTE                           : 'text/x-s4j-sifn',
104599     TYPE_SIF_TASK                           : 'text/x-s4j-sift',
104600     TYPE_SIF_EVENT                          : 'text/x-s4j-sife',
104601
104602     // non-agent URI paths
104603     URI_DEVINFO_1_0                         : 'devinf10',
104604     URI_DEVINFO_1_1                         : 'devinf11',
104605     URI_DEVINFO_1_2                         : 'devinf12',
104606
104607     // Response codes - Generic
104608     STATUS_INVALID_CODE                     : 0,
104609     // Response codes - Informational 1xx
104610     STATUS_IN_PROGRESS                      : 101,
104611     // Response codes - Successful 2xx
104612     STATUS_OK                               : 200,
104613     STATUS_ITEM_ADDED                       : 201,
104614     STATUS_ACCEPTED_FOR_PROCESSING          : 202,
104615     STATUS_NONAUTHORIATATIVE_RESPONSE       : 203,
104616     STATUS_NO_CONTENT                       : 204,
104617     STATUS_RESET_CONTENT                    : 205,
104618     STATUS_PARTIAL_CONTENT                  : 206,
104619     STATUS_CONFLICT_RESOLVED_MERGE          : 207,
104620     STATUS_CONFLICT_RESOLVED_CLIENT_DATA    : 208,
104621     STATUS_CONFLICT_RESOLVED_DUPLICATE      : 209,
104622     STATUS_DELETE_WITHOUT_ARCHIVE           : 210,
104623     STATUS_ITEM_NOT_DELETED                 : 211,
104624     STATUS_AUTHENTICATION_ACCEPTED          : 212,
104625     STATUS_CHUNKED_ITEM_ACCEPTED            : 213,
104626     STATUS_OPERATION_CANCELLED_OK           : 214,
104627     STATUS_NOT_EXECUTED                     : 215,
104628     STATUS_ATOMIC_ROLLBACK_OK               : 216,
104629     STATUS_RESULT_ALERT                     : 221,
104630     STATUS_NEXT_MESSAGE                     : 222,
104631     STATUS_NO_END_OF_DATA                   : 223,
104632     STATUS_SUSPEND                          : 224,
104633     STATUS_RESUME                           : 225,
104634     STATUS_DATA_MANAGEMENT                  : 226,
104635     // status codes 227-250 are reserved for future use,
104636     // Response codes - Redirection 3xx
104637     STATUS_MULTIPLE_CHOICES                 : 300,
104638     STATUS_MOVED_PERMANENTLY                : 301,
104639     STATUS_FOUND                            : 302,
104640     STATUS_SEE_ANOTHER_URI                  : 303,
104641     STATUS_NOT_MODIFIED                     : 304,
104642     STATUS_USE_PROXY                        : 305,
104643     // Response codes - Originator Exceptions 4xx
104644     STATUS_BAD_REQUEST                      : 400,
104645     STATUS_INVALID_CREDENTIALS              : 401,
104646     STATUS_PAYMENT_REQUIRED                 : 402,
104647     STATUS_FORBIDDEN                        : 403,
104648     STATUS_NOT_FOUND                        : 404,
104649     STATUS_COMMAND_NOT_ALLOWED              : 405,
104650     STATUS_OPTIONAL_FEATURE_NOT_SUPPORTED   : 406,
104651     STATUS_MISSING_CREDENTIALS              : 407,
104652     STATUS_REQUEST_TIMEOUT                  : 408,
104653     STATUS_UPDATE_CONFLICT                  : 409,
104654     STATUS_GONE                             : 410,
104655     STATUS_SIZE_REQUIRED                    : 411,
104656     STATUS_INCOMPLETE_COMMAND               : 412,
104657     STATUS_REQUESTED_ENTITY_TOO_LARGE       : 413,
104658     STATUS_URI_TOO_LONG                     : 414,
104659     STATUS_UNSUPPORTED_MEDIA_TYPE           : 415,
104660     STATUS_REQUESTED_SIZE_TOO_BIG           : 416,
104661     STATUS_RETRY_LATER                      : 417,
104662     STATUS_ALREADY_EXISTS                   : 418,
104663     STATUS_CONFLICT_RESOLVED_SERVER_DATA    : 419,
104664     STATUS_DEVICE_FULL                      : 420,
104665     STATUS_UNKNOWN_SEARCH_GRAMMAR           : 421,
104666     STATUS_BAD_CGI_SCRIPT                   : 422,
104667     STATUS_SOFT_DELETE_CONFLICT             : 423,
104668     STATUS_OBJECT_SIZE_MISMATCH             : 424,
104669     STATUS_PERMISSION_DENIED                : 425,
104670     // Response codes - Recipient Exceptions 5xx
104671     STATUS_COMMAND_FAILED                   : 500,
104672     STATUS_NOT_IMPLEMENTED                  : 501,
104673     STATUS_BAD_GATEWAY                      : 502,
104674     STATUS_SERVICE_UNAVAILABLE              : 503,
104675     STATUS_GATEWAY_TIMEOUT                  : 504,
104676     STATUS_VERSION_NOT_SUPPORTED            : 505,
104677     STATUS_PROCESSING_ERROR                 : 506,
104678     STATUS_ATOMIC_FAILED                    : 507,
104679     STATUS_REFRESH_REQUIRED                 : 508,
104680     STATUS_RECIPIENT_EXCEPTION_RESERVED1    : 509,
104681     STATUS_DATASTORE_FAILURE                : 510,
104682     STATUS_SERVER_FAILURE                   : 511,
104683     STATUS_SYNCHRONIZATION_FAILED           : 512,
104684     STATUS_PROTOCOL_VERSION_NOT_SUPPORTED   : 513,
104685     STATUS_OPERATION_CANCELLED              : 514,
104686     STATUS_ATOMIC_ROLLBACK_FAILED           : 516,
104687     STATUS_ATOMIC_RESPONSE_TOO_LARGE_TO_FIT : 517,
104688
104689     // SyncML codecs
104690     CODEC_XML                               : 'xml',
104691     CODEC_WBXML                             : 'wbxml',
104692     FORMAT_B64                              : 'b64',
104693     FORMAT_AUTO                             : 'auto',
104694
104695     // SyncML nodes
104696     NODE_SYNCML                             : 'SyncML',
104697     NODE_SYNCBODY                           : 'SyncBody',
104698
104699     // SyncML commands
104700     CMD_SYNCHDR                             : 'SyncHdr',
104701     CMD_SYNC                                : 'Sync',
104702     CMD_ALERT                               : 'Alert',
104703     CMD_STATUS                              : 'Status',
104704     CMD_GET                                 : 'Get',
104705     CMD_PUT                                 : 'Put',
104706     CMD_ADD                                 : 'Add',
104707     CMD_REPLACE                             : 'Replace',
104708     CMD_DELETE                              : 'Delete',
104709     CMD_RESULTS                             : 'Results',
104710     CMD_ATOMIC                              : 'Atomic',
104711     CMD_COPY                                : 'Copy',
104712     CMD_EXEC                                : 'Exec',
104713     CMD_MAP                                 : 'Map',
104714     CMD_MAPITEM                             : 'MapItem',
104715     CMD_SEARCH                              : 'Search',
104716     CMD_SEQUENCE                            : 'Sequence',
104717     CMD_FINAL                               : 'Final',
104718
104719     // SyncML standard device types
104720     DEVTYPE_HANDHELD                        : 'handheld',
104721     DEVTYPE_PAGER                           : 'pager',
104722     DEVTYPE_PDA                             : 'pda',
104723     DEVTYPE_PHONE                           : 'phone',
104724     DEVTYPE_SERVER                          : 'server',
104725     DEVTYPE_SMARTPHONE                      : 'smartphone',
104726     DEVTYPE_WORKSTATION                     : 'workstation',
104727
104728     // Item status codes
104729     ITEM_OK                                 : 0,
104730     ITEM_ADDED                              : 1,
104731     ITEM_MODIFIED                           : 2,
104732     ITEM_DELETED                            : 3,
104733     ITEM_SOFTDELETED                        : 4,
104734 };
104735
104736 module.exports = _self;
104737
104738 });
104739 define('ripple/platform/tizen/2.0/syncml-js-lib/context', function (require, exports, module) {
104740 // -*- coding: utf-8 -*-
104741 //-----------------------------------------------------------------------------
104742 // file: $Id$
104743 // lib:  syncml-js.context
104744 // auth: griffin <griffin@uberdev.org>
104745 // date: 2012/10/22
104746 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
104747 //-----------------------------------------------------------------------------
104748
104749 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
104750     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
104751     storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'),
104752     router = require('ripple/platform/tizen/2.0/syncml-js-lib/router'),
104753     synchronizer = require('ripple/platform/tizen/2.0/syncml-js-lib/synchronizer'),
104754     protocol = require('ripple/platform/tizen/2.0/syncml-js-lib/protocol'),
104755     localadapter = require('ripple/platform/tizen/2.0/syncml-js-lib/localadapter'),
104756     idxdb = {},
104757     _self;
104758
104759 // todo: is this the right place to put this?...
104760 //       the reason that i did not put it in the `define` call is
104761 //       because it needs access to `this.indexedDB`...
104762 var idxdb = {};
104763 if ( typeof(window) != 'undefined' && window.indexedDB )
104764 {
104765     idxdb.indexedDB   = window.indexedDB;
104766     idxdb.IDBKeyRange = window.IDBKeyRange;
104767 }
104768 else
104769 {
104770     idxdb.indexedDB   = this.indexedDB;
104771     idxdb.IDBKeyRange = this.IDBKeyRange;
104772 }
104773
104774 _self = (function () {
104775     var exports = {};
104776
104777     //---------------------------------------------------------------------------
104778     exports.Context = common.Base.extend({
104779
104780         //-------------------------------------------------------------------------
104781         constructor: function(options) {
104782             // options.storage expects the following properties:
104783             //   - indexedDB
104784             //   - IDBKeyRange
104785             options = options || {};
104786             this.storage      = options.storage || idxdb;
104787             this.dbname       = ( options.prefix || '' ) + 'syncml-js';
104788             this.autoCommit   = options.autoCommit == undefined ? true : options.autoCommit;
104789             this.router       = options.router || new router.SmartRouter();
104790             this.synchronizer = options.synchronizer || new synchronizer.Synchronizer();
104791             this.protocol     = options.protocol || new protocol.Protocol();
104792             this.codec        = options.codec || constant.CODEC_XML;
104793             this.listener     = options.listener;
104794             this.ua           = options.ua;
104795             this.config       = _.defaults({}, options.config, {
104796                 trustDevInfo      : false,
104797                 exposeErrorTrace  : false
104798             });
104799             this._db          = null;
104800             this._dbtxn       = null;
104801         },
104802
104803             //-------------------------------------------------------------------------
104804             getAdapter: function(options, devInfo, cb) {
104805                 options = options || {};
104806                 var self = this;
104807                 if ( this._db == undefined )
104808                 {
104809                     storage.openDatabase(this, function(err, db) {
104810                         if ( err ) {
104811                             return cb(err);
104812                         }
104813                         self._db = db;
104814                         self._db.onerror = function(event) {
104815                             // todo: remove this?...
104816                         };
104817                         self._dbtxn = storage.getTransaction(self._db, null, 'readwrite');
104818                         self.getAdapter(options, devInfo, cb);
104819                     });
104820                 }
104821                 else
104822                 {
104823                     var ret = new localadapter.LocalAdapter(this, options, devInfo);
104824                     return ret._load(cb);
104825                 }
104826             },
104827
104828             //-------------------------------------------------------------------------
104829             _txn: function() {
104830                 try {
104831                     // this is a work-around for XPC-based syncml... try to open
104832                     // a store, if it fails, we need a new transaction.
104833                     var store = this._dbtxn.objectStore('mapping');
104834                     return this._dbtxn;
104835                 } catch ( exc ) {
104836                     this._dbtxn = storage.getTransaction(this._db, null, 'readwrite');
104837                     return this._dbtxn;
104838                 }
104839             },
104840
104841             //-------------------------------------------------------------------------
104842             getEasyClientAdapter: function(options, cb) {
104843                 try{
104844                     this._getEasyClientAdapter(options, cb);
104845                 }catch(e){
104846                     cb(e);
104847                 }
104848             },
104849
104850             //-------------------------------------------------------------------------
104851             _getEasyClientAdapter: function(options, cb) {
104852                 // options should be:= {
104853                 //   // devID,
104854                 //   // displayName,
104855                 //   devInfo: {},
104856                 //   stores: [],
104857                 //   peer: {},
104858                 //   routes: [
104859                 //     [ source, target ],
104860                 //   ]
104861                 // }
104862                 // response: cb(err, adapter, stores, peer);
104863
104864                 var self = this;
104865
104866                 var ret = {
104867                     adapter: null,
104868                     stores: [],
104869                     peer: null
104870                 };
104871
104872                 var setupAdapter = function(cb) {
104873                     var adapterOptions = _.omit(options, 'devInfo', 'stores', 'peers', 'routes');
104874                     self.getAdapter(adapterOptions, options.devInfo, function(err, adapter) {
104875                         if ( err ) {
104876                             return cb(err);
104877                         }
104878                         ret.adapter = adapter;
104879                         if ( adapter.devInfo ) {
104880                             return cb();
104881                         }
104882                         adapter.setDevInfo(options.devInfo, cb);
104883                     });
104884                 };
104885
104886                 var setupStores = function(cb) {
104887                     common.cascade(options.stores, function(storeInfo, cb) {
104888                         var store = ret.adapter.getStore(storeInfo.uri);
104889                         if ( store != undefined )
104890                         {
104891                             if ( storeInfo.agent ) {
104892                                 store.agent = storeInfo.agent;
104893                             }
104894                             ret.stores.push(store);
104895                             return cb();
104896                         }
104897                         ret.adapter.addStore(storeInfo, function(err, store) {
104898                             if ( err ) {
104899                                 return cb(err);
104900                             }
104901                             ret.stores.push(store);
104902                             return cb();
104903                         });
104904                     }, cb);
104905                 };
104906
104907                 var setupPeer = function(cb) {
104908                     var peer = _.find(ret.adapter.getPeers(), function(p) {
104909                         return p.url == options.peer.url;
104910                     });
104911                     if ( peer )
104912                     {
104913                         ret.peer = peer;
104914                         return cb();
104915                     }
104916                     ret.adapter.addPeer(options.peer, function(err, peer) {
104917                         if ( err ) {
104918                             return cb(err);
104919                         }
104920                         ret.peer = peer;
104921                         common.cascade(options.routes, function(route, cb) {
104922                             ret.peer.setRoute(route[0], route[1], cb);
104923                         }, cb);
104924                     });
104925                 };
104926                 setupAdapter(function(err) {
104927                     if ( err ) {
104928                         return cb(err);
104929                     }
104930                     setupStores(function(err) {
104931                         if ( err ) {
104932                             return cb(err);
104933                         }
104934                         setupPeer(function(err) {
104935                             if ( err ) {
104936                                 return cb(err);
104937                             }
104938                             cb(null, ret.adapter, ret.stores, ret.peer);
104939                         });
104940                     });
104941                 });
104942             },
104943
104944             //-------------------------------------------------------------------------
104945             close: function(cb) {
104946                 if ( this._db )
104947                     this._db.close();
104948                 this._db = null;
104949                 cb(null);
104950             }
104951
104952     });
104953
104954     return exports;
104955
104956 })();
104957
104958 module.exports = _self;
104959
104960 });
104961 define('ripple/platform/tizen/2.0/syncml-js-lib/ctype', function (require, exports, module) {
104962 // -*- coding: utf-8 -*-
104963 //-----------------------------------------------------------------------------
104964 // file: $Id$
104965 // auth: metagriffin <metagriffin@uberdev.org>
104966 // date: 2012/10/13
104967 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
104968 //-----------------------------------------------------------------------------
104969 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
104970     ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'),
104971     _self;
104972
104973 _self = (function () {
104974
104975     var exports = {};
104976
104977     //---------------------------------------------------------------------------
104978     exports.ContentTypeInfo = common.Base.extend({
104979
104980         //-------------------------------------------------------------------------
104981         constructor: function(ctype, versions, options) {
104982             this.ctype    = ctype;
104983             this.versions = _.isArray(versions) ? versions : [versions];
104984             _.defaults(this, options || {}, {
104985                 preferred: false,
104986                 transmit:  true,
104987                 receive:   true,
104988             });
104989         },
104990
104991         //-------------------------------------------------------------------------
104992         merge: function(other) {
104993             if ( this.ctype != other.ctype
104994                 || ! _.isEqual(this.versions, other.versions)
104995                 || this.preferred != other.preferred )
104996                 return false;
104997             this.transmit = this.transmit || other.transmit;
104998             this.receive  = this.receive  || other.receive;
104999             return true
105000         },
105001
105002         //-------------------------------------------------------------------------
105003         toStruct: function() {
105004             return {
105005                 ctype: this.ctype,
105006                 versions: this.versions,
105007                 preferred: this.preferred,
105008                 transmit:  this.transmit,
105009                 receive:   this.receive
105010             };
105011         },
105012
105013         //-------------------------------------------------------------------------
105014         toSyncML: function(nodeName, uniqueVerCt) {
105015             if ( _.isFunction(nodeName) )
105016             {
105017                 cb = nodeName;
105018                 nodeName = null;
105019             }
105020             else if ( _.isFunction(uniqueVerCt) )
105021             {
105022                 cb = uniqueVerCt;
105023                 uniqueVerCt = null;
105024             }
105025             if ( ! nodeName )
105026             {
105027                 nodeName = this.transmit ? 'Tx' : 'Rx';
105028                 if ( this.preferred )
105029                     nodeName += '-Pref';
105030             }
105031             if ( this.preferred )
105032                 nodeName += '-Pref';
105033
105034             if ( uniqueVerCt )
105035             {
105036                 var ret = _.map(this.versions, function(v) {
105037                     var tmp = ET.Element(nodeName);
105038                     ET.SubElement(tmp, 'CTType').text = this.ctype;
105039                     ET.SubElement(tmp, 'VerCT').text = v;
105040                     return tmp;
105041                 }, this);
105042                 return ret;
105043             }
105044             var ret = ET.Element(nodeName);
105045             ET.SubElement(ret, 'CTType').text = this.ctype;
105046             _.each(this.versions, function(v) {
105047                 ET.SubElement(ret, 'VerCT').text = v;
105048             });
105049             return ret;
105050         },
105051
105052         describe: function(stream, cb) {
105053             stream.write(this.ctype);
105054             stream.write(this.versions.length == 1 ? ' version ' : ' versions ');
105055             stream.write(this.versions.join(', '));
105056             var flags = [];
105057             if ( this.preferred )
105058                 flags.push('preferred');
105059             if ( this.transmit )
105060                 flags.push('tx');
105061             if ( this.receive )
105062                 flags.push('rx');
105063             if ( flags.length > 0 )
105064             {
105065                 stream.write(' (');
105066                         stream.write(flags.join(', '));
105067                         stream.write(')');
105068                         }
105069                         stream.write('\n');
105070                         }
105071
105072                         }, {
105073
105074                             //-------------------------------------------------------------------------
105075                             fromStruct: function(struct) {
105076                                 return new exports.ContentTypeInfo(struct.ctype, struct.versions, struct);
105077                             },
105078
105079                     //-------------------------------------------------------------------------
105080                     fromSyncML: function(xnode) {
105081                         return new exports.ContentTypeInfo(
105082                             xnode.findtext('CTType'),
105083                             _.map(xnode.findall('VerCT'), function(e) { return e.text; }),
105084                             {
105085                                 preferred: xnode.tag.match('-Pref$') != undefined,
105086                         transmit:  xnode.tag.indexOf('Tx') >= 0,
105087                         receive:   xnode.tag.indexOf('Rx') >= 0
105088                             }
105089                             );
105090                     }
105091
105092                         });
105093
105094     return exports;
105095
105096 })();
105097
105098 module.exports = _self;
105099
105100 });
105101 define('ripple/platform/tizen/2.0/syncml-js-lib/devinfo', function (require, exports, module) {
105102 // -*- coding: utf-8 -*-
105103 //-----------------------------------------------------------------------------
105104 // file: $Id$
105105 // lib:  syncml-js.devinfo
105106 // auth: griffin <griffin@uberdev.org>
105107 // date: 2012/11/06
105108 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
105109 //-----------------------------------------------------------------------------
105110
105111 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
105112     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
105113     storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store'),
105114     ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'),
105115     _self;
105116
105117 _self = (function () {
105118
105119     var exports = {};
105120
105121     var strAttributeMap = [
105122     ['manufacturerName',    'Man'],
105123       ['modelName',           'Mod'],
105124       ['oem',                 'OEM'],
105125       ['firmwareVersion',     'FwV'],
105126       ['softwareVersion',     'SwV'],
105127       ['hardwareVersion',     'HwV'],
105128       ['devID',               'DevID'],
105129       ['devType',             'DevTyp']
105130     ];
105131
105132 var boolAttributeMap = [
105133     ['utc',                 'UTC'],
105134       ['largeObjects',        'SupportLargeObjs'],
105135       ['hierarchicalSync',    'SupportHierarchicalSync'],
105136       ['numberOfChanges',     'SupportNumberOfChanges']
105137     ];
105138
105139 //---------------------------------------------------------------------------
105140 exports.DevInfo = common.Base.extend({
105141
105142     //-------------------------------------------------------------------------
105143     constructor: function(adapter, options) {
105144         var self = this;
105145         var options = _.defaults({}, options, {
105146             devType           : constant.DEVTYPE_WORKSTATION,
105147             manufacturerName  : '-',
105148             modelName         : '-',
105149             oem               : '-',
105150             hardwareVersion   : '-',
105151             firmwareVersion   : '-',
105152             softwareVersion   : '-',
105153             utc               : true,
105154             largeObjects      : true,
105155             hierarchicalSync  : true,
105156             numberOfChanges   : true,
105157             extensions        : {}
105158         });
105159
105160         // todo: is there anyway to mark attributes as read-only?...
105161
105162         //: [read-only] these are all read-only attributes
105163         this.devID            = options.devID || common.makeID();
105164         this.devType          = options.devType;
105165         this.manufacturerName = options.manufacturerName;
105166         this.modelName        = options.modelName;
105167         this.oem              = options.oem;
105168         this.hardwareVersion  = options.hardwareVersion;
105169         this.firmwareVersion  = options.firmwareVersion;
105170         this.softwareVersion  = options.softwareVersion;
105171         this.utc              = options.utc;
105172         this.largeObjects     = options.largeObjects;
105173         this.hierarchicalSync = options.hierarchicalSync;
105174         this.numberOfChanges  = options.numberOfChanges;
105175         this.extensions       = {};
105176
105177         _.each(options.extensions, function(values, name) {
105178             self.setExtension(name, values);
105179         });
105180
105181         // --- private attributes
105182         this._a       = adapter;
105183     },
105184
105185         //-------------------------------------------------------------------------
105186         setExtension: function(name, values) {
105187             this.extensions[name] = _.isArray(values) ? values : [values];
105188         },
105189
105190         //-------------------------------------------------------------------------
105191         getExtensionKeys: function() {
105192             return _.keys(this.extensions);
105193         },
105194
105195         //-------------------------------------------------------------------------
105196         getExtension: function(name) {
105197             return this.extensions[name];
105198         },
105199
105200         //-------------------------------------------------------------------------
105201         _load: function(cb) {
105202             cb();
105203         },
105204
105205         //-------------------------------------------------------------------------
105206         _updateModel: function(cb) {
105207             if ( ! this._a._model )
105208                 return cb('devinfo created on un-initialized adapter');
105209             this._a._model.devInfo = {
105210                 devID            : this.devID,
105211                 devType          : this.devType,
105212                 manufacturerName : this.manufacturerName,
105213                 modelName        : this.modelName,
105214                 oem              : this.oem,
105215                 hardwareVersion  : this.hardwareVersion,
105216                 firmwareVersion  : this.firmwareVersion,
105217                 softwareVersion  : this.softwareVersion,
105218                 utc              : this.utc,
105219                 largeObjects     : this.largeObjects,
105220                 hierarchicalSync : this.hierarchicalSync,
105221                 numberOfChanges  : this.numberOfChanges,
105222                 extensions       : this.extensions
105223             };
105224             cb();
105225         },
105226
105227         //-------------------------------------------------------------------------
105228         toSyncML: function(dtdVersion, stores) {
105229             dtdVersion = dtdVersion || constant.SYNCML_DTD_VERSION_1_2;
105230             if ( dtdVersion != constant.SYNCML_DTD_VERSION_1_2 )
105231                 throw new Error('unsupported DTD version "' + dtdVersion + '"')
105232                     var xret = ET.Element('DevInf', {'xmlns': constant.NAMESPACE_DEVINF})
105233                     ET.SubElement(xret, 'VerDTD').text = dtdVersion;
105234             for ( var idx=0 ; idx<strAttributeMap.length ; idx++ )
105235             {
105236                 var map = strAttributeMap[idx];
105237                 // todo: should i enforce the fact that these are all *required*?...
105238                 if ( this[map[0]] != undefined )
105239                     ET.SubElement(xret, map[1]).text = this[map[0]];
105240             }
105241             for ( var idx=0 ; idx<boolAttributeMap.length ; idx++ )
105242             {
105243                 var map = boolAttributeMap[idx];
105244                 if ( this[map[0]] )
105245                     ET.SubElement(xret, map[1])
105246             }
105247             if ( stores && stores.length > 0 )
105248                 for ( var idx=0 ; idx<stores.length ; idx++ )
105249                     xret.append(stores[idx].toSyncML());
105250             var xext = null;
105251             for ( var name in this.extensions )
105252             {
105253                 if ( ! xext )
105254                     xext = ET.SubElement(xret, 'Ext');
105255                 ET.SubElement(xext, 'XNam').text = name;
105256                 var values = this.extensions[name];
105257                 for ( var idx=0 ; idx<values.length ; idx++ )
105258                     ET.SubElement(xext, 'XVal').text = '' + values[idx];
105259             };
105260             return xret;
105261         },
105262
105263 }, {
105264
105265     //-------------------------------------------------------------------------
105266     fromSyncML: function(xnode) {
105267         var options = {};
105268         var stores  = []
105269             var dtdVersion = xnode.findtext('VerDTD')
105270             if ( dtdVersion != constant.SYNCML_DTD_VERSION_1_2 )
105271                 throw new common.ProtocolError('unsupported DTD version "' + dtdVersion + '"');
105272         for ( var idx=0 ; idx<strAttributeMap.length ; idx++ )
105273         {
105274             var map = strAttributeMap[idx];
105275             // todo: should i enforce the fact that these are all *required*?...
105276             options[map[0]] = xnode.findtext(map[1]);
105277         }
105278         for ( var idx=0 ; idx<boolAttributeMap.length ; idx++ )
105279         {
105280             var map = boolAttributeMap[idx];
105281             options[map[0]] = xnode.find(map[1]) != undefined;
105282         }
105283         _.each(xnode.getchildren(), function(child) {
105284             if ( child.tag == 'DataStore' )
105285             return stores.push(storemod.Store.fromSyncML(child));
105286         if ( child.tag == 'Ext' )
105287         {
105288             options.extensions = {};
105289             var elist = child.getchildren();
105290             var ecur  = null;
105291             for ( var idx=0 ; idx<elist.length ; idx++ )
105292         {
105293             var eitem = elist[idx];
105294             if ( eitem.tag == 'XNam' )
105295         {
105296             ecur = eitem.text;
105297             continue;
105298         }
105299         if ( ! ecur )
105300             // paranoia...
105301             continue;
105302         if ( ! options.extensions[ecur] )
105303             options.extensions[ecur] = [];
105304         options.extensions[ecur].push(eitem.text);
105305         }
105306         return;
105307         }
105308         });
105309         return [new exports.DevInfo(null, options), stores];
105310     }
105311
105312 });
105313
105314 return exports;
105315
105316 })();
105317
105318 module.exports = _self;
105319
105320 });
105321 define('ripple/platform/tizen/2.0/syncml-js-lib/elementtree', function (require, exports, module) {
105322 /*
105323  *  Copyright 2013 Intel Corporation
105324  *
105325  * Licensed under the Apache License, Version 2.0 (the "License");
105326  * you may not use this file except in compliance with the License.
105327  * You may obtain a copy of the License at
105328  *
105329  * http://www.apache.org/licenses/LICENSE-2.0
105330  *
105331  * Unless required by applicable law or agreed to in writing, software
105332  * distributed under the License is distributed on an "AS IS" BASIS,
105333  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
105334  * See the License for the specific language governing permissions and
105335  * limitations under the License.
105336  */
105337
105338 var utils = require('ripple/utils'),
105339     _parser,
105340     _serializer,
105341     _self;
105342
105343 function _find(query, element, type) {
105344     var querylist = query.split("/"),
105345         e = element._node,
105346         tag, i, ret;
105347
105348     if (querylist.length === 0) {
105349         return undefined;
105350     }
105351
105352     for(i = 0; i < querylist.length; i++) {
105353         tag = querylist[i];
105354         try {
105355             e = e.getElementsByTagName(tag)[0];
105356         } catch (error) {
105357             e = undefined;
105358             break;
105359         }
105360     }
105361
105362     if (e) {
105363         if (type === "TEXT") {
105364             return e.textContent;
105365         } else if (type === "NODE") {
105366             ret = {
105367                 _doc: element,
105368                 _node: e,
105369                 find: function (query) {
105370                     return _find(query, this, "NODE");
105371                 },
105372                 findtext: function (query) {
105373                     return _find(query, this, "TEXT");
105374                 },
105375                 findall: function (query) {
105376                     return _findall(query, this);
105377                 },
105378                 getchildren: function () {
105379                     return _getchildren(this);
105380                 },
105381                 append: function (node) {
105382                     this._node.appendChild(node._node);
105383                 },
105384                 getroot: function () {
105385                     return this;
105386                 }
105387             };
105388             ret.__defineSetter__("text", function (text) {
105389                 this._node.textContent = text;
105390             });
105391             ret.__defineGetter__("text", function () {
105392                 return this._node.textContent;
105393             });
105394             ret.__defineGetter__("tag", function () {
105395                 return _tag(this);
105396             });
105397             return ret;
105398         }
105399     } else {
105400         return undefined;
105401     }
105402 }
105403
105404 function _findall(query, element) {
105405     var querylist = query.split("/"),
105406         e = element._node,
105407         tag,
105408         array,
105409         tmp,
105410         ret = [],
105411         i;
105412
105413     for(i = 0; i < querylist.length - 1; i++) {
105414         tag = querylist[i];
105415         try {
105416             e = e.getElementsByTagName(tag)[0];
105417         } catch (error) {
105418             return ret;
105419         }
105420     }
105421
105422     tag = querylist[querylist.length - 1];
105423     array = e.getElementsByTagName(tag);
105424     ///return ret;
105425     for(i = 0; i < array.length; i++) {
105426         tmp = {
105427             _doc: element,
105428             _node: array[i],
105429             find: function (query) {
105430                 return _find(query, this, "NODE");
105431             },
105432             findtext: function (query) {
105433                 return _find(query, this, "TEXT");
105434             },
105435             findall: function (query) {
105436                 return _findall(query, this);
105437             },
105438             getchildren: function () {
105439                 return _getchildren(this);
105440             },
105441             append: function (node) {
105442                 this._node.appendChild(node._node);
105443             },
105444             getroot: function () {
105445                 return this;
105446             }
105447         };
105448         tmp.__defineSetter__("text", function (text) {
105449             this._node.textContent = text;
105450         });
105451         tmp.__defineGetter__("text", function () {
105452             return this._node.textContent;
105453         });
105454         tmp.__defineGetter__("tag", function () {
105455             return _tag(this);
105456         });
105457         ret.push(tmp);
105458     }
105459     return ret;
105460 }
105461
105462 function _tag(element) {
105463     var array;
105464     array = element._node.tagName.split(":");
105465     return array[array.length - 1];
105466 }
105467
105468 function _getchildren(element) {
105469     var ret = [], e, i;
105470     for (i = 0; i < element._node.childNodes.length; i++) {
105471         e = {
105472             _doc: element,
105473             _node: element._node.childNodes[i],
105474             find: function (query) {
105475                 return _find(query, this, "NODE");
105476             },
105477             findtext: function (query) {
105478                 return _find(query, this, "TEXT");
105479             },
105480             findall: function (query) {
105481                 return _findall(query, this);
105482             },
105483             getchildren: function () {
105484                 return _getchildren(this);
105485             },
105486             append: function (node) {
105487                 this._node.appendChild(node._node);
105488             },
105489             getroot: function () {
105490                 return this;
105491             }
105492         };
105493         e.__defineSetter__("text", function (text) {
105494             this._node.textContent = text;
105495         });
105496         e.__defineGetter__("text", function () {
105497             return this._node.textContent;
105498         });
105499         e.__defineGetter__("tag", function () {
105500             return _tag(this);
105501         });
105502         ret.push(e);
105503     }
105504
105505     return ret;
105506 }
105507
105508
105509 _self = (function () {
105510     ET = {};
105511
105512     ET.Element = function(name, attributes) {
105513         var element = {},
105514             doc,
105515             node;
105516
105517         doc = _parser.parseFromString("<" + name + "></" + name + ">", "text/xml");
105518         node = doc.childNodes[0];
105519         if (attributes) {
105520             utils.forEach(attributes, function (value, key) {
105521                 node.setAttribute(key, value);
105522             });
105523         }
105524
105525         element = {
105526             _doc: doc,
105527             _node: node,
105528             find: function (query) {
105529                 return _find(query, this, "NODE");
105530             },
105531             findtext: function (query) {
105532                 return _find(query, this, "TEXT");
105533             },
105534             findall: function (query) {
105535                 return _findall(query, this);
105536             },
105537             getchildren: function () {
105538                 return _getchildren(this);
105539             },
105540             append: function (node) {
105541                 this._node.appendChild(node._node);
105542             },
105543             getroot: function () {
105544                 return this;
105545             }
105546         };
105547
105548         element.__defineSetter__("text", function (text) {
105549             this._node.textContent = text;
105550         });
105551
105552         element.__defineGetter__("text", function () {
105553             return this._node.textContent;
105554         });
105555
105556         element.__defineGetter__("tag", function () {
105557             return _tag(this);
105558         });
105559
105560         return element;
105561     };
105562
105563     ET.SubElement = function(element, name, attributes) {
105564         var subElement = {},
105565             node;
105566         node = element._doc.createElement(name);
105567         if (attributes) {
105568             utils.forEach(attributes, function (value, key) {
105569                 node.setAttribute(key, value);
105570             });
105571         }
105572         element._node.appendChild(node);
105573         subElement = {
105574             _doc: element._doc,
105575             _node: node,
105576             find: function (query) {
105577                 return _find(query, this, "NODE");
105578             },
105579             findtext: function (query) {
105580                 return _find(query, this, "TEXT");
105581             },
105582             findall: function (query) {
105583                 return _findall(query, this);
105584             },
105585             getchildren: function () {
105586                 return _getchildren(this);
105587             },
105588             append: function (node) {
105589                 this._node.appendChild(node._node);
105590             },
105591             getroot: function () {
105592                 return this;
105593             }
105594         };
105595         subElement.__defineSetter__("text", function (text) {
105596             this._node.textContent = text;
105597         });
105598         subElement.__defineGetter__("text", function () {
105599             return this._node.textContent;
105600         });
105601         subElement.__defineGetter__("tag", function () {
105602             return _tag(this);
105603         });
105604
105605         return subElement;
105606     };
105607
105608     ET.tostring = function(element) {
105609         return _serializer.serializeToString(element._node);
105610     };
105611     ET.parse = function(doc) {
105612         var element = {};
105613
105614         element = {
105615             _doc: doc,
105616             _node: doc.childNodes[0],
105617             find: function (query) {
105618                 return _find(query, this, "NODE");
105619             },
105620             findtext: function (query) {
105621                 return _find(query, this, "TEXT");
105622             },
105623             findall: function (query) {
105624                 return _findall(query, this);
105625             },
105626             getchildren: function () {
105627                 return _getchildren(this);
105628             },
105629             append: function (node) {
105630                 this._node.appendChild(node._node);
105631             },
105632             getroot: function () {
105633                 return this;
105634             }
105635         };
105636         element.__defineSetter__("text", function (text) {
105637             this._node.textContent = text;
105638         });
105639         element.__defineGetter__("text", function () {
105640             return this._node.textContent;
105641         });
105642         element.__defineGetter__("tag", function () {
105643             return _tag(this);
105644         });
105645
105646         return element;
105647     };
105648
105649     ET.CdataElement = function(str) {
105650         var doc, cdata;
105651         doc = _parser.parseFromString("<data></data>", "text/xml");
105652         cdata = doc.createCDATASection(str);
105653         return cdata;
105654     };
105655
105656     return ET;
105657 })();
105658
105659 _parser = new DOMParser();
105660 _serializer = new XMLSerializer();
105661
105662 module.exports = _self;
105663
105664 });
105665 define('ripple/platform/tizen/2.0/syncml-js-lib/item', function (require, exports, module) {
105666 // -*- coding: utf-8 -*-
105667 //-----------------------------------------------------------------------------
105668 // file: $Id$
105669 // lib:  syncml-js.item
105670 // auth: griffin <griffin@uberdev.org>
105671 // date: 2012/11/30
105672 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
105673 //-----------------------------------------------------------------------------
105674
105675 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common');
105676
105677 var _self = (function () {
105678     var exports = {};
105679
105680     //---------------------------------------------------------------------------
105681     exports.Item = common.Base.extend({
105682
105683         //: the unique identifier (within the context of a SyncML datastore)
105684         //: of the current SyncML item.
105685         id: null,
105686
105687         compare: function(other) {
105688             return ( other === this ? 0 : 1 );
105689         }
105690
105691     });
105692
105693     return exports;
105694
105695 })();
105696
105697 module.exports = _self;
105698
105699 });
105700 define('ripple/platform/tizen/2.0/syncml-js-lib/localadapter', function (require, exports, module) {
105701 // -*- coding: utf-8 -*-
105702 //-----------------------------------------------------------------------------
105703 // file: $Id$
105704 // lib:  syncml-js.localadapter
105705 // auth: griffin <griffin@uberdev.org>
105706 // date: 2012/10/22
105707 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
105708 //-----------------------------------------------------------------------------
105709
105710 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
105711     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
105712     codec = require('ripple/platform/tizen/2.0/syncml-js-lib/codec'),
105713     storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'),
105714     remote = require('ripple/platform/tizen/2.0/syncml-js-lib/remoteadapter'),
105715     storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store'),
105716     devinfomod = require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'),
105717     adapter = require('ripple/platform/tizen/2.0/syncml-js-lib/adapter'),
105718     state = require('ripple/platform/tizen/2.0/syncml-js-lib/state'),
105719     useragent = require('ripple/platform/tizen/2.0/syncml-js-lib/useragent'),
105720     _self;
105721
105722 _self = (function () {
105723     var exports = {};
105724
105725     //---------------------------------------------------------------------------
105726     exports.LocalAdapter = adapter.Adapter.extend({
105727
105728         //-------------------------------------------------------------------------
105729         constructor: function(context, options, devInfo) {
105730
105731             // todo: is there anyway to mark attributes as read-only?...
105732
105733             //: [read-only] devInfo describes this adapter's device info and
105734             //: capabilities.
105735             this.devInfo = null;
105736
105737             //: [read-only] the device ID of this adapter.
105738             this.devID = options.devID || null;
105739
105740             //: [read-only] specifies whether this Adapter represents a local
105741             //: or remote peer.
105742             this.isLocal = true;
105743
105744             //: [read-only] human-facing name of this adapter
105745             this.displayName = options.displayName || null;
105746
105747             //: [read-only] the adapter-wide default value of the maximum
105748             //: message size.
105749             this.maxMsgSize = options.maxMsgSize || null;
105750
105751             //: [read-only] the adapter-wide default value of the maximum
105752             //: object size.
105753             this.maxObjSize = options.maxObjSize || null;
105754
105755             //: [read-only] specifies default conflict resolution policy for
105756             //: this adapter. if undefined, defaults to constant.POLICY_ERROR.
105757             this.conflictPolicy = options.conflictPolicy || constant.POLICY_ERROR;
105758
105759             // --- private attributes
105760             this.id       = options.id || common.makeID();
105761             this._c       = context;
105762             // TODO: use _.pick() for these options...
105763             this._options = options;
105764             this._devInfo = devInfo;
105765             this._model   = null;
105766             this._stores  = {};
105767             this._peers   = [];
105768         },
105769
105770             //-------------------------------------------------------------------------
105771             _getModel: function() {
105772                 return this._model;
105773             },
105774
105775             //-------------------------------------------------------------------------
105776             setDevInfo: function(devInfo, cb) {
105777                 if ( this._model == undefined )
105778                     this._model = {
105779                         id              : this.id,
105780                         displayName     : this.displayName,
105781                         maxMsgSize      : this.maxMsgSize,
105782                         maxObjSize      : this.maxObjSize,
105783                         conflictPolicy  : this.conflictPolicy,
105784                         devInfo         : null,
105785                         stores          : [],
105786                         peers           : [],
105787                         isLocal         : 1
105788                     };
105789
105790                 var di = new devinfomod.DevInfo(this, devInfo);
105791                 di._updateModel(_.bind(function(err) {
105792                     if ( err )
105793                         return cb(err);
105794
105795                     this._model.devID = this._model.devInfo.devID;
105796                     this.devID        = this._model.devInfo.devID;
105797                     this.devInfo      = di;
105798
105799                 // since the local devinfo has changed, we need to ensure that
105800                 // we rebroadcast it (in case there are any affects...), thus
105801                 // resetting all anchors.
105802                 // TODO: this seems a little heavy-handed, since this will force
105803                 //       a slow-sync for each datastore. is that really the best
105804                 //       thing?...
105805                 this._resetAllAnchors();
105806
105807                 this._save(this._c._txn(), cb);
105808
105809                 }, this));
105810             },
105811
105812             //-------------------------------------------------------------------------
105813             _resetAllAnchors: function() {
105814                 _.each(this._model.peers, function(peer) {
105815                     _.each(peer.stores, function(store) {
105816                         if ( ! store.binding )
105817                         return;
105818                     store.binding.localAnchor  = null;
105819                     store.binding.remoteAnchor = null;
105820                     });
105821                 });
105822             },
105823
105824             //-------------------------------------------------------------------------
105825             getPeers: function() {
105826                 return this._peers;
105827             },
105828
105829             //-------------------------------------------------------------------------
105830             addPeer: function(peerInfo, cb) {
105831                 var self = this;
105832
105833                 // TODO: if there is already a peer for the specified URL, then
105834                 //       we may have a problem!...
105835
105836                 // todo: if we are adding a peer to an adapter that already has
105837                 //       non-client peers, then we may have a problem!...
105838                 //       (this is only true while syncml-js is not capable of truly
105839                 //       operating in peer-to-peer mode)
105840
105841                 var peer = new remote.RemoteAdapter(this, peerInfo);
105842                 peer._updateModel(function(err) {
105843                     if ( err )
105844                     return cb(err);
105845                 self._peers.push(peer);
105846                 cb(null, peer);
105847                 });
105848             },
105849
105850             //-------------------------------------------------------------------------
105851             save: function(cb) {
105852                 this._save(this._c._txn(), cb);
105853             },
105854
105855             //-------------------------------------------------------------------------
105856             _save: function(dbtxn, cb) {
105857                 var self = this;
105858                 self._updateModel(function(err) {
105859                     if ( err )
105860                     return cb(err);
105861                 storage.put(dbtxn.objectStore('adapter'), self._model, cb);
105862                 });
105863             },
105864
105865             //-------------------------------------------------------------------------
105866             _updateModel: function(cb) {
105867                 var self = this;
105868                 var model = self._model;
105869                 model.displayName    = self.displayName;
105870                 model.devID          = self.devID;
105871                 model.maxMsgSize     = self.maxMsgSize;
105872                 model.maxObjSize     = self.maxObjSize;
105873                 model.conflictPolicy = self.conflictPolicy;
105874                 model.isLocal        = 1;
105875                 common.cascade([
105876                         // update the devInfo model
105877                         function(cb) {
105878                             if ( ! self.devInfo )
105879                     return cb();
105880                 return self.devInfo._updateModel(cb);
105881                         },
105882                         // update the stores model
105883                         function(cb) {
105884                             model.stores = [];
105885                             common.cascade(_.values(self._stores), function(store, cb) {
105886                                 store._updateModel(cb);
105887                             }, cb);
105888                         },
105889
105890                         // update the peers model
105891                         function(cb) {
105892                             // NOTE: unlike stores, which can completely regenerate the
105893                             //       model based on the class, the peers store binding
105894                             //       and routing info is only in the model, so cannot be
105895                             //       completely deleted...
105896                             common.cascade(self._peers, function(peer, cb) {
105897                                 peer._updateModel(cb);
105898                             }, cb);
105899                         }
105900
105901                 ], cb);
105902             },
105903
105904             //-------------------------------------------------------------------------
105905             _load: function(cb) {
105906                 var self = this;
105907
105908                 // TODO: if options specifies a devID/name/etc, use that...
105909
105910                 storage.getAll(
105911                     this._c,
105912                     this._c._txn().objectStore('adapter').index('isLocal'),
105913                     {only: 1},
105914                     function(err, adapters) {
105915                         if ( err ) {
105916                             return cb(err);
105917                         }
105918                         if ( adapters.length > 1 )
105919                             return cb('multiple local adapters defined - specify which devID to load');
105920                         if ( adapters.length <= 0 )
105921                             return cb(null, self);
105922                         self._loadModel(adapters[0], function(err) {
105923                             if ( err )
105924                                 return cb(err);
105925                             return cb(null, self);
105926                         });
105927                     }
105928                 );
105929             },
105930
105931             //-------------------------------------------------------------------------
105932             _loadModel: function(model, cb) {
105933                 var self = this;
105934                 self._model         = model;
105935                 self.displayName    = model.displayName;
105936                 self.devID          = model.devID;
105937                 self.maxMsgSize     = model.maxMsgSize;
105938                 self.maxObjSize     = model.maxObjSize;
105939                 self.conflictPolicy = model.conflictPolicy;
105940                 common.cascade([
105941                         // load device info
105942                         function(cb) {
105943                             var di = new devinfomod.DevInfo(self, self._model.devInfo);
105944                             di._load(function(err) {
105945                                 if ( err )
105946                                 return cb(err);
105947                             self.devInfo = di;
105948                             cb();
105949                             });
105950                         },
105951                         // load stores
105952                         function(cb) {
105953                             common.cascade(model.stores, function(e, cb) {
105954                                 var store = new storemod.Store(self, e);
105955                                 store._load(function(err) {
105956                                     if ( err )
105957                                     return cb(err);
105958                                 self._stores[store.uri] = store;
105959                                 return cb();
105960                                 });
105961                             }, cb);
105962                         },
105963                         // load peers
105964                         function(cb) {
105965                             var remotes = _.filter(model.peers, function(e) {
105966                                 return ! e.isLocal;
105967                             });
105968                             self._peers = [];
105969                             common.cascade(remotes, function(e, cb) {
105970                                 var peer = new remote.RemoteAdapter(self, e);
105971                                 peer._load(function(err) {
105972                                     if ( err )
105973                                     return cb(err);
105974                                 self._peers.push(peer);
105975                                 return cb();
105976                                 });
105977                             }, cb);
105978                         }
105979                 ], cb);
105980             },
105981
105982             //-------------------------------------------------------------------------
105983             sync: function(peer, mode, options, cb) {
105984                 // `options` is optional and can have the following properties:
105985                 //   * `ua`
105986
105987                 // TODO: initialize a new context transaction?...
105988                 // todo: or perhaps add a new session.txn?...
105989
105990                 if ( cb == undefined && _.isFunction(options) )
105991                 {
105992                     cb = options;
105993                     options = {};
105994                 }
105995                 options = options || {};
105996
105997                 var self = this;
105998                 var discover = ( mode == constant.SYNCTYPE_DISCOVER );
105999                 if ( discover )
106000                     mode = constant.SYNCTYPE_SLOW_SYNC;
106001
106002                 if ( ! _.find(self._peers, function(p) { return p === peer; }) )
106003                     return cb(new common.InvalidAdapter('invalid peer for adapter'));
106004                 if ( mode != constant.SYNCTYPE_AUTO )
106005                 {
106006                     mode = common.synctype2alert(mode);
106007                     if ( ! mode )
106008                         return cb(new common.TypeError('invalid synctype'));
106009                 }
106010                 if ( ! self.devInfo )
106011                     return cb(new common.InvalidAdapter('cannot synchronize adapter as client: invalid devInfo'));
106012
106013                 var session = state.makeSession({
106014                     context  : self._c,
106015                     ua       : new useragent.UserAgentMultiplexer([options.ua, self._c.ua]),
106016                     txn      : _.bind(self._c._txn, self._c),
106017                     adapter  : self,
106018                     peer     : peer,
106019                     isServer : false,
106020                     discover : discover,
106021                     info     : state.makeSessionInfo({
106022                         id       : ( peer.lastSessionID || 0 ) + 1,
106023                     msgID    : 1,
106024                     codec    : self._c.codec,
106025                     mode     : mode
106026                     })
106027                 });
106028
106029                 session.send = function(contentType, data, cb) {
106030                     session.peer.sendRequest(session, contentType, data, function(err, response) {
106031                         if ( err )
106032                         return cb(err);
106033                     // todo: allow the client to force the server to authorize itself as well...
106034                     self._receive(session, response, null, cb);
106035                     });
106036                 };
106037
106038                 // TODO: should i do a router.calculate() at this point?
106039                 //       the reason is that if there was a sync, then a
106040                 //       .setRoute(), then things may have changed...
106041                 //       corner-case, yes... but still valid.
106042
106043                 var failed = 0;
106044
106045                 var startSession = function() {
106046                     session.context.protocol.initialize(session, null, function(err, commands) {
106047                         if ( err )
106048                         return cb(err);
106049                     self._transmit(session, commands, function(err) {
106050                         if ( err )
106051                     {
106052                         if ( ! ( err instanceof common.InvalidCredentials )
106053                             && ! ( err instanceof common.CredentialsRequired ) )
106054                             return cb(err);
106055                         if ( err instanceof common.InvalidCredentials )
106056                         failed += 1;
106057                     if ( failed > 100 )
106058                     {
106059                         return cb(err);
106060                     }
106061                     var credErr = err;
106062                     var uaEvent = {
106063                         session : session,
106064                         auth    : err.auth,
106065                         count   : failed
106066                     };
106067                     return session.ua.fetchCredentials(uaEvent, function(err, auth) {
106068                         if ( err )
106069                         return cb(err);
106070                     if ( ! auth )
106071                         return cb(credErr);
106072                     if ( auth.persist )
106073                     {
106074                         session.peer.auth = auth.type;
106075                         session.peer.username = auth.username;
106076                         session.peer.password = auth.password;
106077                     }
106078                     else
106079                         session.auth = auth;
106080                     // todo: should i just create a new session?...
106081                     session.info.id += 1;
106082                     session.info.msgID = 1;
106083                     return startSession();
106084                     });
106085                     }
106086                     self._save(session.txn(), function(err) {
106087                         if ( err )
106088                         return cb(err);
106089                     return cb(null, self._session2stats(session));
106090                     });
106091                     });
106092                     });
106093                 };
106094
106095                 session.context.synchronizer.initStoreSync(session, function(err) {
106096                     if ( err )
106097                     return cb(err);
106098                 startSession();
106099                 });
106100
106101             },
106102
106103             //-------------------------------------------------------------------------
106104             _session2stats: function(session) {
106105                 var ret = {};
106106                 _.each(_.values(session.info.dsstates), function(ds) {
106107                     var stats = _.clone(ds.stats);
106108                     stats.mode = common.alert2synctype(ds.mode);
106109                     if ( ds.action == 'error' && ds.error )
106110                     stats.error = ds.error;
106111                 ret[ds.uri] = stats;
106112                 });
106113                 return ret;
106114             },
106115
106116             //-------------------------------------------------------------------------
106117             _transmit: function(session, commands, cb) {
106118                 var self = this;
106119                 if ( session.info.msgID > 20 )
106120                     return cb('too many client/server messages');
106121                 session.context.protocol.negotiate(session, commands, function(err, commands) {
106122                     if ( err )
106123                     return cb(err);
106124                 if ( session.context.protocol.isComplete(session, commands) )
106125                 {
106126                     // we're done! store all the anchors and session IDs and exit...
106127                     var pmodel = session.peer._getModel();
106128                     if ( ! pmodel )
106129                     return cb('unexpected error: could not locate this peer in local adapter');
106130                 _.each(session.info.dsstates, function(ds, uri) {
106131                     var pstore = _.find(pmodel.stores, function(s) { return s.uri == ds.peerUri; });
106132                     if ( ! pstore )
106133                     return cb('unexpected error: could not locate bound peer store in local adapter');
106134                 pstore.binding.localAnchor  = ds.nextAnchor;
106135                 pstore.binding.remoteAnchor = ds.peerNextAnchor;
106136                 });
106137                 session.peer.lastSessionID = session.info.id;
106138                 pmodel.lastSessionID       = session.info.id;
106139                 return cb();
106140                 }
106141                 session.context.protocol.produce(session, commands, function(err, tree) {
106142                     if ( err )
106143                     return cb(err);
106144                 codec.Codec.autoEncode(tree, session.info.codec, function(err, contentType, data) {
106145                     if ( err )
106146                     return cb(err);
106147                 // update the session with the last request commands so
106148                 // that when we receive the response package, it can be
106149                 // compared against that.
106150                 // TODO: should that only be done on successful transmit?...
106151                 session.info.lastCommands = commands;
106152                 session.send(contentType, data, function(err) {
106153                     if ( err )
106154                     return cb(err);
106155                 cb();
106156                 });
106157                 })
106158                 });
106159                 });
106160             },
106161
106162             //-------------------------------------------------------------------------
106163             authorize: function(request, sessionInfo, authorize, cb) {
106164                 var self = this;
106165                 var ct   = request.headers['Content-Type'];
106166                 codec.Codec.autoDecode(ct, request.body, function(err, xtree, codecName) {
106167                     if ( err )
106168                     return cb(err);
106169                 self._c.protocol.authorize(xtree, null, authorize, cb);
106170                 });
106171             },
106172
106173             //-------------------------------------------------------------------------
106174             getTargetID: function(request, sessionInfo, cb) {
106175                 var self = this;
106176                 var ct   = request.headers['Content-Type'];
106177                 codec.Codec.autoDecode(ct, request.body, function(err, xtree, codecName) {
106178                     if ( err )
106179                     return cb(err);
106180                 return cb(null, self._c.protocol.getTargetID(xtree));
106181                 });
106182             },
106183
106184             //-------------------------------------------------------------------------
106185             handleRequest: function(request, sessionInfo, authorize, response, options, cb) {
106186
106187                 // TODO: initialize a new context transaction?...
106188                 // todo: or perhaps add a new session.txn?...
106189
106190                 if ( cb == undefined && _.isFunction(options) )
106191                 {
106192                     cb = options;
106193                     options = {};
106194                 }
106195                 options = options || {};
106196
106197                 var self = this;
106198                 var session = state.makeSession({
106199                     context  : self._c,
106200                     ua       : new useragent.UserAgentMultiplexer([options.ua, self._c.ua]),
106201                     txn      : _.bind(self._c._txn, self._c),
106202                     adapter  : self,
106203                     peer     : null,
106204                     isServer : true,
106205                     info     : sessionInfo
106206                 });
106207                 session.send = response;
106208                 this._receive(session, request, authorize, function(err, stats) {
106209                     if ( err )
106210                     return cb(err);
106211                 self._save(session.txn(), function(err) {
106212                     if ( err )
106213                     return cb(err);
106214                 return cb(null, self._session2stats(session));
106215                 });
106216                 });
106217             },
106218
106219             //-------------------------------------------------------------------------
106220             _receive: function(session, request, authorize, cb) {
106221                 var self = this;
106222                 if ( ! session.isServer )
106223                 {
106224                     session.info.lastMsgID = session.info.msgID;
106225                     session.info.msgID += 1;
106226                 }
106227                 var ct = request.headers['Content-Type'];
106228                 codec.Codec.autoDecode(ct, request.body, function(err, xtree, codecName) {
106229                     if ( err )
106230                     return cb(err);
106231                 session.info.codec = codecName;
106232                 var do_authorize = ( ! authorize ) ? common.noop : function(cb) {
106233                     session.context.protocol.authorize(xtree, null, authorize, function(err) {
106234                         return cb(err);
106235                     });
106236                 };
106237                 do_authorize(function(err) {
106238                     if ( err )
106239                     return cb(err);
106240                 session.context.protocol.consume(
106241                     session, session.info.lastCommands, xtree,
106242                     function(err, commands) {
106243                         if ( err ) {
106244                             return cb(err);
106245                         }
106246                         if ( session.discover && session.peer.devInfo )
106247                     return cb(null, self._session2stats(session));
106248                 self._transmit(session, commands, function(err) {
106249                     if ( err )
106250                     return cb(err);
106251                 if ( ! session.isServer )
106252                     return cb();
106253                 self._save(session.txn(), function(err) {
106254                     if ( err )
106255                     return cb(err);
106256                 return cb(null, self._session2stats(session));
106257                 });
106258                 });
106259                     }
106260                 );
106261                 });
106262                 })
106263             },
106264
106265     });
106266
106267     return exports;
106268
106269 })();
106270
106271 module.exports = _self;
106272
106273 });
106274 define('ripple/platform/tizen/2.0/syncml-js-lib/matcher', function (require, exports, module) {
106275 // -*- coding: utf-8 -*-
106276 //-----------------------------------------------------------------------------
106277 // file: $Id$
106278 // lib:  syncml-js.matcher
106279 // auth: griffin <griffin@uberdev.org>
106280 // date: 2012/12/05
106281 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
106282 //-----------------------------------------------------------------------------
106283
106284 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
106285     _self;
106286
106287 _self = (function () {
106288
106289     var exports = {};
106290
106291     //---------------------------------------------------------------------------
106292     exports._cntpref = function(source, target) {
106293         return ( source.preferred ? 1 : 0 ) + ( target.preferred ? 1 : 0 );
106294     };
106295
106296     //---------------------------------------------------------------------------
106297     exports._pickTransmitContentType = function(source, target, prefcnt, checkVersion) {
106298         for ( var sidx=0 ; sidx<source.length ; sidx++ )
106299 {
106300     var sct = source[sidx];
106301     for ( var tidx=0 ; tidx<target.length ; tidx++ )
106302 {
106303     var tct = target[tidx];
106304     if ( sct.ctype != tct.ctype )
106305     continue;
106306 if ( ! checkVersion )
106307 {
106308     if ( exports._cntpref(sct, tct) >= prefcnt )
106309         return [sct.ctype, sct.versions[sct.versions.length - 1]];
106310     continue;
106311 }
106312 for ( var svidx=sct.versions.length ; svidx>0 ; svidx-- )
106313 {
106314     var sv = sct.versions[svidx - 1]
106315         for ( var tvidx=tct.versions.length ; tvidx>0 ; tvidx-- )
106316         {
106317             var tv = tct.versions[tvidx - 1]
106318                 if ( sv != tv )
106319                     continue;
106320             if ( exports._cntpref(sct, tct) >= prefcnt )
106321                 return [sct.ctype, sv];
106322         }
106323 }
106324 }
106325 }
106326 return null;
106327 };
106328
106329 //---------------------------------------------------------------------------
106330 exports.pickTransmitContentType = function(source, target) {
106331
106332     // TODO: this is probably not the most efficient algorithm!...
106333     //       (but it works... ;-)
106334
106335     // order of preference:
106336     //   - transmit => receive, BOTH preferred, VERSION match
106337     //   - transmit => receive, ONE preferred, VERSION match
106338     //   - transmit => receive, neither preferred, VERSION match
106339     //   - transmit => receive, BOTH preferred, no version match
106340     //   - transmit => receive, ONE preferred, no version match
106341     //   - transmit => receive, neither preferred, no version match
106342     //   - tx/rx => tx/rx, BOTH preferred, VERSION match
106343     //   - tx/rx => tx/rx, ONE preferred, VERSION match
106344     //   - tx/rx => tx/rx, neither preferred, VERSION match
106345     //   - tx/rx => tx/rx, BOTH preferred, no version match
106346     //   - tx/rx => tx/rx, ONE preferred, no version match
106347     //   - tx/rx => tx/rx, neither preferred, no version match
106348
106349     // todo: make it explicit (or overrideable) that i am depending on the ordering
106350     //       of the versions supported to give an indicator of preference...
106351
106352     var sct = source.getContentTypes();
106353     var tct = target.getContentTypes();
106354
106355     var fct = function(cts, transmit) {
106356         return _.filter(cts, function(ct) {
106357             return transmit ? ct.transmit : ct.receive;
106358         });
106359     };
106360
106361     return exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 2, true)
106362         || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 1, true)
106363         || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 0, true)
106364         || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 2, false)
106365         || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 1, false)
106366         || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 0, false)
106367         || exports._pickTransmitContentType(sct, tct, 2, true)
106368         || exports._pickTransmitContentType(sct, tct, 1, true)
106369         || exports._pickTransmitContentType(sct, tct, 0, true)
106370         || exports._pickTransmitContentType(sct, tct, 2, false)
106371         || exports._pickTransmitContentType(sct, tct, 1, false)
106372         || exports._pickTransmitContentType(sct, tct, 0, false)
106373         || null;
106374
106375 };
106376
106377 // TODO: OH MY GOD.
106378 //       this is insanely inefficient.
106379 //       i'm embarrassed.
106380 //       fortunately, it's hidden really low-level...
106381 //       but now you know, doh! please don't blackmail me!... ;-)
106382
106383 // TODO: this currently requires that both tx and rx match in both
106384 //       directions with the same velocity... it should prioritize
106385 //       that, but then fallback to giving simplex matches priority.
106386
106387 //---------------------------------------------------------------------------
106388 var has_ct = function(a, b, checkVersion, transmit, wildcard) {
106389     a = _.filter(a, function(e) { return transmit ? e.transmit : e.receive });
106390     b = _.filter(b, function(e) { return transmit ? e.transmit : e.receive });
106391     for ( var aidx=0 ; aidx<a.length ; aidx++ )
106392     {
106393         var ct_a = a[aidx];
106394         for ( var bidx=0 ; bidx<b.length ; bidx++ )
106395         {
106396             var ct_b = b[bidx];
106397             if ( ct_a.ctype != ct_b.ctype )
106398                 continue;
106399             if ( ! checkVersion )
106400                 return true;
106401             for ( var vaidx=0 ; vaidx<ct_a.versions.length ; vaidx++ )
106402             {
106403                 var va = ct_a.versions[vaidx];
106404                 for ( var vbidx=0 ; vbidx<ct_b.length ; vbidx++ )
106405                 {
106406                     var vb = ct_b.versions[vbidx];
106407                     if ( va == vb )
106408                         return true;
106409                 }
106410             }
106411         }
106412     } 
106413     return false;
106414 };
106415
106416 //---------------------------------------------------------------------------
106417 var has_ct_both = function(a, b, checkVersion, wildcard) {
106418     return has_ct(a, b, checkVersion, true, wildcard)
106419         && has_ct(a, b, checkVersion, false, wildcard);
106420 };
106421
106422 //---------------------------------------------------------------------------
106423 var cmpStore_ct_set_crit = function(base, ds1, ds2, checkVersion, wildcard) {
106424     var bds1 = has_ct_both(base, ds1, checkVersion, wildcard);
106425     var bds2 = has_ct_both(base, ds2, checkVersion, wildcard);
106426     if ( bds1 && bds2 )
106427         return 0;
106428     if ( bds1 )
106429         return -1;
106430     if ( bds2 )
106431         return 1;
106432     return 0;
106433 };
106434
106435 //---------------------------------------------------------------------------
106436 var cmpStore_ct_set = function(base, ds1, ds2) {
106437     var ret = cmpStore_ct_set_crit(base, ds1, ds2, true, false);
106438     if ( ret != 0 )
106439         return ret;
106440     ret = cmpStore_ct_set_crit(base, ds1, ds2, false, false);
106441     if ( ret != 0 )
106442         return ret;
106443     ret = cmpStore_ct_set_crit(base, ds1, ds2, true, true);
106444     if ( ret != 0 )
106445         return ret;
106446     ret = cmpStore_ct_set_crit(base, ds1, ds2, false, true);
106447     if ( ret != 0 )
106448         return ret;
106449     return 0;
106450 };
106451
106452 //---------------------------------------------------------------------------
106453 var getct = function(store) {
106454     return store.getContentTypes ? store.getContentTypes() : store.contentTypes;
106455 };
106456
106457 //---------------------------------------------------------------------------
106458 var cmpStore_ct_pref = function(base, ds1, ds2) {
106459     var basect = _.filter(getct(base), function(ct) { return ct.preferred; });
106460     var ds1ct  = _.filter(getct(ds1), function(ct) { return ct.preferred; });
106461     var ds2ct  = _.filter(getct(ds2), function(ct) { return ct.preferred; });
106462     return cmpStore_ct_set(basect, ds1ct, ds2ct);
106463 };
106464
106465 //---------------------------------------------------------------------------
106466 var cmpStore_ct_all = function(base, ds1, ds2) {
106467     return cmpStore_ct_set(getct(base), getct(ds1), getct(ds2));
106468 };
106469
106470 //---------------------------------------------------------------------------
106471 var cmpStore_ct = function(base, ds1, ds2) {
106472     var ret = cmpStore_ct_pref(base, ds1, ds2)
106473         if ( ret != 0 )
106474             return ret;
106475     return cmpStore_ct_all(base, ds1, ds2);
106476 };
106477
106478 //---------------------------------------------------------------------------
106479 var cmpStore_uri = function(base, ds1, ds2) {
106480     var ret = difflib.getCloseMatches(base.uri, [ds1.uri, ds2.uri], 1, 0.5);
106481     if ( ret.length <= 0 )
106482         return 0;
106483     if ( ret[0] == ds1.uri )
106484         return -1;
106485     return 1;
106486 };
106487
106488 //---------------------------------------------------------------------------
106489 exports.cmpStore = function(base, ds1, ds2) {
106490     var ret = cmpStore_ct(base, ds1, ds2);
106491     if ( ret != 0 )
106492         return ret;
106493     return cmpStore_uri(base, ds1, ds2);
106494 };
106495
106496 return exports;
106497
106498 })();
106499
106500 module.exports = _self;
106501
106502
106503 });
106504 define('ripple/platform/tizen/2.0/syncml-js-lib/protocol', function (require, exports, module) {
106505 // -*- coding: utf-8 -*-
106506 //-----------------------------------------------------------------------------
106507 // file: $Id$
106508 // lib:  syncml-js.protocol
106509 // auth: griffin <griffin@uberdev.org>
106510 // date: 2012/11/04
106511 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
106512 //-----------------------------------------------------------------------------
106513
106514 var db = require('ripple/db'),
106515     common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
106516     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
106517     devinfo = require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'),
106518     state = require('ripple/platform/tizen/2.0/syncml-js-lib/state'),
106519     base64 = require('ripple/platform/tizen/2.0/syncml-js-lib/base64'),
106520     ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'),
106521     _firstflag = false,
106522     changednum, _counts;
106523
106524 var _self = (function () {
106525
106526     var exports = {};
106527
106528     //---------------------------------------------------------------------------
106529     var getError = function(xnode) {
106530         var ret = {
106531             message: xnode.findtext('Item/Data')
106532         };
106533         try{
106534             var xerr  = xnode.find('Error');
106535         }catch(e){
106536             var xerr = null;
106537         }
106538         if ( ! xerr )
106539 {
106540     try{
106541         var xerr  = xnode.find('Item/Error');
106542     }catch(e){
106543         var xerr = null;
106544     }
106545 }
106546 if ( ! xerr )
106547 {
106548     if ( ! ret.message )
106549         return null;
106550     return ret;
106551 }
106552 ret.code    = xerr.findtext('Code');
106553 ret.message = xerr.findtext('Message');
106554 ret.trace   = xerr.findtext('Trace');
106555 return ret;
106556 }
106557
106558 //---------------------------------------------------------------------------
106559 var badStatus = function(xnode, kls, attrs) {
106560     if ( ! kls )
106561         kls = common.ProtocolError;
106562     var code  = xnode.findtext('Data');
106563     var cname = xnode.findtext('Cmd');
106564     var msg   = null;
106565     if ( kls == common.ProtocolError )
106566         msg = 'unexpected status code ' + code + ' for command "' + cname + '"';
106567     else
106568         msg = 'received status code ' + code + ' for command "' + cname + '"';
106569     var error = getError(xnode);
106570     if ( error )
106571     {
106572         if ( error.code )
106573             msg += ': [' + error.code + '] ' + error.message;
106574         else
106575             msg += ': ' + error.message;
106576     }
106577     return new kls(msg, undefined, attrs)
106578 };
106579
106580 //---------------------------------------------------------------------------
106581 exports.getError  = getError;
106582 exports.badStatus = badStatus;
106583
106584 //---------------------------------------------------------------------------
106585 exports.Protocol = common.Base.extend({
106586
106587     //-------------------------------------------------------------------------
106588     constructor: function(options) {
106589     },
106590
106591     //-------------------------------------------------------------------------
106592     authorize: function(xtree, uri, authorize, cb) {
106593
106594         // TODO: if this session has been authorized before, don't call authorize
106595         //       ie.:
106596         //         if ( session.info.authAccepted )
106597         //           return cb();
106598         //       BUT this requires the session object... oops.
106599
106600         if ( ! authorize )
106601     authorize = function(uri, data, cb) { return cb(null, data); };
106602 if ( xtree.tag != 'SyncML' )
106603     throw new common.ProtocolError('root element was not "SyncML"');
106604 var xcred = xtree.find('SyncHdr/Cred');
106605 if ( ! xcred )
106606     return authorize(uri, null, cb);
106607 var data = xcred.findtext('Data');
106608 var authtype = xcred.findtext('Meta/Type');
106609 var format = xcred.findtext('Meta/Format');
106610 if ( format == constant.FORMAT_B64 )
106611     data = base64.decode(data);
106612 else if ( format )
106613     throw new common.UnknownFormatType(format);
106614 switch ( authtype )
106615 {
106616     case constant.NAMESPACE_AUTH_BASIC:
106617         {
106618             data = common.splitn(data, ':', 1);
106619             return authorize(uri, {
106620                 auth:     constant.NAMESPACE_AUTH_BASIC,
106621                    username: data[0],
106622                    password: data[1]
106623             }, cb);
106624         }
106625     case constant.NAMESPACE_AUTH_MD5:
106626         {
106627             return authorize(uri, {
106628                 auth:   constant.NAMESPACE_AUTH_BASIC,
106629                    digest: data
106630             }, cb);
106631         }
106632     default:
106633         {
106634             return cb(new common.UnknownAuthType(
106635                         'unknown/unimplemented auth type "' + authtype + '"'));
106636         }
106637 }
106638 },
106639
106640     //-------------------------------------------------------------------------
106641     getTargetID: function(xtree) {
106642         if ( xtree.tag != 'SyncML' )
106643             throw new common.ProtocolError('root element was not "SyncML"');
106644         // todo: do more validity checks?...
106645         return xtree.findtext('SyncHdr/Target/LocURI');
106646     },
106647
106648     //-------------------------------------------------------------------------
106649     isComplete: function(session, commands) {
106650         return (! session.isServer
106651                 && commands.length == 3
106652                 && commands[0].name == constant.CMD_SYNCHDR
106653                 && commands[1].name == constant.CMD_STATUS
106654                 && commands[1].statusOf == constant.CMD_SYNCHDR
106655                 && commands[1].statusCode == constant.STATUS_OK
106656                 && commands[2].name == constant.CMD_FINAL
106657                );
106658     },
106659
106660     //----------------------<---------------------------------------------------
106661     initialize: function(session, xtree, cb) {
106662         var cmd = state.makeCommand({
106663             name        : constant.CMD_SYNCHDR,
106664         cmdID       : 0,
106665         version     : constant.SYNCML_VERSION_1_2,
106666         source      : session.info.effectiveID || session.adapter.devID,
106667         sourceName  : session.adapter.displayName,
106668         respUri     : session.isServer ? session.info.returnUrl : null
106669         });
106670
106671         var checkPeer = ( ! session.isServer ) ? function(cb) {
106672             if ( ! xtree )
106673                 return cb();
106674             var xhdr = xtree.find('SyncHdr');
106675             // todo: check peer id...
106676             if ( session.info.id != common.int(xhdr.findtext('SessionID')) )
106677             {
106678                 return cb(new common.ProtocolError('session ID mismatch "'
106679                             + xhdr.findtext('SessionID')
106680                             + '" (expected: ' + session.info.id + ')'));
106681                         }
106682                         // todo: check message id...
106683                         cb();
106684                         } : function(cb) {
106685                             var xhdr = xtree.find('SyncHdr');
106686                             var peerID = xhdr.findtext('Source/LocURI');
106687                             if ( session.info.peerID && session.info.peerID != peerID )
106688                 {
106689                     return cb(new common.ProtocolError('unexpected peer ID "' + peerID + '"'));
106690                 }
106691                 if ( session.peer && session.peer.devID != peerID )
106692                 {
106693                     return cb(new common.ProtocolError('unacceptable peer ID "' + peerID + '"'));
106694                 }
106695                 session.info.peerID = peerID;
106696                 // check that no session swapping occurred
106697                 if ( session.info.id != undefined
106698                     && session.info.id != common.int(xhdr.findtext('SessionID')) )
106699                 {
106700                     return cb(new common.ProtocolError('session ID mismatch "'
106701                                 + xhdr.findtext('SessionID')
106702                                 + '" (expected: ' + session.info.id + ')'));
106703                             }
106704                             session.info.id     = common.int(xhdr.findtext('SessionID'));
106705                             session.info.msgID  = common.int(xhdr.findtext('MsgID'));
106706                             if ( session.peer && session.peer.devID == peerID )
106707                             return cb();
106708                             // TODO: i should delete unused peers here... ie. anything that
106709                             //       hasn't been used in some configurable number of seconds,
106710                             //       which should probably default to something like a month...
106711                             session.peer = _.find(session.adapter.getPeers(), function(peer) {
106712                                 return ( peer.devID == peerID );
106713                             });
106714                             if ( session.peer )
106715                             {
106716                                 return cb();
106717                             }
106718                             var peerInfo = {
106719                                 devID:        peerID,
106720                            displayName:  xhdr.findtext('Source/LocName'),
106721                            maxMsgSize:   common.int(xhdr.findtext('Meta/MaxMsgSize')),
106722                            maxObjSize:   common.int(xhdr.findtext('Meta/MaxObjSize'))
106723                             };
106724                             session.adapter.addPeer(peerInfo, function(err, peer) {
106725                                 if ( err )
106726                                 return cb(err);
106727                             session.peer = peer;
106728                             return cb();
106729                             });
106730                         };
106731
106732         checkPeer(function(err) {
106733
106734             session.info.cmdID        = 0;
106735             session.info.pendingMsgID = ( session.isServer
106736                 ? session.info.msgID
106737                 : session.info.lastMsgID );
106738             cmd.sessionID   = session.info.id;
106739             cmd.msgID       = session.info.msgID;
106740             cmd.target      = session.peer ? session.peer.devID || null : null;
106741             cmd.targetName  = session.peer ? session.peer.displayName || null : null;
106742             cmd.auth        = session.auth
106743             ? session.auth.type
106744             : session.peer
106745             ? session.peer.auth
106746             : null;
106747
106748         if ( err )
106749             return cb(err, [cmd]);
106750
106751         if ( cmd.msgID == 1 )
106752         {
106753             // NOTE: normally, the "server" would not send this info. however, in
106754             //       the syncml-js world where it is much more peer-oriented
106755             //       instead of client/server, i send this as well... the
106756             //       idea being, if two "client" peers are communicating in
106757             //       the event of server unavailability, then they may need
106758             //       to know each-others limitations...
106759             cmd.maxMsgSize = common.getMaxMemorySize(session.context);
106760             cmd.maxObjSize = common.getMaxMemorySize(session.context);
106761             ///cmd.maxMsgSize = 150000;
106762             ///cmd.maxObjSize = 4000000;
106763         }
106764         cb(null, [cmd]);
106765         });
106766     },
106767
106768     //-------------------------------------------------------------------------
106769     negotiate: function(session, commands, cb) {
106770         // // todo: determine why i decided to clone the commands...
106771         // commands = _.clone(commands);
106772
106773         if ( commands.length > 0 && _.last(commands).name == constant.CMD_FINAL )
106774             return cb(null, commands);
106775
106776         if ( commands.length > 0
106777                 && _.last(commands).name == constant.CMD_ALERT
106778                 && _.last(commands).data == constant.STATUS_NEXT_MESSAGE )
106779             // todo: should i add a "final" here?...
106780             // commands.push(state.makeCommand({name: constant.CMD_FINAL}));
106781             return cb(null, commands);
106782
106783         var createDevInfoCommands = function(commands, cb) {
106784             // todo: this flag is crap. instead, the local devInfo should have
106785             //       a record of which sessionID lead to the recording, and
106786             //       base it on that. maybe timestamp too... (but it must be
106787             //       in the minutes, just in case...)
106788             session.info.gotinfo = true;
106789             if ( ! session.discover )
106790             {
106791                 commands.push(state.makeCommand({
106792                     name       : constant.CMD_PUT,
106793                     cmdID      : session.nextCmdID(),
106794                     type       : constant.TYPE_SYNCML_DEVICE_INFO + '+' + session.info.codec,
106795                     source     : './' + constant.URI_DEVINFO_1_2,
106796                     data       : session.adapter.devInfo.toSyncML(constant.SYNCML_DTD_VERSION_1_2,
106797                         _.values(session.adapter._stores))
106798                 }));
106799             }
106800             commands.push(state.makeCommand({
106801                 name     : constant.CMD_GET,
106802                 cmdID    : session.nextCmdID(),
106803                 type     : constant.TYPE_SYNCML_DEVICE_INFO + '+' + session.info.codec,
106804                 target   : './' + constant.URI_DEVINFO_1_2
106805             }));
106806             return cb(null, commands);
106807         };
106808
106809         var createCommands = function(commands, cb) {
106810             // request the remote device info if not currently available or
106811             // in discover mode or explicitly re-exchanging it (paranoid mode)
106812             var putget = false;
106813             if ( !! session.discover )
106814             {
106815                 return createDevInfoCommands(commands, cb);
106816             }
106817             if ( ! session.peer.devInfo )
106818             {
106819                 var uaEvent = {session: session};
106820                 return session.ua.acceptDevInfoSwap(uaEvent, function(err) {
106821                     if ( err )
106822                 {
106823                     return cb(err);
106824                 }
106825                 return createDevInfoCommands(commands, cb);
106826                 });
106827             }
106828             if ( ! session.context.config.trustDevInfo && ! session.info.gotinfo )
106829             {
106830                 return createDevInfoCommands(commands, cb);
106831             }
106832             // NOTE: in the current handling of "trustDevInfo", i am doing a
106833             //       potentially unnecessary extra request/response phase to
106834             //       confirm that the devInfo has not changed... i *could*
106835             //       issue the put/get as well as the alert, *assuming* that
106836             //       no devInfo is going to change...
106837             return session.context.synchronizer.actions(session, commands, cb);
106838         };
106839
106840         return createCommands(commands, function(err, commands) {
106841             if ( err )
106842             return cb(err);
106843         //Hack: Memotoo service need to send alert command at the beging
106844         var args, tmp;
106845         args = db.retrieveObject("syncml-alert-args");
106846         tmp = {
106847             name       : constant.CMD_ALERT,
106848                cmdID      : session.nextCmdID(),
106849                data       : args.data,
106850                source     : args.source,
106851                target     : args.target,
106852                maxObjSize : "4000000"
106853         };
106854         if (args.lastAnchor) {
106855             tmp.lastAnchor = args.lastAnchor;
106856         }
106857
106858         if (args.nextAnchor) {
106859             tmp.nextAnchor = args.nextAnchor;
106860         }
106861         _firstflag = db.retrieveObject("syncml-first-flag");
106862         if( !_firstflag) {
106863             commands.push(state.makeCommand(tmp));
106864             db.saveObject("syncml-first-flag", true);
106865         }
106866         commands.push(state.makeCommand({name: constant.CMD_FINAL}));
106867         cb(null, commands);
106868         });
106869     },
106870
106871     //-------------------------------------------------------------------------
106872     // NOTE: `produce` is equivalent to the `pysyncml.protocol.commands2tree`...
106873     // Consumes state.Command commands and converts them to an ET protocol tree
106874     produce: function(session, commands, cb) {
106875
106876         if ( commands.length <= 0 )
106877             return cb('protocol.produce received empty commands');
106878
106879         var hdrcmd = commands[0];
106880         commands = _.rest(commands, 1);
106881
106882         if ( hdrcmd.name != constant.CMD_SYNCHDR )
106883             return cb('unexpected first command "' + hdrcmd.name + '"');
106884
106885         if ( hdrcmd.version != constant.SYNCML_VERSION_1_2 )
106886             return cb('unsupported SyncML version "' + hdrcmd.version + '"');
106887
106888         var xsync = ET.Element(constant.NODE_SYNCML);
106889         var xhdr  = ET.SubElement(xsync, hdrcmd.name);
106890         if ( hdrcmd.version == constant.SYNCML_VERSION_1_2 )
106891         {
106892             ET.SubElement(xhdr, 'VerDTD').text = constant.SYNCML_DTD_VERSION_1_2;
106893             ET.SubElement(xhdr, 'VerProto').text = hdrcmd.version;
106894         }
106895
106896         ET.SubElement(xhdr, 'SessionID').text = hdrcmd.sessionID;
106897         ET.SubElement(xhdr, 'MsgID').text = hdrcmd.msgID;
106898         var xsrc = ET.SubElement(xhdr, 'Source');
106899         ET.SubElement(xsrc, 'LocURI').text = hdrcmd.source;
106900         if ( hdrcmd.sourceName )
106901             ET.SubElement(xsrc, 'LocName').text = hdrcmd.sourceName;
106902         var xtgt = ET.SubElement(xhdr, 'Target');
106903         ET.SubElement(xtgt, 'LocURI').text = hdrcmd.target;
106904         if ( hdrcmd.targetName )
106905             ET.SubElement(xtgt, 'LocName').text = hdrcmd.targetName;
106906         if ( hdrcmd.respUri )
106907             ET.SubElement(xhdr, 'RespURI').text = hdrcmd.respUri;
106908
106909         if ( hdrcmd.auth && ! session.info.authAccepted )
106910         {
106911             // TODO: implement other auth schemes...
106912             if ( hdrcmd.auth != constant.NAMESPACE_AUTH_BASIC )
106913                 return cb('auth method "' + hdrcmd.auth + '" not implemented');
106914
106915             if ( hdrcmd.auth == constant.NAMESPACE_AUTH_BASIC )
106916             {
106917                 var xcred = ET.SubElement(xhdr, 'Cred');
106918                 var xmeta = ET.SubElement(xcred, 'Meta');
106919                 ET.SubElement(xmeta, 'Format', {'xmlns': constant.NAMESPACE_METINF}).text = 'b64';
106920                 ET.SubElement(xmeta, 'Type', {'xmlns': constant.NAMESPACE_METINF}).text   = hdrcmd.auth;
106921                 ET.SubElement(xcred, 'Data').text = base64.encode(
106922                         ( session.auth ? session.auth.username : session.peer.username )
106923                         + ':' + ( session.auth ? session.auth.password : session.peer.password ) );
106924             }
106925
106926         }
106927         if ( hdrcmd.maxMsgSize || hdrcmd.maxObjSize )
106928         {
106929             var xmeta = ET.SubElement(xhdr, 'Meta');
106930             if ( hdrcmd.maxMsgSize )
106931                 ET.SubElement(xmeta, 'MaxMsgSize',
106932                         {'xmlns': constant.NAMESPACE_METINF}).text = hdrcmd.maxMsgSize;
106933             if ( hdrcmd.maxObjSize )
106934                 ET.SubElement(xmeta, 'MaxObjSize',
106935                         {'xmlns': constant.NAMESPACE_METINF}).text = hdrcmd.maxObjSize;
106936         }
106937
106938         var xbody = ET.SubElement(xsync, constant.NODE_SYNCBODY);
106939
106940         for ( var idx=0 ; idx<commands.length ; idx++ )
106941         {
106942             var cmd  = commands[idx];
106943             var xcmd = ET.SubElement(xbody, cmd.name);
106944             if ( cmd.cmdID != undefined )
106945                 ET.SubElement(xcmd, 'CmdID').text = cmd.cmdID;
106946             var func = this['_produce_cmd_' + cmd.name.toLowerCase()];
106947             if ( ! func )
106948                 return cb(new common.InternalError('unexpected command "' + cmd.name + '"'));
106949             try{
106950                 func.call(this, session, cmd, xcmd);
106951             }catch(e){
106952                 return cb(new common.InternalError(
106953                             'failed invoking protocol sub-production of "' + cmd.name + '": ' + e, e));
106954             }
106955             if ( cmd.name == constant.CMD_FINAL && idx + 1 != commands.length )
106956                 return cb('command "' + cmd.name + '" not at end of commands');
106957         }
106958
106959         cb(null, xsync);
106960     },
106961
106962     //-------------------------------------------------------------------------
106963     _produce_cmd_alert: function(session, cmd, xcmd) {
106964         ET.SubElement(xcmd, 'Data').text = cmd.data;
106965         var xitem = ET.SubElement(xcmd, 'Item');
106966         ET.SubElement(ET.SubElement(xitem, 'Source'), 'LocURI').text = cmd.source;
106967         ET.SubElement(ET.SubElement(xitem, 'Target'), 'LocURI').text = cmd.target;
106968         if ( cmd.lastAnchor || cmd.nextAnchor || cmd.maxObjSize )
106969         {
106970             var xmeta = ET.SubElement(xitem, 'Meta');
106971             var xanch = ET.SubElement(xmeta, 'Anchor', {'xmlns': constant.NAMESPACE_METINF});
106972             if ( cmd.lastAnchor )
106973                 ET.SubElement(xanch, 'Last').text = cmd.lastAnchor;
106974             if ( cmd.nextAnchor )
106975                 ET.SubElement(xanch, 'Next').text = cmd.nextAnchor;
106976             if ( cmd.maxObjSize )
106977                 ET.SubElement(xmeta, 'MaxObjSize',
106978                         {'xmlns': constant.NAMESPACE_METINF}).text = cmd.maxObjSize;
106979         }
106980     },
106981
106982     //-------------------------------------------------------------------------
106983     _produce_cmd_status: function(session, cmd, xcmd) {
106984         ET.SubElement(xcmd, 'MsgRef').text    = '' + cmd.msgRef;
106985         ET.SubElement(xcmd, 'CmdRef').text    = '' + cmd.cmdRef;
106986         ET.SubElement(xcmd, 'Cmd').text       = cmd.statusOf;
106987         if ( cmd.sourceRef )
106988             ET.SubElement(xcmd, 'SourceRef').text = cmd.sourceRef;
106989         if ( cmd.targetRef )
106990             ET.SubElement(xcmd, 'TargetRef').text = cmd.targetRef;
106991         ET.SubElement(xcmd, 'Data').text      = cmd.statusCode;
106992         var xitem = null;
106993         var xdata = null;
106994         if ( cmd.nextAnchor || cmd.lastAnchor )
106995         {
106996             xitem = ET.SubElement(xcmd, 'Item');
106997             xdata = ET.SubElement(xitem, 'Data');
106998             var xanch = ET.SubElement(xdata, 'Anchor', {'xmlns': constant.NAMESPACE_METINF});
106999             if ( cmd.lastAnchor )
107000                 ET.SubElement(xanch, 'Last').text = cmd.lastAnchor;
107001             if ( cmd.nextAnchor )
107002                 ET.SubElement(xanch, 'Next').text = cmd.nextAnchor;
107003         }
107004         // NOTE: this is NOT standard SyncML...
107005         if ( cmd.errorCode || cmd.errorMsg )
107006         {
107007             xitem = xitem || ET.SubElement(xcmd, 'Item');
107008             xdata = xdata || ET.SubElement(xitem, 'Data');
107009             var xerr = ET.SubElement(xitem, 'Error');
107010             xdata.text = cmd.errorMsg;
107011             if ( cmd.errorCode )
107012                 ET.SubElement(xerr, 'Code').text = cmd.errorCode;
107013             if ( cmd.errorMsg )
107014                 ET.SubElement(xerr, 'Message').text = cmd.errorMsg;
107015             if ( session.context.config.exposeErrorTrace && cmd.errorTrace )
107016                 ET.SubElement(xerr, 'Trace').text = cmd.errorTrace;
107017         }
107018     },
107019
107020     //-------------------------------------------------------------------------
107021     _produce_cmd_get: function(session, cmd, xcmd) {
107022         ET.SubElement(ET.SubElement(xcmd, 'Meta'), 'Type',
107023                 {'xmlns': constant.NAMESPACE_METINF}).text = cmd.type;
107024         if ( cmd.source || cmd.target || cmd.data )
107025         {
107026             var xitem = ET.SubElement(xcmd, 'Item');
107027             if ( cmd.source )
107028             {
107029                 var xsrc = ET.SubElement(xitem, 'Source');
107030                 ET.SubElement(xsrc, 'LocURI').text  = cmd.source;
107031                 ET.SubElement(xsrc, 'LocName').text = cmd.source;
107032             }
107033             if ( cmd.target )
107034             {
107035                 var xtgt = ET.SubElement(xitem, 'Target');
107036                 ET.SubElement(xtgt, 'LocURI').text  = cmd.target;
107037                 ET.SubElement(xtgt, 'LocName').text = cmd.target;
107038             }
107039             if ( cmd.data )
107040             {
107041                 if ( _.isString(cmd.data) )
107042                     ET.SubElement(xitem, 'Data').text = cmd.data;
107043                 else
107044                     // assuming here that it is an ElementTree object...
107045                     ET.SubElement(xitem, 'Data').append(cmd.data);
107046             }
107047         }
107048     },
107049
107050     //-------------------------------------------------------------------------
107051     _produce_cmd_put: function(session, cmd, xcmd) {
107052         return this._produce_cmd_get(session, cmd, xcmd);
107053     },
107054
107055     //-------------------------------------------------------------------------
107056     _produce_cmd_results: function(session, cmd, xcmd) {
107057         ET.SubElement(xcmd, 'MsgRef').text    = cmd.msgRef;
107058         ET.SubElement(xcmd, 'CmdRef').text    = cmd.cmdRef;
107059         ET.SubElement(ET.SubElement(xcmd, 'Meta'), 'Type',
107060                 {'xmlns': constant.NAMESPACE_METINF}).text = cmd.type;
107061         var xitem = ET.SubElement(xcmd, 'Item');
107062         var xsrc  = ET.SubElement(xitem, 'Source');
107063         ET.SubElement(xsrc, 'LocURI').text  = cmd.source;
107064         ET.SubElement(xsrc, 'LocName').text = cmd.source;
107065         if ( cmd.data )
107066         {
107067             if ( _.isString(cmd.data) )
107068                 ET.SubElement(xitem, 'Data').text = cmd.data;
107069             else
107070                 // assuming here that it is an ElementTree object...
107071                 ET.SubElement(xitem, 'Data').append(cmd.data);
107072         }
107073     },
107074
107075     //-------------------------------------------------------------------------
107076     _produce_cmd_sync: function(session, cmd, xcmd) {
107077         ET.SubElement(ET.SubElement(xcmd, 'Source'), 'LocURI').text = cmd.source;
107078         ET.SubElement(ET.SubElement(xcmd, 'Target'), 'LocURI').text = cmd.target;
107079         if ( cmd.noc != undefined )
107080             ET.SubElement(xcmd, 'NumberOfChanges').text = '' + cmd.noc;
107081         if ( ! cmd.data )
107082             return;
107083         for ( var idx=0 ; idx<cmd.data.length ; idx++ )
107084         {
107085             var scmd = cmd.data[idx];
107086             var xscmd = ET.SubElement(xcmd, scmd.name);
107087             if ( scmd.cmdID )
107088                 ET.SubElement(xscmd, 'CmdID').text = scmd.cmdID;
107089             if ( scmd.type
107090                     || ( scmd.format && scmd.format != constant.FORMAT_AUTO ) )
107091             {
107092                 var xsmeta = ET.SubElement(xscmd, 'Meta')
107093                     // todo: implement auto encoding determination...
107094                     //       (the current implementation just lets XML encoding
107095                     //       do it, which is for most things good enough, but
107096                     //       not so good for sequences that need a large amount
107097                     //       of escaping such as binary data...)
107098                     if ( scmd.format && scmd.format != constant.FORMAT_AUTO )
107099                         ET.SubElement(xsmeta, 'Format',
107100                                 {'xmlns': constant.NAMESPACE_METINF}).text = scmd.format;
107101                 if ( scmd.type )
107102                     ET.SubElement(xsmeta, 'Type',
107103                             {'xmlns': constant.NAMESPACE_METINF}).text = scmd.type;
107104             }
107105             var xsitem = ET.SubElement(xscmd, 'Item');
107106             if ( scmd.source )
107107                 ET.SubElement(ET.SubElement(xsitem, 'Source'),
107108                         'LocURI').text = scmd.source;
107109             if ( scmd.sourceParent )
107110                 ET.SubElement(ET.SubElement(xsitem, 'SourceParent'),
107111                         'LocURI').text = scmd.sourceParent;
107112             if ( scmd.target )
107113                 ET.SubElement(ET.SubElement(xsitem, 'Target'),
107114                         'LocURI').text = scmd.target;
107115             if ( scmd.targetParent )
107116                 ET.SubElement(ET.SubElement(xsitem, 'TargetParent'),
107117                         'LocURI').text = scmd.targetParent;
107118             if ( scmd.data )
107119             {
107120                 if ( _.isString(scmd.data) )
107121                     ET.SubElement(xsitem, 'Data').text = scmd.data;
107122                 else
107123                     // assuming here that it is an ElementTree object...
107124                     ET.SubElement(xsitem, 'Data')._node.appendChild(scmd.data);
107125             }
107126         }
107127     },
107128
107129     //-------------------------------------------------------------------------
107130     _produce_cmd_map: function(session, cmd, xcmd) {
107131         ET.SubElement(ET.SubElement(xcmd, 'Source'), 'LocURI').text = cmd.source;
107132         ET.SubElement(ET.SubElement(xcmd, 'Target'), 'LocURI').text = cmd.target;
107133         if ( cmd.sourceItem || cmd.targetItem )
107134         {
107135             var xitem = ET.SubElement(xcmd, constant.CMD_MAPITEM);
107136             if ( cmd.sourceItem )
107137                 ET.SubElement(ET.SubElement(xitem, 'Source'), 'LocURI').text = cmd.sourceItem;
107138             if ( cmd.targetItem )
107139                 ET.SubElement(ET.SubElement(xitem, 'Target'), 'LocURI').text = cmd.targetItem;
107140         }
107141     },
107142
107143     //-------------------------------------------------------------------------
107144     _produce_cmd_final: function(session, cmd, xcmd) {
107145         return;
107146     },
107147
107148     //-------------------------------------------------------------------------
107149     // NOTE: `consume` is equivalent to the `pysyncml.protocol.tree2commands`...
107150     // consume: function...
107151     consume: function(session, lastcmds, xsync, cb) {
107152
107153         // do some preliminary sanity checks...
107154         // todo: do i really want to be returning an error instead of
107155         // generating an error response?...
107156
107157         if ( xsync.tag != constant.NODE_SYNCML
107158                 || xsync.getchildren().length != 2
107159                 || xsync.getchildren()[0].tag != constant.CMD_SYNCHDR
107160                 || xsync.getchildren()[1].tag != constant.NODE_SYNCBODY
107161            )
107162         {
107163             return cb('unexpected SyncML document structure');
107164         }
107165
107166         var version = xsync.getchildren()[0].findtext('VerProto');
107167         if ( version != constant.SYNCML_VERSION_1_2 )
107168             return cb('unsupported SyncML version "' + version + '"');
107169
107170         var verdtd = xsync.getchildren()[0].findtext('VerDTD');
107171         if ( verdtd != constant.SYNCML_DTD_VERSION_1_2 )
107172             return cb('unsupported SyncML DTD version "' + verdtd + '"');
107173
107174         var self = this;
107175
107176         self.initialize(session, xsync, function(err, cmds) {
107177             var hdrcmd = ( cmds && cmds.length > 0 ) ? cmds[0] : null;
107178             var makeErrorCommands = function(err, cb) {
107179
107180                 if ( err.exception )
107181
107182             if ( ! session.isServer )
107183             return cb(err);
107184
107185         var errcmd = state.makeCommand({
107186             name       : constant.CMD_STATUS,
107187             cmdID      : '1',
107188             msgRef     : session.info.pendingMsgID,
107189             cmdRef     : 0,
107190             sourceRef  : xsync.getchildren()[0].findtext('Source/LocURI'),
107191             targetRef  : xsync.getchildren()[0].findtext('Target/LocURI'),
107192             statusOf   : constant.CMD_SYNCHDR,
107193             statusCode : constant.STATUS_COMMAND_FAILED,
107194             errorMsg   : 'an error occurred during processing'
107195         });
107196
107197         // TODO: make this configurable as to whether or not any error
107198         //       is sent back to the peer as a SyncML "standardized" error
107199         //       status...
107200
107201         // TODO: make sure this is doing what is expected/intended...
107202         if ( err.code || err.name )
107203             errcmd.errorCode  = 'syncml-js.' + ( err.code || err.name );
107204         errcmd.errorMsg   = err.message || common.j(err) || '' + err;
107205
107206         return cb(null, [hdrcmd, errcmd,
107207                 state.makeCommand({name: constant.CMD_FINAL})]);
107208             };
107209
107210             if ( err )
107211                 return makeErrorCommands(err, cb);
107212
107213             try {
107214                 self._consume(session, lastcmds, xsync, cmds, function(err, commands) {
107215                     if ( err )
107216                     return makeErrorCommands(err, cb);
107217                 return cb(null, commands);
107218                 });
107219             } catch ( exc ) {
107220                 return makeErrorCommands(exc, cb);
107221             }
107222
107223         });
107224     },
107225
107226     //-------------------------------------------------------------------------
107227     _consume: function(session, lastcmds, xsync, commands, cb) {
107228
107229         var self       = this;
107230         var hdrcmd     = commands[0];
107231         var statusCode = constant.STATUS_OK;
107232
107233         // analyze the SyncHdr
107234         var children = xsync.getchildren()[0].getchildren();
107235         for ( var idx=0 ; idx<children.length ; idx++ )
107236         {
107237             var child = children[idx];
107238
107239
107240             if ( child.tag == 'VerDTD' )
107241             {
107242                 if ( hdrcmd.version == constant.SYNCML_VERSION_1_2 )
107243                 {
107244                     if ( child.text != constant.SYNCML_DTD_VERSION_1_2 )
107245                         return cb(new common.ProtocolError('bad VerDTD "' + child.text + '"'));
107246                 }
107247                 else
107248                     return cb(new common.FeatureNotSupported(
107249                                 'unsupported internal SyncML version "' + hdrcmd.version + '"'));
107250                 continue;
107251             }
107252
107253             if ( child.tag == 'VerProto' )
107254                 // this was checked earlier...
107255                 continue;
107256
107257             if ( child.tag == 'SessionID' )
107258             {
107259                 if ( child.text != hdrcmd.sessionID )
107260                     return cb(new common.ProtocolError(
107261                                 'session ID mismatch: "' + child.text + '" != "' + hdrcmd.sessionID + '"'));
107262                 continue;
107263             }
107264
107265             if ( child.tag == 'MsgID' )
107266             {
107267                 var chkmsg = ( session.isServer ? hdrcmd.msgID : lastcmds[0].msgID );
107268                 if ( child.text != chkmsg )
107269                     return cb(new common.ProtocolError(
107270                                 'message ID mismatch: "' + child.text + '" != "' + chkmsg + '"'));
107271                 continue;
107272             }
107273
107274             if ( child.tag == 'Target' )
107275             {
107276                 var uri = child.findtext('LocURI');
107277
107278                 // TODO... server-side...
107279
107280                 if ( uri != hdrcmd.source )
107281                     return cb(new common.ProtocolError(
107282                                 'incoming target mismatch: "' + uri + '" != "' + hdrcmd.source + '"'));
107283                 continue;
107284             }
107285
107286             if ( child.tag == 'Source' )
107287             {
107288                 var uri = child.findtext('LocURI');
107289                 if ( uri != hdrcmd.target && uri != lastcmds[0].target )
107290                     return cb(new common.ProtocolError(
107291                                 'incoming source mismatch: "' + uri + '" != "' + hdrcmd.target + '"'));
107292                 continue;
107293             }
107294
107295             if ( child.tag == 'RespURI' )
107296             {
107297                 // hdrcmd.target = child.text
107298                 // session.info.respUri = child.text
107299                 if ( ! session.isServer )
107300                     session.info.respUri = child.text;
107301                 continue;
107302             }
107303
107304             if ( child.tag == 'Cred' )
107305             {
107306                 // the responsibility is on the calling framework to ensure this is
107307                 // checked long before we get here... ie. Adapter.authorize(...)
107308                 // or via the Adapter.handleRequest() `authorize` parameter...
107309                 statusCode = constant.STATUS_AUTHENTICATION_ACCEPTED;
107310                 continue;
107311             }
107312
107313             if ( child.tag == 'Meta' )
107314             {
107315                 // this should already have been consumed during the protocol.initialize() call
107316                 continue;
107317             }
107318
107319             return cb(new common.ProtocolError('unexpected header node "' + child.tag + '"'));
107320         };
107321
107322         commands.push(state.makeCommand({
107323             name       : constant.CMD_STATUS,
107324             cmdID      : session.nextCmdID(),
107325             msgRef     : session.info.pendingMsgID,
107326             cmdRef     : 0,
107327             sourceRef  : xsync.getchildren()[0].findtext('Source/LocURI'),
107328             targetRef  : xsync.getchildren()[0].findtext('Target/LocURI'),
107329             statusOf   : constant.CMD_SYNCHDR,
107330             statusCode : statusCode
107331         }));
107332
107333         // and now evaluate the SyncBody
107334
107335         var chkcmds = _.filter(lastcmds, function(e) {
107336             return e.name != constant.CMD_STATUS && e.name != constant.CMD_FINAL;
107337         });
107338
107339         // for each "sync" command, search for sub-commands
107340         // todo: should this be generalized to search for any sub-commands?...
107341         _.each(chkcmds, function(e) {
107342             if ( e.name != constant.CMD_SYNC || ! e.data || e.data.length <= 0 )
107343             return;
107344         _.each(e.data, function(sub) { chkcmds.push(sub); });
107345         });
107346
107347         var children = xsync.getchildren()[1].getchildren();
107348
107349         // first, check all the 'Status' commands
107350
107351         var consumeStatus = function(cb) {
107352
107353             common.cascade(children, function(child, cb) {
107354
107355                 if ( child.tag != constant.CMD_STATUS )
107356                 return cb();
107357
107358             cname = child.findtext('Cmd');
107359
107360             var blen   = chkcmds.length;
107361             var chkcmd = null;
107362             var chkerr = null;
107363
107364             chkcmds = _.filter(chkcmds, function(cmd) {
107365                 if ( chkerr )
107366                 return;
107367             if ( cmd.cmdID != child.findtext('CmdRef')
107368                 || cmd.name != cname
107369                 || lastcmds[0].msgID != child.findtext('MsgRef') )
107370                 return true;
107371             if ( chkcmd )
107372                 chkerr = new Error('unexpected error: multiple check commands match status command');
107373             chkcmd = cmd;
107374             return false;
107375             });
107376
107377             if ( chkerr )
107378                 return cb(chkerr);
107379
107380             if ( chkcmds.length >= blen )
107381                 return cb(new common.ProtocolError(
107382                             'unexpected status node "s' + session.info.id + '.m' + child.findtext('MsgRef')
107383                             + '.c' + child.findtext('CmdRef') + ' cmd=' + cname + '"'));
107384
107385             // TODO: check for unknown elements (and complain?)...
107386
107387             var code = common.int(child.findtext('Data'));
107388
107389             if ( code == constant.STATUS_MISSING_CREDENTIALS )
107390             {
107391                 var authtype = child.findtext('Chal/Meta/Type');
107392                 var attrs = {auth: {type: authtype}};
107393                 return cb(badStatus(child, common.CredentialsRequired, attrs));
107394             }
107395
107396             if ( code == constant.STATUS_INVALID_CREDENTIALS )
107397             {
107398                 // TODO: get the auth type... from where??...
107399                 var authtype = child.findtext('Chal/Meta/Type');
107400                 var attrs = {auth: {type: authtype}};
107401                 return cb(badStatus(child, common.InvalidCredentials, attrs));
107402             }
107403
107404             var targetRef = child.findtext('TargetRef');
107405             if ( targetRef )
107406             {
107407                 // note: doing a normUri on chkcmd.target because it could be "./devinf12"...
107408                 if ( session.peer.normUri(targetRef) != session.peer.normUri(chkcmd.target) )
107409                     return cb(new common.ProtocolError('unexpected target-ref "'
107410                                 + targetRef + '" != "' + chkcmd.target
107411                                 + '" for command "' + cname + '"'));
107412             }
107413
107414             var sourceRef = child.findtext('SourceRef');
107415             if ( sourceRef )
107416             {
107417                 // note: doing a normUri on chkcmd.source because it could be "./devinf12"...
107418                 if ( cname == constant.CMD_SYNCHDR )
107419                 {
107420                     // this is a little odd, but syncevolution strips the sessionid path
107421                     // parameter off for some reason, so compensating here...
107422                     if ( _.indexOf([session.adapter.normUri(chkcmd.source),
107423                                 session.info.effectiveID,
107424                                 session.info.returnUrl],
107425                                 session.adapter.normUri(sourceRef)) < 0
107426                             && session.adapter.normUri(chkcmd.source).indexOf(session.adapter.normUri(sourceRef)) != 0 )
107427                         return cb(new common.ProtocolError('unexpected source-ref "'
107428                                     + sourceRef + '" != "' + chkcmd.source
107429                                     + '" for command "' + cname + '"'));
107430                 }
107431                 else
107432                 {
107433                     if ( session.adapter.normUri(sourceRef) != session.adapter.normUri(chkcmd.source) )
107434                         return cb(new common.ProtocolError('unexpected source-ref "'
107435                                     + sourceRef + '" != "' + chkcmd.source
107436                                     + '" for command "' + cname + '"'));
107437                 }
107438             }
107439
107440             // todo: any other common elements?...
107441
107442             switch ( cname )
107443             {
107444
107445                 case constant.CMD_SYNCHDR:
107446                     {
107447                         if ( code != constant.STATUS_OK && code != constant.STATUS_AUTHENTICATION_ACCEPTED )
107448                             return cb(badStatus(child));
107449                         if ( code == constant.STATUS_AUTHENTICATION_ACCEPTED )
107450                         {
107451                             // TODO: there is currently nothing that can "reset" the
107452                             //       authAccepted flag...  there should be a trap such
107453                             //       that if an auth fails, then authAccepted gets set
107454                             //       to false.
107455                             session.info.authAccepted = true;
107456                         }
107457                         return cb();
107458                     }
107459
107460                 case constant.CMD_ALERT:
107461                     {
107462                         if ( code == constant.STATUS_OK )
107463                             // TODO: do something with the Item/Data/Anchor/Next?...
107464                             return cb();
107465                         if ( code == constant.STATUS_REFRESH_REQUIRED && ! session.isServer )
107466                         {
107467                             // TODO: support the ability for the UA to control which kind of
107468                             //       refresh to do (slow-sync, client-refresh, server-refresh)
107469                             return cb();
107470                         }
107471                         return cb(badStatus(child));
107472                     }
107473
107474                 case constant.CMD_GET:
107475                     {
107476                         if ( code != constant.STATUS_OK )
107477                             return cb(badStatus(child));
107478                         return cb();
107479                     }
107480
107481                 case constant.CMD_PUT:
107482                     {
107483                         if ( code != constant.STATUS_OK )
107484                             return cb(badStatus(child));
107485                         return cb();
107486                     }
107487
107488                 case constant.CMD_RESULTS:
107489                     {
107490                         if ( code != constant.STATUS_OK )
107491                             return cb(badStatus(child));
107492                         return cb();
107493                     }
107494
107495                 case constant.CMD_SYNC:
107496                     {
107497                         // todo: should this be moved into the synchronizer as a "settle" event?...
107498                         var ds = session.info.dsstates[session.adapter.normUri(chkcmd.source)]
107499                             if ( code != constant.STATUS_OK )
107500                             {
107501                                 // check for server-side errors...
107502                                 if ( code >= 500 && code < 600 && child.findtext('Item/Data') )
107503                                 {
107504                                     ds.action = 'error';
107505                                     ds.error  = getError(child);
107506                                     ds.stats.peerErr += 1;
107507                                     return cb();
107508                                 }
107509                                 return cb(badStatus(child));
107510                             }
107511                         if ( ds.action == 'send' )
107512                         {
107513                             if ( session.isServer )
107514                             {
107515                                 ds.action = 'save';
107516                                 return cb();
107517                             }
107518                             ds.action = common.oneWayOut(session, ds.mode) ? 'done' : 'recv';
107519                             return cb();
107520                         }
107521                         return cb(new common.ProtocolError('unexpected sync state for action=' + ds.action));
107522                     }
107523
107524                 case constant.CMD_ADD:
107525                 case constant.CMD_REPLACE:
107526                 case constant.CMD_DELETE:
107527                     {
107528                         var scmd = state.makeCommand({
107529                             name       : cname,
107530                             msgID      : hdrcmd.msgID,
107531                             cmdID      : child.findtext('CmdID'),
107532                             sourceRef  : sourceRef,
107533                             targetRef  : targetRef,
107534                             data       : code
107535                         });
107536
107537                         session.context.synchronizer.settle(
107538                                 session, scmd, chkcmd, child,
107539                                 function(err, cmds) {
107540                                     if ( err )
107541                             return cb(err);
107542                         _.each(cmds, function(cmd) { commands.push(cmd); });
107543                         return cb();
107544                                 });
107545                         return;
107546                     }
107547
107548                 case constant.CMD_MAP:
107549                     {
107550                         if ( session.isServer )
107551                             return cb(new common.ProtocolError(
107552                                         'unexpected server-side status for command "' + cname + '"'));
107553                         if ( code != constant.STATUS_OK )
107554                             return cb(badStatus(child));
107555                         return cb();
107556                     }
107557
107558                 default:
107559                     {
107560                         return cb(new common.ProtocolError('unexpected status for command "' + cname + '"'));
107561                     }
107562
107563             }
107564
107565             }, cb);
107566
107567         };
107568
107569         // second, check all the non-'Status' commands
107570
107571         var consumeCommands = function(cb) {
107572
107573             var gotFinal = false;
107574
107575             common.cascade(children, function(child, cb) {
107576
107577
107578                 if ( child.tag == constant.CMD_STATUS )
107579                 return cb();
107580
107581             if ( child.tag == constant.CMD_FINAL )
107582             {
107583                 gotFinal = true;
107584                 return cb();
107585             }
107586
107587
107588             // todo: restrict this to the following commands?...
107589             //         CMD_ALERT, CMD_GET, CMD_PUT,
107590             //         CMD_SYNC, CMD_RESULTS, CMD_MAP
107591
107592             var func = self['_consume_node_' + child.tag.toLowerCase()];
107593
107594             if ( ! func )
107595                 return cb(new common.ProtocolError('unexpected command node "' + child.tag + '"'));
107596
107597             try{
107598
107599                 func.call(self, session, lastcmds, xsync, child, function(err, cmds) {
107600                     if ( err )
107601                     return cb(err);
107602                 _.each(cmds, function(cmd) { commands.push(cmd); });
107603                 return cb();
107604                 });
107605
107606             }catch(e){
107607                 // log.error('failed invoking protocol sub-consumption of "%s": %s', child.tag, e);
107608                 // log.error('  ' + stacktrace({e: e}).join('\n  '));
107609                 return cb(new common.InternalError(
107610                             'failed invoking protocol sub-consumption of "' + child.tag + '": ' + e, e));
107611             }
107612
107613             }, function(err) {
107614
107615                 if ( err )
107616                     return cb(err);
107617
107618                 if ( ! gotFinal )
107619                 {
107620                     commands.push(state.makeCommand({
107621                         name       : constant.CMD_ALERT,
107622                         cmdID      : session.nextCmdID(),
107623                         data       : constant.STATUS_NEXT_MESSAGE,
107624                         source     : session.adapter.devID,
107625                         target     : session.peer.devID,
107626                     }));
107627                 }
107628
107629                 return cb();
107630
107631             });
107632
107633         };
107634
107635         // do it!
107636
107637         consumeStatus(function(err) {
107638
107639             if ( err )
107640             return cb(err);
107641
107642         // TODO: is this right?... or should i be getting pissed off and
107643         //       raising hell that all my commands were not addressed?...
107644
107645         _.each(chkcmds, function(chkcmd) {
107646             commands.push(chkcmd);
107647         });
107648
107649         return consumeCommands(function(err) {
107650             if ( err )
107651             return cb(err);
107652         return cb(null, commands);
107653         });
107654
107655         });
107656
107657     },
107658
107659     //-------------------------------------------------------------------------
107660     _consume_node_get: function(session, lastcmds, xsync, xnode, cb) {
107661         var cttype = xnode.findtext('Meta/Type');
107662         var target = xnode.findtext('Item/Target/LocURI');
107663         if ( cttype.indexOf(constant.TYPE_SYNCML_DEVICE_INFO) == 0
107664                 && session.adapter.normUri(target) == constant.URI_DEVINFO_1_2 )
107665             return this._consume_node_get_devinf12(session, lastcmds, xsync, xnode, cb);
107666         // todo: make error status node...
107667         cb(new common.ProtocolError(
107668                     'unexpected "' + constant.CMD_GET + '" command for local "' + target + '"'));
107669     },
107670
107671     //-------------------------------------------------------------------------
107672     _consume_node_get_devinf12: function(session, lastcmds, xsync, xnode, cb) {
107673         var ret = [];
107674         ret.push(state.makeCommand({
107675             name       : constant.CMD_STATUS,
107676             cmdID      : session.nextCmdID(),
107677             msgRef     : session.info.pendingMsgID,
107678             cmdRef     : xnode.findtext('CmdID'),
107679             statusOf   : xnode.tag,
107680             statusCode : constant.STATUS_OK,
107681             targetRef  : xnode.findtext('Item/Target/LocURI')
107682         }));
107683         ret.push(state.makeCommand({
107684             name       : constant.CMD_RESULTS,
107685             cmdID      : session.nextCmdID(),
107686             msgRef     : session.info.pendingMsgID,
107687             cmdRef     : xnode.findtext('CmdID'),
107688             type       : constant.TYPE_SYNCML_DEVICE_INFO + '+' + session.info.codec,
107689             source     : './' + constant.URI_DEVINFO_1_2,
107690             data       : session.adapter.devInfo.toSyncML(constant.SYNCML_DTD_VERSION_1_2,
107691                 _.values(session.adapter._stores))
107692
107693         }));
107694         cb(null, ret);
107695     },
107696
107697     //-------------------------------------------------------------------------
107698     _consume_node_put: function(session, lastcmds, xsync, xnode, cb) {
107699         var cttype = xnode.findtext('Meta/Type');
107700         var source = xnode.findtext('Item/Source/LocURI');
107701         if ( cttype.indexOf(constant.TYPE_SYNCML_DEVICE_INFO) == 0
107702                 && session.peer.normUri(source) == constant.URI_DEVINFO_1_2 )
107703             return this._consume_node_put_devinf12(session, lastcmds, xsync, xnode, cb);
107704         // todo: make error status node...
107705         cb(new common.ProtocolError(
107706                     'unexpected "' + constant.CMD_PUT + '" command for remote "' + source + '"'));
107707     },
107708
107709     //-------------------------------------------------------------------------
107710     _consume_node_put_devinf12: function(session, lastcmds, xsync, xnode, cb) {
107711         var xdev = xnode.find('Item/Data/DevInf');
107712         var res  = devinfo.DevInfo.fromSyncML(xdev);
107713         session.peer._setRemoteInfo(res[0], res[1], function(err) {
107714             if ( err )
107715             return cb(err);
107716
107717         var okcmd = state.makeCommand({
107718             name       : constant.CMD_STATUS,
107719             cmdID      : session.nextCmdID(),
107720             msgRef     : xsync.findtext('SyncHdr/MsgID'),
107721             cmdRef     : xnode.findtext('CmdID'),
107722             sourceRef  : xnode.findtext('Item/Source/LocURI'),
107723             statusOf   : xnode.tag,
107724             statusCode : constant.STATUS_OK
107725         });
107726
107727         if ( session.isServer )
107728             return cb(null, [okcmd]);
107729
107730         // TODO: this should only cause a `recalculate` if any
107731         //       meta-information actually changed...
107732
107733         session.context.router.recalculate(session.adapter, session.peer, function(err) {
107734             if ( err )
107735             return cb(err);
107736         session.context.synchronizer.initStoreSync(session, function(err) {
107737             if ( err )
107738             return cb(err);
107739
107740         // TODO: the call to _setRemoteInfo makes the peer
107741         //       "dirty" without saving changes to the model...
107742         //       make sure the `save` executed in Adapter.sync()
107743         //       or Adapter.handleRequest() appropriately causes
107744         //       objects to save themselves to the model...
107745
107746         // session.adapter._save(session.txn(), function(err) {
107747         //   if ( err )
107748         //     return cb(err);
107749
107750         return cb(null, [okcmd]);
107751
107752         // });
107753
107754         });
107755         });
107756         });
107757     },
107758
107759     //-------------------------------------------------------------------------
107760     _consume_node_results: function(session, lastcmds, xsync, xnode, cb) {
107761         var cttype = xnode.findtext('Meta/Type');
107762         var source = xnode.findtext('Item/Source/LocURI');
107763         if ( cttype.indexOf(constant.TYPE_SYNCML_DEVICE_INFO) == 0
107764                 && session.peer.normUri(source) == constant.URI_DEVINFO_1_2 )
107765             return this._consume_node_put_devinf12(session, lastcmds, xsync, xnode, cb);
107766         // todo: make error status node...
107767         return cb(new common.ProtocolError('unexpected "' + constant.CMD_RESULTS
107768                     + '" command for remote "' + source + '"'))
107769     },
107770
107771     //-------------------------------------------------------------------------
107772     _consume_node_alert: function(session, lastcmds, xsync, xnode, cb) {
107773         var code = common.int(xnode.findtext('Data'));
107774         var statusCode = constant.STATUS_OK
107775             switch ( code )
107776             {
107777                 case constant.ALERT_TWO_WAY:
107778                 case constant.ALERT_SLOW_SYNC:
107779                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
107780                 case constant.ALERT_REFRESH_FROM_CLIENT:
107781                 case constant.ALERT_ONE_WAY_FROM_SERVER:
107782                 case constant.ALERT_REFRESH_FROM_SERVER:
107783                     // todo: these should only be received out-of-band: right?...
107784                     // case constant.ALERT_TWO_WAY_BY_SERVER:
107785                     // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER:
107786                     // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER:
107787                     // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER:
107788                     // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER:
107789                     {
107790                         break;
107791                     }
107792                 default:
107793                     {
107794                         if ( session.isServer && code == constant.STATUS_RESUME )
107795                         {
107796                             code = constant.ALERT_SLOW_SYNC;
107797                         }
107798                         else
107799                         {
107800                             return cb(new common.FeatureNotSupported(
107801                                         'unimplemented sync mode '
107802                                         + code + ' ("' + common.mode2string(code) + '")'));
107803                         }
107804                     }
107805             }
107806
107807         if ( session.isServer )
107808         {
107809             // TODO: if this is the server, we need to validate that the requested
107810             //       sync mode is actually feasible... i.e. check:
107811             //         - do the anchors match?
107812             //         - have we bound the datastores together?
107813             //         - is there a pending sync?
107814         }
107815
107816         var uri  = session.adapter.normUri(xnode.findtext('Item/Target/LocURI'));
107817         var ruri = session.peer.normUri(xnode.findtext('Item/Source/LocURI'));
107818
107819         // TODO: this should really be done by the synchronizer... as it can
107820         //       then also do a lot of checks - potentially responding with
107821         //       an error...
107822
107823         var getDS = function(cb) {
107824             if ( session.isServer )
107825             {
107826                 var ds = session.info.dsstates[uri];
107827                 if ( ds )
107828                 {
107829                     ds.action = 'alert';
107830                     return cb(null, ds);
107831                 }
107832
107833                 var peerStore = session.peer.getStore(ruri);
107834                 if ( ! peerStore )
107835                     return cb(new common.ProtocolError(
107836                                 'request to synchronize unknown remote client URI "' + ruri
107837                                 + '" (to local server URI "' + uri + '")'));
107838
107839                 // todo: if already correctly bound, then we don't need to re-bind
107840                 // if ( peerStore._getBinding() )
107841                 // {
107842                 //   log.critical('(currently bound)');
107843                 // }
107844                 // else
107845                 //   log.critical('(currently unbound)');
107846
107847                 session.peer.setRoute(uri, ruri, true, function(err) {
107848                     if ( err )
107849                     return cb(err);
107850                 var peerStore = session.peer.getStore(ruri);
107851                 var ds = state.makeStoreSyncState({
107852                     uri        : uri,
107853                     peerUri    : ruri,
107854                     lastAnchor : peerStore._getBinding().localAnchor,
107855                     mode       : null,
107856                     action     : 'alert'
107857                 });
107858                 session.info.dsstates[uri] = ds;
107859                 return cb(null, ds);
107860                 });
107861                 return;
107862             }
107863             else
107864             {
107865                 var ds = session.info.dsstates[uri];
107866                 if ( ! ds )
107867                     return cb(new common.ProtocolError('request for unreflected local datastore "'
107868                                 + uri + '"'));
107869                 ds.action = 'send';
107870                 if ( code == ds.mode )
107871                     return cb(null, ds);
107872
107873                 var uaEvent = {
107874                     session   : session,
107875                     uri       : uri,
107876                     peerUri   : ruri,
107877                     modeReq   : ds.mode,
107878                     modeRes   : code
107879                 };
107880                 session.ua.acceptSyncModeSwitch(uaEvent, function(err) {
107881                     if ( err )
107882                 {
107883                     return cb(err);
107884                 }
107885                 if ( session.context.listener )
107886                     session.context.listener(uaEvent);
107887                 return cb(null, ds);
107888                 });
107889             }
107890         };
107891
107892
107893         getDS(function(err, ds) {
107894
107895             if ( err )
107896             return cb(err);
107897
107898         ds.mode = code;
107899         ds.peerLastAnchor = xnode.findtext('Item/Meta/Anchor/Last', null);
107900         ds.peerNextAnchor = xnode.findtext('Item/Meta/Anchor/Next', null);
107901
107902         if ( ds.peerLastAnchor != session.peer.getStore(ruri)._getBinding().remoteAnchor )
107903         {
107904             ds.peerLastAnchor = null;
107905             switch ( ds.mode )
107906         {
107907             case constant.ALERT_SLOW_SYNC:
107908             case constant.ALERT_REFRESH_FROM_CLIENT:
107909             case constant.ALERT_REFRESH_FROM_SERVER:
107910                 {
107911                     break;
107912                 }
107913             default:
107914                 {
107915                     if ( session.isServer )
107916                     {
107917                         ds.mode = constant.ALERT_SLOW_SYNC;
107918                         statusCode = constant.STATUS_REFRESH_REQUIRED;
107919                     }
107920                     else
107921                     {
107922                         // todo: should i assume that the server knows something
107923                         //       that i don't and just go along with it?...
107924                         return cb(new common.ProtocolError(
107925                                     'server-side requested inappropriate ' + common.mode2string(ds.mode)
107926                                     + ' sync mode on unbound datastore "' + uri + '"'));
107927                     }
107928                 }
107929         }
107930         }
107931
107932         return cb(null, [state.makeCommand({
107933             name       : constant.CMD_STATUS,
107934                cmdID      : session.nextCmdID(),
107935                msgRef     : xsync.findtext('SyncHdr/MsgID'),
107936                cmdRef     : xnode.findtext('CmdID'),
107937                targetRef  : xnode.findtext('Item/Target/LocURI'),
107938                sourceRef  : xnode.findtext('Item/Source/LocURI'),
107939                statusOf   : xnode.tag,
107940                statusCode : statusCode,
107941                // todo: syncevolution does not echo the remote last anchor... why not?
107942                lastAnchor : ds.peerLastAnchor,
107943                nextAnchor : ds.peerNextAnchor
107944         })]);
107945
107946         });
107947
107948     },
107949
107950     //-------------------------------------------------------------------------
107951     _consume_node_sync: function(session, lastcmds, xsync, xnode, cb) {
107952         var self   = this;
107953         var uri    = xnode.findtext('Target/LocURI');
107954         var store  = session.adapter.getStore(session.adapter.normUri(uri));
107955         var ds     = session.info.dsstates[session.adapter.normUri(uri)];
107956         var commands = [state.makeCommand({
107957             name        : constant.CMD_SYNC,
107958             msgID       : xsync.findtext('SyncHdr/MsgID'),
107959             cmdID       : xnode.findtext('CmdID'),
107960             source      : xnode.findtext('Source/LocURI'),
107961             target      : uri,
107962             data        : [],
107963         })];
107964         var noc = common.int(xnode.findtext('NumberOfChanges'));
107965         if (noc !== undefined) {
107966             changednum = noc;
107967             _counts = 0;
107968         }
107969         common.cascade(xnode.getchildren(), function(child, cb) {
107970             switch ( child.tag )
107971         {
107972             case 'CmdID':
107973             case 'Target':
107974             case 'Source':
107975             case 'NumberOfChanges':
107976                 {
107977                     return cb();
107978                 }
107979             case constant.CMD_ADD:
107980             case constant.CMD_REPLACE:
107981             case constant.CMD_DELETE:
107982                 {
107983                     var func = self['_consume_sync_' + child.tag.toLowerCase()];
107984                     func.call(self, session, lastcmds, store, xsync, child, function(err, cmds) {
107985                         if ( err )
107986                         return cb(err);
107987                     _.each(cmds, function(cmd) { commands[0].data.push(cmd); });
107988                     return cb();
107989                     });
107990                     return;
107991                 }
107992             default:
107993                 {
107994                     return cb(new common.ProtocolError('unexpected sync command "' + child.tag + '"'));
107995                 }
107996         }
107997         }, function(err) {
107998             if ( err )
107999                 return cb(err);
108000             // confirm that i received the right number of changes...
108001             /*
108002                if ( noc != undefined && noc != commands[0].data.length )
108003                return cb(new common.ProtocolError('number-of-changes mismatch (received '
108004                + commands[0].data.length + ', expected '
108005                + noc + ')'));
108006                */
108007             _counts =  _counts + commands[0].data.length;
108008             if ( ds.action != 'error' )
108009             {
108010                 if ( ! session.isServer )
108011                 {
108012                     if ( ds.action != 'recv' )
108013                         return cb(new common.ProtocolError('unexpected sync state for URI "'
108014                                     + uri + '": action=' + ds.action));
108015                     if (changednum != undefined && changednum <= _counts)  {
108016                         ds.action = 'done';
108017                         changednum = undefined;
108018                         _counts = 0;
108019                     }
108020                 }
108021                 else
108022                 {
108023                     if ( ds.action != 'alert' )
108024                         return cb(new common.ProtocolError(
108025                                     'unexpected sync state for URI "' + uri + '": action=' + ds.action));
108026                     ds.action = common.oneWayIn(session, ds.mode) ? 'save' : 'send';
108027                 }
108028             }
108029             return session.context.synchronizer.reactions(session, commands, cb);
108030         });
108031     },
108032
108033     //-------------------------------------------------------------------------
108034     _consume_xnode2item: function(session, lastcmds, store, xsync, xnode, cb) {
108035         var ctype  = xnode.findtext('Meta/Type');
108036         // todo: can the version be specified in the Meta tag?... maybe create an
108037         //       extension to SyncML to communicate this?...
108038         var ctver  = null;
108039         var format = xnode.findtext('Meta/Format');
108040         var xitem  = xnode.findall('Item/Data');
108041         if ( xitem.length > 1 )
108042             return cb(new common.ProtocolError(
108043                         '"' + xnode.tag + '" command with non-singular item data nodes'));
108044         if ( xitem.length < 1 )
108045             return cb(new common.ProtocolError(
108046                         '"' + xnode.tag + '" command with missing data node'));
108047         var xitem = xitem[0];
108048         // todo: confirm that getchildren only returns element nodes...
108049         if ( xitem.getchildren().length == 1 )
108050             data = xitem.getchildren()[0];
108051         else
108052         {
108053             data = xitem.text;
108054             if ( format == constant.FORMAT_B64 )
108055                 data = base64.decode(data);
108056         }
108057         return store.agent.loadsItem(data, ctype, ctver, cb);
108058     },
108059
108060     //-------------------------------------------------------------------------
108061     _consume_sync_add: function(session, lastcmds, store, xsync, xnode, cb) {
108062         this._consume_xnode2item(session, lastcmds, store, xsync, xnode, function(err, item) {
108063             if ( err )
108064             return cb(err);
108065         return cb(null, [state.makeCommand({
108066             name          : constant.CMD_ADD,
108067                msgID         : xsync.findtext('SyncHdr/MsgID'),
108068                cmdID         : xnode.findtext('CmdID'),
108069                source        : xnode.findtext('Item/Source/LocURI'),
108070                sourceParent  : xnode.findtext('Item/SourceParent/LocURI'),
108071                targetParent  : xnode.findtext('Item/TargetParent/LocURI'),
108072                data          : item
108073         })]);
108074         });
108075     },
108076
108077     //-------------------------------------------------------------------------
108078     _consume_sync_replace: function(session, lastcmds, store, xsync, xnode, cb) {
108079         this._consume_xnode2item(session, lastcmds, store, xsync, xnode, function(err, item) {
108080             if ( err )
108081             return cb(err);
108082         return cb(null, [state.makeCommand({
108083             name          : constant.CMD_REPLACE,
108084                msgID         : xsync.findtext('SyncHdr/MsgID'),
108085                cmdID         : xnode.findtext('CmdID'),
108086                source        : xnode.findtext('Item/Source/LocURI'),
108087                sourceParent  : xnode.findtext('Item/SourceParent/LocURI'),
108088                target        : xnode.findtext('Item/Target/LocURI'),
108089                targetParent  : xnode.findtext('Item/TargetParent/LocURI'),
108090                data          : item
108091         })]);
108092         });
108093     },
108094
108095     //-------------------------------------------------------------------------
108096     _consume_sync_delete: function(session, lastcmds, store, xsync, xnode, cb) {
108097         return cb(null, [state.makeCommand({
108098             name          : constant.CMD_DELETE,
108099         msgID         : xsync.findtext('SyncHdr/MsgID'),
108100         cmdID         : xnode.findtext('CmdID'),
108101         source        : xnode.findtext('Item/Source/LocURI'),
108102         sourceParent  : xnode.findtext('Item/SourceParent/LocURI'),
108103         target        : xnode.findtext('Item/Target/LocURI'),
108104         targetParent  : xnode.findtext('Item/TargetParent/LocURI')
108105         })]);
108106     },
108107
108108     // #----------------------------------------------------------------------------
108109     // def makeStatus(self, session, xsync, xnode, status=constant.STATUS_OK, **kw):
108110     //   return state.Command(
108111     //     name       = constant.CMD_STATUS,
108112     //     cmdID      = session.nextCmdID(),
108113     //     msgRef     = xsync.findtext('SyncHdr/MsgID'),
108114     //     cmdRef     = xnode.findtext('CmdID'),
108115     //     statusOf   = xnode.tag,
108116     //     statusCode = status,
108117     //     **kw
108118     //     )
108119
108120     //-------------------------------------------------------------------------
108121     _consume_node_map: function(session, lastcmds, xsync, xnode, cb) {
108122         if ( ! session.isServer )
108123             return cb(new common.ProtocolError(
108124                         'unexpected "Map" command received by client-side SyncML peer'));
108125         // TODO: convert the sender-side to support command.items like
108126         //       this as well...
108127         var cmd = state.makeCommand({
108128             name    : constant.CMD_MAP,
108129             msgID   : xsync.findtext('SyncHdr/MsgID'),
108130             cmdID   : xnode.findtext('CmdID'),
108131             source  : xnode.findtext('Source/LocURI'),
108132             target  : xnode.findtext('Target/LocURI'),
108133             items   : []
108134         });
108135         _.each(xnode.findall('MapItem'), function(xnode) {
108136             // todo: support hierarchical sync...
108137             cmd.items.push({
108138                 source        : xnode.findtext('Source/LocURI'),
108139                 // sourceParent  : xnode.findtext('SourceParent/LocURI'),
108140                 target        : xnode.findtext('Target/LocURI'),
108141                 // targetParent  : xnode.findtext('TargetParent/LocURI')
108142             });
108143         });
108144         return session.context.synchronizer.reactions(session, [cmd], cb);
108145     }
108146
108147
108148 });
108149
108150 return exports;
108151
108152 })();
108153
108154 module.exports = _self;
108155
108156 });
108157 define('ripple/platform/tizen/2.0/syncml-js-lib/remoteadapter', function (require, exports, module) {
108158 // -*- coding: utf-8 -*-
108159 //-----------------------------------------------------------------------------
108160 // file: $Id$
108161 // lib:  syncml-js.remoteadapter
108162 // auth: griffin <griffin@uberdev.org>
108163 // date: 2012/11/04
108164 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
108165 //-----------------------------------------------------------------------------
108166
108167 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
108168     devinfomod = require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'),
108169     adapter = require('ripple/platform/tizen/2.0/syncml-js-lib/adapter'),
108170     storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store'),
108171     _self;
108172
108173 _self = (function () {
108174     var exports = {};
108175
108176     //---------------------------------------------------------------------------
108177     exports.RemoteAdapter = adapter.Adapter.extend({
108178
108179         //-------------------------------------------------------------------------
108180         constructor: function(adapter, options) {
108181
108182             //: [read-only] the URL of the remote syncml peer, acting as a server,
108183             //: to connect to.
108184             this.url = options.url || null;
108185
108186             //: [read-only] specifies whether this Adapter represents a local
108187             //: or remote peer.
108188             this.isLocal = false;
108189
108190             //: [read-only] the DevID of the remote syncml peer (which usually
108191             //: defaults to the URL).
108192             this.devID = options.devID || options.url || null;
108193
108194             //: [read-only] the authentication method to use to identify the local
108195             //: peer to the remote peer.
108196             ///TODO: this.auth = options.auth || null;
108197             this.auth = 'syncml:auth-basic';
108198
108199             //: [read-only] the human-friendly display name of the remote peer.
108200             this.displayName = options.displayName || null;
108201
108202             //: [read-only] the username to use during credential-based authentication.
108203             this.username = options.username || null;
108204
108205             //: [read-only] the password to use during credential-based authentication.
108206             this.password = options.password || null;
108207
108208             //: [read-only] the peer-wide default value of the maximum
108209             //: message size.
108210             this.maxMsgSize = options.maxMsgSize || null;
108211
108212             //: [read-only] the peer-wide default value of the maximum
108213             //: object size.
108214             this.maxObjSize = options.maxObjSize || null;
108215
108216             //: [read-only] the DevInfo object for this remote peer.
108217             this.devInfo = null;
108218
108219             this.lastSessionID = options.lastSessionID || null;
108220
108221             // --- private attributes
108222             this.id       = options.id || common.makeID();
108223             this._a       = adapter;
108224             this._c       = adapter._c;
108225             this._stores  = {};
108226             this._proxy   = null;
108227
108228             // TODO: filter these options for db-valid only properties...
108229             this._options = options;
108230         },
108231
108232             //-------------------------------------------------------------------------
108233             _load: function(cb) {
108234
108235                 var self  = this;
108236                 var model = this._getModel();
108237
108238                 // todo: should this be loading these?...
108239                 // self.displayName = model.displayName;
108240                 // self.devID       = model.devID;
108241
108242                 var loadDevInfo = function(cb) {
108243                     var di = new devinfomod.DevInfo(self, model.devInfo);
108244                     di._load(function(err) {
108245                         if ( err )
108246                         return cb(err);
108247                     self.devInfo = di;
108248                     cb();
108249                     });
108250                 };
108251
108252                 var loadStores = function(cb) {
108253                     common.cascade(model.stores, function(e, cb) {
108254                         var store = new storemod.Store(self, e);
108255                         store._load(function(err) {
108256                             if ( err )
108257                             return cb(err);
108258                         self._stores[store.uri] = store;
108259                         return cb();
108260                         });
108261                     }, cb);
108262                 };
108263
108264                 loadDevInfo(function(err) {
108265                     if ( err )
108266                     return cb(err);
108267                 loadStores(cb);
108268                 });
108269             },
108270
108271             //-------------------------------------------------------------------------
108272             _updateModel: function(cb) {
108273                 var self = this;
108274                 if ( ! this._a._model || ! this._a._model.peers )
108275                     return cb(new common.InternalError('peer created on un-initialized adapter'));
108276                 var model = self._getModel();
108277                 // todo: should this be in this._getModel()?...
108278                 if ( ! model )
108279                 {
108280                     model = {
108281                         id:       self.id,
108282                         devInfo:  null,
108283                         stores:   [],
108284                         routes:   []
108285                     };
108286                     self._a._model.peers.push(model);
108287                 }
108288
108289                 model.isLocal         = 0;
108290                 model.url             = self.url;
108291                 model.devID           = self.devID;
108292                 model.displayName     = self.displayName;
108293                 model.auth            = self.auth;
108294                 model.username        = self.username;
108295                 model.password        = self.password;
108296                 model.lastSessionID   = self.lastSessionID
108297                     model.maxMsgSize      = self.maxMsgSize;
108298                 model.maxObjSize      = self.maxObjSize;
108299
108300                 common.cascade([
108301
108302                         // update the devInfo model
108303                         function(cb) {
108304                             if ( ! self.devInfo )
108305                     return cb();
108306                 return self.devInfo._updateModel(cb);
108307                         },
108308
108309                         // update the stores model
108310                         function(cb) {
108311                             // TODO: this should really be the responsibility of the Store class...
108312                             // NOTE: since bindings are not stored in Store, they need to be saved
108313                             //       and re-applied.
108314                             // TODO: or, perhaps better, i should purge all unwanted stores
108315                             //       instead of doing this brute-force method...
108316                             var bindings = _.object(_.map(model.stores, function(store) {
108317                                 return [store.uri, store.binding];
108318                             }));
108319                             model.stores = [];
108320                             common.cascade(_.values(self._stores), function(store, cb) {
108321                                 store._updateModel(cb);
108322                             }, function(err) {
108323                                 if ( err )
108324                                 return cb(err);
108325                             _.each(bindings, function(binding, uri) {
108326                                 var store = _.find(model.stores, function(s) { return s.uri == uri; });
108327                                 if ( ! store )
108328                                 return;
108329                             store.binding = binding;
108330                             });
108331                             return cb();
108332                             });
108333                         },
108334
108335                         ], cb);
108336
108337             },
108338
108339             //-------------------------------------------------------------------------
108340             _getModel: function() {
108341                 return _.find(this._a._model.peers,
108342                         function(e) { return e.id == this.id; }, this);
108343             },
108344
108345             //-------------------------------------------------------------------------
108346             _setRemoteInfo: function(devInfo, stores, cb) {
108347                 var self      = this;
108348                 self._model   = self._getModel();
108349                 devInfo._a    = self;
108350                 self.devInfo  = devInfo;
108351                 self.devInfo._updateModel(function(err) {
108352                     if ( err )
108353                     return cb(err);
108354                 // merge the new datastore info with any pre-existing store bindings
108355                 // step 1: prepare the new stores (clean up the URIs)
108356                 var lut = _.object(_.map(stores, function(store) {
108357                     store.uri = self.normUri(store.uri);
108358                     return [store.uri, store];
108359                 }));
108360                 // step 2: remove all stores that are no longer mentioned
108361                 self._stores = _.object(
108362                     _.map(
108363                         _.filter(_.keys(self._stores), function(oldUri) {
108364                             return _.indexOf(_.keys(lut), oldUri) >= 0;
108365                         }), function(uri) {
108366                             return [uri, self._stores[uri]];
108367                         }
108368                         )
108369                     );
108370                 // step 3: merge the datastore info for existing stores
108371                 var merge_stores = function(cb) {
108372                     common.cascade(_.values(self._stores), function(store, cb) {
108373                         store.merge(lut[store.uri], function(err) {
108374                             if ( err )
108375                             return cb(err);
108376                         delete lut[store.uri];
108377                         return cb();
108378                         });
108379                     }, cb);
108380                 };
108381                 // step 4: add new datastores
108382                 var add_stores = function(cb) {
108383                     common.cascade(_.values(lut), function(store, cb) {
108384                         self.addStore(store, cb);
108385                     }, cb);
108386                 };
108387                 merge_stores(function(err) {
108388                     if ( err )
108389                     return cb(err);
108390                 add_stores(cb);
108391                 });
108392                 });
108393             },
108394
108395             //-------------------------------------------------------------------------
108396             setRoute: function(localUri, remoteUri, autoMapped, cb) {
108397                 if ( _.isFunction(autoMapped) )
108398                     // defaulting 'autoMapped' to false
108399                     return this.setRoute(localUri, remoteUri, false, autoMapped);
108400                 var pmodel = this._getModel();
108401                 if ( ! pmodel )
108402                     return cb(new common.InternalError('could not locate this peer in local adapter'));
108403                 pmodel.routes = _.filter(pmodel.routes, function(r) {
108404                     return r.localUri != localUri && r.remoteUri != remoteUri;
108405                 });
108406                 pmodel.routes.push({localUri   : localUri,
108407                     remoteUri  : remoteUri,
108408                     autoMapped : autoMapped
108409                 });
108410                 // now search through previous bindings, breaking incorrect ones...
108411                 // NOTE: this requires that a router.recalculate() is called at
108412                 //       some point later since other valid bindings may now be
108413                 //       possible...
108414                 _.each(pmodel.stores, function(store) {
108415                     if ( store.uri != remoteUri
108416                         && ( ! store.binding || store.binding.uri != localUri ) )
108417                     {
108418                         return;
108419                     }
108420                     if ( ! store.binding )
108421                 {
108422                     store.binding = {
108423                         uri          : localUri,
108424                     autoMapped   : autoMapped,
108425                     localAnchor  : null,
108426                     remoteAnchor : null
108427                     };
108428                     return;
108429                 }
108430                 if ( store.uri == remoteUri && store.binding.uri == localUri )
108431                 {
108432                     store.binding.autoMapped = store.binding.autoMapped && autoMapped;
108433                     return;
108434                 }
108435                 store.binding = null;
108436                 return;
108437                 });
108438                 // TODO: this additional route may impact "smart routing" - recalculate?...
108439                 // TODO: saving adapter from peer --- SHOULD IT BE DOING THIS?...
108440                 // TODO: get transaction from a session!...
108441                 this._a._save(this._c._txn(), cb);
108442             },
108443
108444             //-------------------------------------------------------------------------
108445             sendRequest: function(session, contentType, data, cb) {
108446                 var xmlhttp;
108447
108448                 // TODO: shouldn't proxies just overwrite .sendRequest() ?...
108449                 if ( this._proxy )
108450                     return this._proxy.sendRequest(session, contentType, data, cb);
108451
108452                 var req = {
108453                     url     : session.info.respUri || this.url,
108454                     method  : 'POST',
108455                     headers : {'Content-Type': contentType},
108456                     body    : data
108457                 };
108458
108459                 xmlhttp = new XMLHttpRequest();
108460                 xmlhttp.open(req.method, req.url, false);
108461
108462                 xmlhttp.setRequestHeader("Content-Type", contentType);
108463                 xmlhttp.send(req.body);
108464
108465                 var response = {
108466                     headers: {
108467                         "Content-Type": xmlhttp.getResponseHeader("content-type")
108468                     },
108469                     body: xmlhttp.responseXML
108470                 };
108471                 return cb(null, response);
108472             }
108473
108474     });
108475
108476     return exports;
108477
108478 })();
108479
108480 module.exports = _self;
108481
108482 });
108483 define('ripple/platform/tizen/2.0/syncml-js-lib/router', function (require, exports, module) {
108484 // -*- coding: utf-8 -*-
108485 //-----------------------------------------------------------------------------
108486 // file: $Id$
108487 // lib:  syncml-js.router
108488 // auth: griffin <griffin@uberdev.org>
108489 // date: 2012/11/04
108490 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
108491 //-----------------------------------------------------------------------------
108492
108493 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
108494     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
108495     ctype = require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'),
108496     matcher = require('ripple/platform/tizen/2.0/syncml-js-lib/matcher'),
108497     stablematch = require('ripple/platform/tizen/2.0/syncml-js-lib/stablematch'),
108498     _self;
108499
108500 _self = (function () {
108501
108502     var exports = {};
108503
108504     //---------------------------------------------------------------------------
108505     exports.Router = common.Base.extend({
108506
108507         //-------------------------------------------------------------------------
108508         constructor: function(options) {
108509         },
108510
108511         //-------------------------------------------------------------------------
108512         getTargetUri: function(adapter, peer, sourceUri) {
108513             var pmodel = peer._getModel();
108514             for ( var idx=0 ; idx<pmodel.routes.length ; idx++ )
108515     {
108516         var route = pmodel.routes[idx];
108517         if ( route.localUri == sourceUri )
108518         return route.remoteUri;
108519     }
108520     for ( var idx=0 ; idx<pmodel.stores.length ; idx++ )
108521     {
108522         var store = pmodel.stores[idx];
108523         if ( store.binding && store.binding.uri == sourceUri )
108524         return store.uri;
108525     }
108526     return null;
108527         },
108528
108529         //-------------------------------------------------------------------------
108530         recalculate: function(adapter, peer, cb) {
108531             // the non-"SmartRouter" only connects manually-configured routes...
108532             var routes = _.filter(peer._getModel().routes,
108533                     function(r) { return ! r.autoMapped; });
108534             return this._setupRoutes(adapter, peer, routes, cb);
108535         },
108536
108537         //-------------------------------------------------------------------------
108538         _setupRoutes: function(adapter, peer, routes, cb) {
108539             // available local URIs
108540             var lset = _.map(adapter._getModel().stores,
108541                     function(s) { return adapter.normUri(s.uri); });
108542             // available remote URIs
108543             var rset = _.map(peer._getModel().stores,
108544                     function(s) { return peer.normUri(s.uri); });
108545
108546             // break all routes not listed
108547             var ruris = _.map(routes, function(r) { return r.remoteUri; });
108548             var xrset = _.filter(rset, function(uri) {
108549                 return _.indexOf(ruris, uri) < 0;
108550             });
108551             _.each(xrset, function(uri) {
108552                 var smodel = peer.getStore(uri)._getModel();
108553                 if ( ! smodel.binding )
108554                 return;
108555             smodel.binding = null;
108556             });
108557
108558             var err = null;
108559             _.each(routes, function(route) {
108560                 if ( err )
108561                 return;
108562
108563             route.localUri  = adapter.normUri(route.localUri);
108564             route.remoteUri = peer.normUri(route.remoteUri);
108565             if ( _.indexOf(rset, route.remoteUri) < 0
108566                 || _.indexOf(lset, route.localUri) < 0 )
108567             {
108568                 err = 'unable to route from "' + route.localUri
108569                 + '" (here) to "' + route.remoteUri
108570                 + '" (peer): no such stores or already routed elsewhere';
108571             return;
108572             }
108573
108574             lset = _.filter(lset, function(uri) { return uri != route.localUri; });
108575             rset = _.filter(rset, function(uri) { return uri != route.remoteUri; });
108576
108577
108578             var smodel = peer.getStore(route.remoteUri)._getModel();
108579             if ( smodel.binding && smodel.binding.uri == route.localUri )
108580                 return;
108581             smodel.binding = {
108582                 uri          : route.localUri,
108583                 autoMapped   : route.autoMapped,
108584                 localAnchor  : null,
108585                 remoteAnchor : null
108586             };
108587             });
108588
108589             if ( err )
108590                 return cb(err);
108591
108592             return cb();
108593         },
108594
108595         //-------------------------------------------------------------------------
108596         getBestTransmitContentType: function(adapter, peer, uri) {
108597             var lstore = adapter.getStore(uri);
108598             var rstore = peer.getStore(this.getTargetUri(adapter, peer, uri));
108599             return matcher.pickTransmitContentType(lstore, rstore);
108600         },
108601
108602     });
108603
108604     //---------------------------------------------------------------------------
108605     exports.SmartRouter = exports.Router.extend({
108606
108607         //-------------------------------------------------------------------------
108608         recalculate: function(adapter, peer, cb) {
108609
108610             // note: if you don't want smart routing, assign the non-SmartRouter
108611             //       router (i.e. syncml-js.Router) to the loaded context
108612
108613             // available local URIs
108614             var llut = _.object(
108615                 _.map(adapter._getModel().stores,
108616                     function(s) { return [adapter.normUri(s.uri), s]; }));
108617             var lset = _.keys(llut);
108618
108619             // available remote URIs
108620             var rlut = _.object(
108621                 _.map(peer._getModel().stores,
108622                     function(s) { return [adapter.normUri(s.uri), s]; }));
108623             var rset = _.keys(rlut);
108624
108625             // TODO: i am directly touching the model here.
108626             //       total i-rep violation.
108627             //       i'm embarrassed.
108628             //       fortunately, it's just between syncml-js classes...
108629             //       but now you know, doh! please don't blackmail me!... ;-)
108630
108631             // manual routes
108632             var pmodel = peer._getModel();
108633             pmodel.routes = _.filter(pmodel.routes,
108634                     function(r) { return ! r.autoMapped; });
108635
108636             // remove manual routes from available routes
108637             var uris = _.map(pmodel.routes, function(r) { return r.localUri; });
108638             lset = _.filter(lset, function(uri) {
108639                 return _.indexOf(uris, uri) < 0;
108640             });
108641             uris = _.map(pmodel.routes, function(r) { return r.remoteUri; });
108642             rset = _.filter(rset, function(uri) {
108643                 return _.indexOf(uris, uri) < 0;
108644             });
108645
108646             // match remaining stores
108647             var rankL = function(luri) {
108648                 var ret = _.rest(rset, 0);
108649                 ret.sort(function(a, b) {
108650                     return matcher.cmpStore(llut[luri], rlut[a], rlut[b]);
108651                 });
108652                 return ret;
108653             };
108654             var rankR = function(ruri) {
108655                 var ret = _.rest(lset, 0);
108656                 ret.sort(function(a, b) {
108657                     return matcher.cmpStore(rlut[ruri], llut[a], llut[b]);
108658                 });
108659                 return ret;
108660             };
108661             var matches = stablematch.match(lset, rset, rankL, rankR);
108662
108663             // add them to the routes (as auto-routed)
108664             for ( var idx=0 ; idx<matches.length ; idx++ )
108665             {
108666                 var pair = matches[idx];
108667                 pmodel.routes.push({
108668                     localUri   : pair[0],
108669                     remoteUri  : pair[1],
108670                     autoMapped : true
108671                 });
108672             }
108673
108674             return this._setupRoutes(adapter, peer, pmodel.routes, cb);
108675         },
108676
108677     });
108678
108679     return exports;
108680
108681 })();
108682
108683 module.exports = _self;
108684
108685 });
108686 define('ripple/platform/tizen/2.0/syncml-js-lib/stablematch', function (require, exports, module) {
108687 // -*- coding: utf-8 -*-
108688 //-----------------------------------------------------------------------------
108689 // file: $Id$
108690 // desc: implements a solution to the stable matching problem using a
108691 //       left-optimized algorithm. shamelessly adapted from:
108692 //         https://github.com/paulgb/Python-Gale-Shapley/
108693 // auth: metagriffin <mg.npmjs@uberdev.org>
108694 // date: 2012/12/29
108695 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
108696 //-----------------------------------------------------------------------------
108697
108698 var _self = (function () {
108699
108700     var exports = {};
108701
108702     // TODO: figure out how to pull this dynamically from package.json...
108703     exports.version = '0.0.4';
108704
108705     //---------------------------------------------------------------------------
108706     exports.match = function(A, B, rankA, rankB) {
108707         if ( ! A || ! B || ! A.length || ! B.length ) {
108708             return [];
108709         }
108710         if ( A.length == B.length ) {
108711             return exports._match(A, B, rankA, rankB);
108712         }
108713
108714         // TODO: this is a brute-force implementation of getting both
108715         //       lists to be of symmetric length... make this "better".
108716         //       for example, build this directly into _match() or use
108717         //       deterministic exclusion of the longer data set.
108718
108719         var sA   = _.rest(A, 0);
108720         var sB   = _.rest(B, 0);
108721         var mlen = Math.max(sA, sB);
108722         while ( sA.length < mlen )
108723             sA.push(null);
108724         while ( sB.length < mlen )
108725             sB.push(null);
108726         var sRA  = function(a) {
108727             var ret = rankA(a);
108728             while ( ret.length < mlen )
108729                 ret.push(null);
108730             return ret;
108731         };
108732         var sRB  = function(b) {
108733             var ret = rankB(b);
108734             while ( ret.length < mlen )
108735                 ret.push(null);
108736             return ret;
108737         };
108738         var ret = exports._match(sA, sB, sRA, sRB);
108739         return _.filter(ret, function(pair) {
108740             return pair[0] != null && pair[1] != null;
108741         });
108742     };
108743
108744     //---------------------------------------------------------------------------
108745     exports._match = function(A, B, rankA, rankB) {
108746         // this translates sets A and B to indeces, since _imatch can only work
108747         // with sets of elements that can be used as the key in a hash (in this
108748         // implementation).
108749         var iA  = _.range(A.length);
108750         var iB  = _.range(B.length);
108751         var iRA = function(ia) {
108752             var ret = rankA(A[ia]);
108753             return _.map(ret, function(item) {
108754                 return _.indexOf(B, item);
108755             });
108756         };
108757         var iRB = function(ib) {
108758             var ret = rankB(B[ib]);
108759             return _.map(ret, function(item) {
108760                 return _.indexOf(A, item);
108761             });
108762         };
108763         var ret = exports._imatch(iA, iB, iRA, iRB);
108764         return _.map(ret, function(item) {
108765             return [A[item[0]], B[item[1]]];
108766         });
108767     };
108768
108769     //---------------------------------------------------------------------------
108770     exports._imatch = function(A, B, rankA, rankB) {
108771         // TODO: improve this... it was a brute-force porting of
108772         //         https://github.com/paulgb/Python-Gale-Shapley
108773         //       without any eye on optimal outcome or performance...
108774         //: `partners` is a paring hash of { a => [b, rank] }
108775         var partners = {};
108776         _.each(A, function(a) {
108777             partners[a] = [rankA(a)[0], 0];
108778         });
108779         //: `stable` indicates stability of the current pairing in `partners`
108780         var stable = false;
108781         while ( ! stable )
108782         {
108783             stable = true;
108784             _.each(B, function(b) {
108785                 var paired = false;
108786                 for ( var n=0 ; n<A.length ; n++ )
108787                 {
108788                     var a = rankB(b)[n];
108789                     var pair = partners[a];
108790                     if ( pair[0] == b )
108791                     {
108792                         if ( paired )
108793                         {
108794                             stable = false;
108795                             partners[a] = [rankA(a)[pair[1] + 1], pair[1] + 1];
108796                         }
108797                         else
108798                             paired = true;
108799                     }
108800                 }
108801             });
108802         }
108803         return _.map(_.keys(partners), function(a) {
108804             return [a, partners[a][0]];
108805         });
108806     };
108807
108808     return exports;
108809 })();
108810
108811 module.exports = _self;
108812
108813 });
108814 define('ripple/platform/tizen/2.0/syncml-js-lib/state', function (require, exports, module) {
108815 // -*- coding: utf-8 -*-
108816 //-----------------------------------------------------------------------------
108817 // file: $Id$
108818 // auth: metagriffin <metagriffin@uberdev.org>
108819 // date: 2012/10/27
108820 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
108821 //-----------------------------------------------------------------------------
108822
108823 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
108824     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
108825     _self;
108826
108827 _self = (function () {
108828     var exports = {};
108829
108830     //---------------------------------------------------------------------------
108831     exports.makeCommand = function(options) {
108832         return _.defaults({}, options, {
108833             // ?
108834         });
108835     };
108836
108837     //---------------------------------------------------------------------------
108838     exports.makeStats = function(options) {
108839         return _.defaults({}, options, {
108840             mode      : null,
108841                hereAdd   : 0,
108842                hereMod   : 0,
108843                hereDel   : 0,
108844                hereErr   : 0,
108845                peerAdd   : 0,
108846                peerMod   : 0,
108847                peerDel   : 0,
108848                peerErr   : 0,
108849                conflicts : 0,
108850                merged    : 0,
108851         });
108852     };
108853
108854     //---------------------------------------------------------------------------
108855     exports.makeSessionInfo = function(options) {
108856         return _.defaults({}, options, {
108857             id           : null,
108858                msgID        : null,
108859                cmdID        : 0,
108860                dsstates     : {},
108861                lastCommands : [],
108862                stats        : exports.makeStats()
108863         });
108864     };
108865
108866     //---------------------------------------------------------------------------
108867     exports.makeStoreSyncState = function(options) {
108868         return _.defaults({}, options, {
108869             uri        : null,
108870                peerUri    : null,
108871                lastAnchor : null,
108872                nextAnchor : '' + common.ts(),
108873                mode       : constant.ALERT_TWO_WAY,
108874                action     : null,
108875                stats      : exports.makeStats()
108876         });
108877     };
108878
108879     //---------------------------------------------------------------------------
108880     exports.makeSession = function(options) {
108881         return new (function() {
108882             this.context   = options.context || null;
108883             this.ua        = options.ua      || null;
108884             this.txn       = options.txn     || options.context.txn;
108885             this.adapter   = options.adapter || null;
108886             this.peer      = options.peer    || null;
108887             this.info      = options.info    || null;
108888             this.discover  = options.discover ? true : false;
108889             this.isServer  = options.isServer ? true : false;
108890             this.nextCmdID = function() {
108891                 this.info.cmdID += 1;
108892                 return this.info.cmdID;
108893             };
108894         })();
108895
108896         // return _.defaults({}, options, {
108897         //   context : null,
108898         //   adapter : null,
108899         //   peer    : null,
108900         //   info    : null
108901         // });
108902     };
108903
108904     var smult = function(s, count) {
108905         var ret = '';
108906         for ( var idx=0 ; idx<count ; idx++ )
108907             ret += s;
108908         return ret;
108909     };
108910
108911     var num2str = function(num) {
108912         // TODO: i18n...
108913         // TODO: this is *UGLY*
108914         // TODO: OMG, i'm *so* embarrassed
108915         // TODO: but it works... sort of.
108916         if ( num == 0 )
108917             return '-';
108918         var ret = '';
108919         num = '' + num;
108920         for ( var idx=num.length ; idx>0 ; idx-=3 )
108921         {
108922             if ( ret.length > 0 )
108923                 ret = ',' + ret;
108924             ret = num.charAt(idx - 1) + ret;
108925             if ( idx - 1 > 0 )
108926                 ret = num.charAt(idx - 2) + ret;
108927             if ( idx - 2 > 0 )
108928                 ret = num.charAt(idx - 3) + ret;
108929         }
108930         return ret;
108931     };
108932
108933     var center = function(s, wid, pad) {
108934         // todo: is there no way to get sprintf to do this for me???...
108935         pad = pad || ' ';
108936         if ( wid <= s.length )
108937             return s;
108938         var diff = wid - s.length;
108939         return smult(pad, Math.floor(diff / 2)) + s + smult(pad, Math.ceil(diff / 2));
108940     };
108941
108942     var right = function(s, wid, pad) {
108943         // todo: is there no way to get sprintf to do this for me???...
108944         pad = pad || ' ';
108945         if ( wid <= s.length )
108946             return s;
108947         return smult(pad, wid - s.length) + s;
108948     };
108949
108950     //---------------------------------------------------------------------------
108951     // TODO: this should probably be put into another package...
108952     exports.describeStats = function(stats, stream, options) {
108953
108954         // ASCII OBJECTIVE:
108955         // +----------------------------------------------------------------------------------+
108956         // |                                      TITLE                                       |
108957         // +----------+------+-------------------------+--------------------------+-----------+
108958         // |          |      |          Local          |          Remote          | Conflicts |
108959         // |   Source | Mode |  Add  | Mod | Del | Err |   Add  | Mod | Del | Err | Col | Mrg |
108960         // +----------+------+-------+-----+-----+-----+--------+-----+-----+-----+-----+-----+
108961         // | contacts |  <=  |   -   |  -  |  -  |  -  | 10,387 |  -  |  -  |  -  |  -  |  -  |
108962         // |     note |  SS  | 1,308 |  -  |   2 |  -  |    -   |  -  |  -  |  -  |  -  |  -  |
108963         // +----------+------+-------+-----+-----+-----+--------+-----+-----+-----+-----+-----+
108964         // |                  1,310 local changes and 10,387 remote changes.                  |
108965         // +----------------------------------------------------------------------------------+
108966
108967         // UNICODE OBJECTIVE:
108968         // ┌──────────────────────────────────────────────────────────────────────────────────┐
108969         // │                                      TITLE                                       │
108970         // ├──────────┬──────┬─────────────────────────┬──────────────────────────┬───────────┤
108971         // │          │      │          Local          │          Remote          │ Conflicts │
108972         // │   Source │ Mode │  Add    Mod   Del   Err │   Add    Mod   Del   Err │ Col   Mrg │
108973         // ├──────────┼──────┼───────┼─────┼─────┼─────┼────────┼─────┼─────┼─────┼─────┼─────┤
108974         // │ contacts │  <=  │       │     │     │     │ 10,387 │     │     │     │     │     │
108975         // │     note │  SS  │ 1,308 │     │   2 │     │        │     │     │     │     │     │
108976         // ├──────────┴──────┴───────┴─────┴─────┴─────┴────────┴─────┴─────┴─────┴─────┴─────┤
108977         // │                  1,310 local changes and 10,387 remote changes.                  │
108978         // └──────────────────────────────────────────────────────────────────────────────────┘
108979
108980         // todo: perhaps the fancy version should have color-coding as well?...
108981
108982         options = _.defaults({}, options, {
108983             title      : null,
108984                 details    : true,
108985                 totals     : true,
108986                 ascii      : false,
108987                 gettext    : function(text) { return text; }
108988         });
108989
108990         var modeStringLut = _.object([
108991                 [constant.SYNCTYPE_TWO_WAY             , '<>'],
108992                 [constant.SYNCTYPE_SLOW_SYNC           , 'SS'],
108993                 [constant.SYNCTYPE_ONE_WAY_FROM_CLIENT , '->'],
108994                 [constant.SYNCTYPE_REFRESH_FROM_CLIENT , '=>'],
108995                 [constant.SYNCTYPE_ONE_WAY_FROM_SERVER , '<-'],
108996                 [constant.SYNCTYPE_REFRESH_FROM_SERVER , '<=']
108997                 ]);
108998
108999         if ( options.ascii )
109000         {
109001
109002             // unicode graphing characters: ('\xe2\x94\x80' - '\xe2\x94\xc0')
109003             // mapping table unicode ==> ascii
109004
109005             glyphs = {
109006                 '─': '-',
109007                 '━': '-',
109008                 '│': '|',
109009                 '┃': '|',
109010                 '┄': '-',
109011                 '┅': '-',
109012                 '┆': '|',
109013                 '┇': '|',
109014                 '┈': '-',
109015                 '┉': '-',
109016                 '┊': '|',
109017                 '┋': '|',
109018                 '┌': '+',
109019                 '┍': '+',
109020                 '┎': '+',
109021                 '┏': '+',
109022                 '┐': '+',
109023                 '┑': '+',
109024                 '┒': '+',
109025                 '┓': '+',
109026                 '└': '+',
109027                 '┕': '+',
109028                 '┖': '+',
109029                 '┗': '+',
109030                 '┘': '+',
109031                 '┙': '+',
109032                 '┚': '+',
109033                 '┛': '+',
109034                 '├': '+',
109035                 '┝': '+',
109036                 '┞': '+',
109037                 '┟': '+',
109038                 '┠': '+',
109039                 '┡': '+',
109040                 '┢': '+',
109041                 '┣': '+',
109042                 '┤': '+',
109043                 '┥': '+',
109044                 '┦': '+',
109045                 '┧': '+',
109046                 '┨': '+',
109047                 '┩': '+',
109048                 '┪': '+',
109049                 '┫': '+',
109050                 '┬': '+',
109051                 '┭': '+',
109052                 '┮': '+',
109053                 '┯': '+',
109054                 '┰': '+',
109055                 '┱': '+',
109056                 '┲': '+',
109057                 '┳': '+',
109058                 '┴': '+',
109059                 '┵': '+',
109060                 '┶': '+',
109061                 '┷': '+',
109062                 '┸': '+',
109063                 '┹': '+',
109064                 '┺': '+',
109065                 '┻': '+',
109066                 '┼': '+',
109067                 '┽': '+',
109068                 '┾': '+',
109069                 '┿': '+',
109070             };
109071
109072             var UnicodeToAsciiStream = common.Stream.extend({
109073                 constructor: function(stream) {
109074                     this.stream = stream;
109075                 },
109076                 write: function(data) {
109077                     if ( data == undefined )
109078                 return;
109079             var ascii = '';
109080             for ( var idx=0 ; idx<data.length ; idx++ )
109081             {
109082                 var el = data[idx];
109083                 if ( glyphs[el] != undefined )
109084                 ascii += glyphs[el];
109085                 else
109086                 ascii += el;
109087             }
109088             this.stream.write(ascii);
109089                 }
109090             });
109091
109092             stream = new UnicodeToAsciiStream(stream);
109093
109094         }
109095
109096         // todo: this does not handle the case where the title is wider than the table.
109097
109098         var wSrc  = options.gettext('Source').length;
109099         var wMode = options.gettext('Mode').length;
109100         var wCon  = options.gettext('Conflicts').length;
109101         var wCol  = options.gettext('Col').length;
109102         var wMrg  = options.gettext('Mrg').length;
109103         var wHereAdd = wPeerAdd = options.gettext('Add').length;
109104         var wHereMod = wPeerMod = options.gettext('Mod').length;
109105         var wHereDel = wPeerDel = options.gettext('Del').length;
109106         var wHereErr = wPeerErr = options.gettext('Err').length
109107
109108             var totLoc = 0;
109109         var totRem = 0;
109110         var totErr = 0;
109111         var totCol = 0;
109112         var totMrg = 0;
109113
109114         _.each(stats, function(value, key) {
109115             wSrc  = Math.max(wSrc, key.length);
109116             wMode = Math.max(wMode, modeStringLut[value.mode].length);
109117             wCol  = Math.max(wCol, num2str(value.conflicts).length);
109118             wMrg  = Math.max(wMrg, num2str(value.merged).length);
109119             wHereAdd = Math.max(wHereAdd, num2str(value.hereAdd).length);
109120             wPeerAdd = Math.max(wPeerAdd, num2str(value.peerAdd).length);
109121             wHereMod = Math.max(wHereMod, num2str(value.hereMod).length);
109122             wPeerMod = Math.max(wPeerMod, num2str(value.peerMod).length);
109123             wHereDel = Math.max(wHereDel, num2str(value.hereDel).length);
109124             wPeerDel = Math.max(wPeerDel, num2str(value.peerDel).length);
109125             wHereErr = Math.max(wHereErr, num2str(value.hereErr).length);
109126             wPeerErr = Math.max(wPeerErr, num2str(value.peerErr).length);
109127             totLoc += value.hereAdd + value.hereMod + value.hereDel;
109128             totRem += value.peerAdd + value.peerMod + value.peerDel;
109129             totErr += value.hereErr + value.peerErr;
109130             totCol += value.conflicts;
109131             totMrg += value.merged;
109132         });
109133
109134         // TODO: i'm 100% sure there is a python library that can do this for me...
109135
109136         if ( wCon > wCol + 3 + wMrg )
109137         {
109138             diff = wCon - ( wCol + 3 + wMrg );
109139             wCol += diff / 2;
109140             wMrg = wCon - 3 - wCol;
109141         }
109142         else
109143             wCon = wCol + 3 + wMrg;
109144
109145         if ( options.details )
109146             tWid = ( wSrc + 3 + wMode + 3
109147                     + wHereAdd + wHereMod + wHereDel + wHereErr + 9 + 3
109148                     + wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 + 3
109149                     + wCon );
109150         else
109151             tWid = options.title ? options.title.length : 0;
109152
109153         if ( options.totals )
109154         {
109155             // TODO: oh dear. from an i18n POV, this is *horrible*!...
109156             sumlist = [];
109157             // for val, singular, plural in [
109158             _.each([
109159                     [totLoc, options.gettext('local change'), options.gettext('local changes')],
109160                     [totRem, options.gettext('remote change'), options.gettext('remote changes')],
109161                     [totErr, options.gettext('error'), options.gettext('errors')]
109162                     ], function(set) {
109163                         if ( set[0] <= 0 )
109164                 return;
109165             sumlist.push(num2str(set[0]) + ' ' + ( set[0] == 1 ? set[1] : set[2] ));
109166                     });
109167             if ( sumlist.length <= 0 )
109168                 sumlist = options.gettext('No changes');
109169             else if ( sumlist.length == 1 )
109170                 sumlist = sumlist[0];
109171             else
109172                 sumlist = ( sumlist.slice(0, -1).join(', ') + ' '
109173                         + options.gettext('and') + ' ' + sumlist[sumlist.length - 1] );
109174             if ( totMrg > 0 || totCol > 0 )
109175             {
109176                 sumlist += ': ';
109177                 if ( totMrg == 1 )
109178                     sumlist += num2str(totMrg) + ' ' + options.gettext('merge');
109179                 else if ( totMrg > 1 )
109180                     sumlist += num2str(totMrg) + ' ' + options.gettext('merges');
109181                 if ( totMrg > 0 && totCol > 0 )
109182                     sumlist += ' ' + options.gettext('and') + ' ';
109183                 if ( totCol == 1 )
109184                     sumlist += num2str(totCol) + ' ' + options.gettext('conflict');
109185                 else if ( totCol > 1 )
109186                     sumlist += num2str(totCol) + ' ' + options.gettext('conflicts');
109187             }
109188             sumlist += '.';
109189             if ( sumlist.length > tWid )
109190             {
109191                 wSrc += sumlist.length - tWid;
109192                 tWid = sumlist.length;
109193             }
109194         }
109195
109196         if ( options.title )
109197         {
109198             stream.write('┏━' + smult('━', tWid) + '━┓\n');
109199             stream.write('┃ ' + center(options.title, tWid) + ' ┃\n');
109200         }
109201
109202         if ( options.details )
109203         {
109204             if ( options.title )
109205                 stream.write('┡━'
109206                         + smult('━', wSrc)
109207                         + '━┯━'
109208                         + smult('━', wMode)
109209                         + '━┯━'
109210                         + smult('━', ( wHereAdd + wHereMod + wHereDel + wHereErr + 9 ))
109211                         + '━┯━'
109212                         + smult('━', ( wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 ))
109213                         + '━┯━'
109214                         + smult('━', wCon)
109215                         + '━┩\n'
109216                         );
109217             else
109218                 stream.write('┌─'
109219                         + smult('─', wSrc)
109220                         + '─┬─'
109221                         + smult('─', wMode)
109222                         + '─┬─'
109223                         + smult('─', ( wHereAdd + wHereMod + wHereDel + wHereErr + 9 ))
109224                         + '─┬─'
109225                         + smult('─', ( wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 ))
109226                         + '─┬─'
109227                         + smult('─', wCon)
109228                         + '─┐\n'
109229                         );
109230
109231             stream.write('│ ' + smult(' ', wSrc));
109232             stream.write(' │ ' + smult(' ', wMode));
109233             stream.write(' │ ' + center(options.gettext('Local'), wHereAdd + wHereMod + wHereDel + wHereErr + 9 ));
109234             stream.write(' │ ' + center(options.gettext('Remote'), wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 ));
109235             stream.write(' │ ' + center(options.gettext('Conflicts'), wCon));
109236             stream.write(' │\n');
109237
109238             stream.write('│ ' + right(options.gettext('Source'), wSrc));
109239             stream.write(' │ ' + center(options.gettext('Mode'), wMode));
109240             stream.write(' │ ' + center(options.gettext('Add'), wHereAdd));
109241             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Mod'), wHereMod));
109242             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Del'), wHereDel));
109243             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Err'), wHereErr));
109244             stream.write(' │ ' + center(options.gettext('Add'), wPeerAdd));
109245             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Mod'), wPeerMod));
109246             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Del'), wPeerDel));
109247             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Err'), wPeerErr));
109248             stream.write(' │ ' + center(options.gettext('Col'), wCol));
109249             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Mrg'), wMrg));
109250             stream.write(' │\n');
109251
109252             stream.write('├─' + smult('─', wSrc)
109253                     + '─┼─' + smult('─', wMode)
109254                     + '─┼─' + smult('─', wHereAdd)
109255                     + '─┼─' + smult('─', wHereMod)
109256                     + '─┼─' + smult('─', wHereDel)
109257                     + '─┼─' + smult('─', wHereErr)
109258                     + '─┼─' + smult('─', wPeerAdd)
109259                     + '─┼─' + smult('─', wPeerMod)
109260                     + '─┼─' + smult('─', wPeerDel)
109261                     + '─┼─' + smult('─', wPeerErr)
109262                     + '─┼─' + smult('─', wCol)
109263                     + '─┼─' + smult('─', wMrg)
109264                     + '─┤\n'
109265                     );
109266
109267             var numcol = function(val, wid) {
109268                 if ( val == 0 )
109269                     return ' │ ' + center(options.ascii ? '-' : ' ', wid);
109270                 return ' │ ' + right(num2str(val), wid);
109271             };
109272
109273             var keys = _.keys(stats);
109274             // todo: sort case insensitively...
109275             keys.sort();
109276             _.each(keys, function(key) {
109277                 var stat = stats[key];
109278                 stream.write('│ ' + right(key, wSrc));
109279                 stream.write(' │ ' + center(modeStringLut[stat.mode], wMode));
109280                 stream.write(numcol(stat.hereAdd, wHereAdd));
109281                 stream.write(numcol(stat.hereMod, wHereMod));
109282                 stream.write(numcol(stat.hereDel, wHereDel));
109283                 stream.write(numcol(stat.hereErr, wHereErr));
109284                 stream.write(numcol(stat.peerAdd, wPeerAdd));
109285                 stream.write(numcol(stat.peerMod, wPeerMod));
109286                 stream.write(numcol(stat.peerDel, wPeerDel));
109287                 stream.write(numcol(stat.peerErr, wPeerErr));
109288                 stream.write(numcol(stat.conflicts, wCol));
109289                 stream.write(numcol(stat.merged, wMrg));
109290                 stream.write(' │\n');
109291             });
109292
109293             if ( options.totals )
109294                 stream.write('├─');
109295             else
109296                 stream.write('└─');
109297
109298             stream.write(smult('─', wSrc)
109299                     + '─┴─' + smult('─', wMode)
109300                     + '─┴─' + smult('─', wHereAdd)
109301                     + '─┴─' + smult('─', wHereMod)
109302                     + '─┴─' + smult('─', wHereDel)
109303                     + '─┴─' + smult('─', wHereErr)
109304                     + '─┴─' + smult('─', wPeerAdd)
109305                     + '─┴─' + smult('─', wPeerMod)
109306                     + '─┴─' + smult('─', wPeerDel)
109307                     + '─┴─' + smult('─', wPeerErr)
109308                     + '─┴─' + smult('─', wCol)
109309                     + '─┴─' + smult('─', wMrg)
109310                     );
109311
109312             if ( options.totals )
109313                 stream.write('─┤\n');
109314             else
109315                 stream.write('─┘\n');
109316         }
109317
109318         // ─━│┃┄┅┆┇┈┉┊┋┼┽┾┿
109319         // ┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛
109320         // ├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫
109321         // ┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻
109322
109323         if ( options.totals )
109324         {
109325             if ( !! options.title && ! options.details )
109326                 stream.write('┌─' + smult('─', tWid) + '─┐\n');
109327             stream.write('│ ' + center(sumlist, tWid));
109328             stream.write(' │\n');
109329             stream.write('└─' + smult('─', tWid) + '─┘\n');
109330         }
109331
109332         return;
109333
109334     };
109335
109336     return exports;
109337
109338 })();
109339
109340 module.exports = _self;
109341
109342 });
109343 define('ripple/platform/tizen/2.0/syncml-js-lib/storage', function (require, exports, module) {
109344 // -*- coding: utf-8 -*-
109345 //-----------------------------------------------------------------------------
109346 // file: $Id$
109347 // lib:  syncml-js.storage
109348 // auth: griffin <griffin@uberdev.org>
109349 // date: 2012/10/31
109350 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
109351 //-----------------------------------------------------------------------------
109352
109353 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
109354     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant');
109355
109356 var _self = (function () {
109357
109358     var exports = {};
109359
109360     //---------------------------------------------------------------------------
109361     _.extend(exports, {
109362
109363         //-------------------------------------------------------------------------
109364         errstr: function(target) {
109365             if ( target.error && typeof(target.error.toString) == 'function' )
109366         return target.error.toString();
109367     var ret = '';
109368     var count = 0;
109369     for ( var key in target.error )
109370         count += 1;
109371     if ( count == 1 && target.error.name )
109372         ret = '' + target.error.name;
109373     else
109374     {
109375         ret = '{';
109376         for ( var key in target.error )
109377     {
109378         ret += key + ': ' + target.error[key];
109379         count -= 1;
109380         if ( count > 0 )
109381         ret += ', ';
109382     }
109383     }
109384     if ( target.errorCode )
109385     {
109386         if ( ret.length <= 0 || ret == '{}' )
109387             ret = '' + target.errorCode;
109388         else
109389             ret = '[' + target.errorCode + '] ' + ret;
109390     }
109391     if ( ret.length <= 0 || ret == '{}' )
109392         // last ditch effort...
109393         ret = common.prettyJson(target);
109394     return ret;
109395         },
109396
109397             //-------------------------------------------------------------------------
109398             openDatabase: function(context, cb) {
109399                 var dbreq = context.storage.indexedDB.open(context.dbname, 1);
109400                 dbreq.onblocked = function(event) {
109401                     cb({code: 'syncml-js.storage.OD.10',
109402                         message: 'database blocked by other process/tab/window'});
109403                 };
109404                 dbreq.onerror = function(event) {
109405                     var errmsg = exports.errstr(event.target);
109406                     cb({code: 'syncml-js.storage.OD.20',
109407                         message: 'failed to open syncml-js database: ' + errmsg});
109408                 };
109409                 dbreq.onupgradeneeded = function(event) {
109410
109411
109412                     var db = event.target.result;
109413
109414                     var adapterTable = db.createObjectStore('adapter', {keyPath: 'id'});
109415                     adapterTable.createIndex('isLocal', 'isLocal', {unique: false});
109416                     adapterTable.createIndex('devID', 'devID', {unique: true});
109417
109418                     var mappingTable = db.createObjectStore(
109419                             'mapping',
109420                             {keyPath: ['store_id', 'guid']});
109421                     mappingTable.createIndex('store_id', 'store_id', {unique: false});
109422                     // mappingTable.createIndex('guid', 'guid', {unique: false});
109423                     // mappingTable.createIndex('luid', 'luid', {unique: false});
109424
109425                     var changeTable = db.createObjectStore(
109426                             'change',
109427                             {keyPath: ['store_id', 'item_id']});
109428                     changeTable.createIndex('store_id', 'store_id', {unique: false});
109429                     // changeTable.createIndex('item_id', 'item_id', {unique: false});
109430
109431                 };
109432                 dbreq.onsuccess = function(event) {
109433                     cb(null, event.target.result);
109434                 };
109435             },
109436
109437             //-------------------------------------------------------------------------
109438             getTransaction: function(db, tables, mode) {
109439                 // NOTE: the spec says passing in null should be valid... but
109440                 //       mozilla's indexedDB seems to barf with:
109441                 //         [Exception... "The operation failed because the
109442                 //         requested database object could not be found. For
109443                 //         example, an object store did not exist but was
109444                 //         being opened."  code: "8" nsresult: "0x80660003
109445                 //         (NotFoundError)"
109446                 if ( ! tables )
109447                     tables = ['adapter','mapping','change'];
109448                 if ( ! mode )
109449                     mode = 'readwrite';
109450                 return db.transaction(tables, mode);
109451             },
109452
109453             //-------------------------------------------------------------------------
109454             dumpDatabase: function(context, cb) {
109455
109456                 var ret = {};
109457                 var txn = context._txn();
109458
109459                 var steps = [
109460                     function(cb) {
109461                         exports.getAll(context, txn.objectStore('adapter'), {}, function(err, adapters) {
109462                             ret.adapter = adapters;
109463                             return cb(err);
109464                         });
109465                     },
109466                     function(cb) {
109467                         exports.getAll(context, txn.objectStore('mapping'), {}, function(err, mappings) {
109468                             ret.mapping = mappings;
109469                             return cb(err);
109470                         });
109471                     },
109472                     function(cb) {
109473                         exports.getAll(context, txn.objectStore('change'), {}, function(err, changes) {
109474                             ret.change = changes;
109475                             return cb(err);
109476                         });
109477                     }
109478                 ];
109479
109480                 common.cascade(steps, function(step, cb) {
109481                     return step(cb);
109482                 }, function(err) {
109483                     return cb(err, ret);
109484                 });
109485             },
109486
109487             //-------------------------------------------------------------------------
109488             clearDatabase: function(context, cb) {
109489                 var dbreq = context.storage.indexedDB.open(context.dbname, 1);
109490                 dbreq.onblocked = function(event) {
109491                     cb({code: 'syncml-js.storage.CD.10',
109492                         message: 'database blocked by other process/tab/window'});
109493                 };
109494                 dbreq.onerror = function(event) {
109495                     var errmsg = exports.errstr(event.target);
109496                     cb({code: 'syncml-js.storage.CD.20',
109497                         message: 'failed to open syncml-js database: ' + errmsg});
109498                 };
109499                 dbreq.onsuccess = function(event) {
109500                     var db = event.target.result;
109501                     db.onerror = dbreq.onerror;
109502                     async.map(['adapter', 'mapping', 'change'], function(name, cb) {
109503                         cb();
109504                     }, function(err) {
109505                         if ( err )
109506                         return cb(err);
109507                     db.close();
109508                     });
109509                 };
109510             },
109511
109512             //-------------------------------------------------------------------------
109513             getAll: function(context, source, options, cb) {
109514                 // supported options:
109515                 //   - range
109516                 //   - only
109517                 options = options || {};
109518                 var range = options.range;
109519                 if ( ! range && options.only )
109520                     range = context.storage.IDBKeyRange.only(options.only);
109521                 var req = source.openCursor(range);
109522                 var ret = [];
109523                 req.onsuccess = function(event) {
109524                     var cursor = event.target.result;
109525                     if ( cursor )
109526                     {
109527                         ret.push(cursor.value);
109528                         // ret.push({key: cursor.key, value: cursor.value});
109529                         return cursor.continue();
109530                     }
109531                     cb(null, ret);
109532                 };
109533                 req.onerror = function(event) {
109534                     cb(exports.errstr(event.target));
109535                 };
109536             },
109537
109538             //-------------------------------------------------------------------------
109539             put: function(store, object, cb) {
109540                 var req = store.put(object);
109541                 req.onsuccess = function(event) { cb(); };
109542                 req.onerror = function(event) {
109543                     cb(exports.errstr(event.target));
109544                 };
109545             },
109546
109547             //-------------------------------------------------------------------------
109548             delete: function(store, objectID, cb) {
109549                 var req = store.delete(objectID);
109550                 req.onsuccess = function(event) { cb(); };
109551                 req.onerror = function(event) {
109552                     cb(exports.errstr(event.target));
109553                 };
109554             },
109555
109556             //-------------------------------------------------------------------------
109557             deleteAll: function(source, matches, cb) {
109558                 var req = source.openCursor();
109559                 req.onsuccess = function(event) {
109560                     var cursor = event.target.result;
109561                     if ( cursor )
109562                     {
109563                         for (key in matches)
109564                             if ( matches[key] != cursor.value[key] )
109565                                 return cursor.continue();
109566                         exports.delete(source, cursor.key, function(err) {
109567                             if ( err )
109568                             return cb(err);
109569                         return cursor.continue();
109570                         });
109571                         return;
109572                     }
109573                     cb(null);
109574                 };
109575                 req.onerror = function(event) {
109576                     cb(exports.errstr(event.target));
109577                 };
109578             },
109579
109580             //-------------------------------------------------------------------------
109581             iterateCursor: function(openCursor, iterator, cb) {
109582                 openCursor.onsuccess = function(event) {
109583                     var cursor = event.target.result;
109584                     if ( ! cursor )
109585                         return cb();
109586                     iterator(cursor.value.value, cursor.value.id, function(err) {
109587                         if ( err )
109588                         return cb(err);
109589                     return cursor.continue();
109590                     });
109591                 };
109592                 openCursor.onerror = function(event) {
109593                     cb(exports.errstr(event.target));
109594                 };
109595             }
109596
109597     });
109598
109599     return exports;
109600
109601 })();
109602
109603 module.exports = _self;
109604
109605 });
109606 define('ripple/platform/tizen/2.0/syncml-js-lib/store', function (require, exports, module) {
109607 // -*- coding: utf-8 -*-
109608 //-----------------------------------------------------------------------------
109609 // file: $Id$
109610 // lib:  syncml-js.store
109611 // auth: griffin <griffin@uberdev.org>
109612 // date: 2012/11/04
109613 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
109614 //-----------------------------------------------------------------------------
109615
109616
109617 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
109618     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
109619     ctype = require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'),
109620     storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'),
109621     ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree');
109622
109623
109624 var _self = (function () {
109625     var exports = {};
109626
109627     //---------------------------------------------------------------------------
109628     exports.Store = common.Base.extend({
109629
109630         //-------------------------------------------------------------------------
109631         constructor: function(adapter, options) {
109632
109633             // todo: some of these attributes should be modifiable...
109634
109635             //: for local stores, specifies the agent that will implement
109636             //: the actual item operations -- it must implement the
109637             //: syncml-js.Agent API.
109638             this.agent = options.agent || null;
109639
109640             //: [read-only] specifies the SyncML URI that this store is bound to.
109641             this.uri = ( adapter ? adapter.normUri(options.uri) : options.uri ) || null;
109642
109643             //: [read-only] specifies the human-readable name for this store.
109644             //: if undefined, defaults to URI.
109645             this.displayName = options.displayName || this.uri || null;
109646
109647             //: [read-only] specifies the maximum GUID size for items in this store.
109648             //: if undefined, defaults to adapter setting.
109649             this.maxGuidSize = options.maxGuidSize || null;
109650
109651             //: [read-only] specifies the maximum object size for items in this store.
109652             //: if undefined, defaults to adapter setting.
109653             this.maxObjSize = options.maxObjSize || null;
109654
109655             //: [read-only] specifies conflict resolution policy for this store.
109656             //: if undefined, defaults to adapter setting.
109657             this.conflictPolicy = options.conflictPolicy || null;
109658
109659             //: [read-only] specifies which syncTypes this store supports.
109660             //: (defaults to all.)
109661             this.syncTypes = options.syncTypes;
109662             if ( this.syncTypes == undefined || this.syncTypes.length <= 0 )
109663             {
109664                 this.syncTypes = [
109665                     constant.SYNCTYPE_TWO_WAY,
109666                     constant.SYNCTYPE_SLOW_SYNC,
109667                     constant.SYNCTYPE_ONE_WAY_FROM_CLIENT,
109668                     constant.SYNCTYPE_REFRESH_FROM_CLIENT,
109669                     constant.SYNCTYPE_ONE_WAY_FROM_SERVER,
109670                     constant.SYNCTYPE_REFRESH_FROM_SERVER,
109671                     constant.SYNCTYPE_SERVER_ALERTED
109672                 ];
109673             }
109674
109675             ctypes = options.contentTypes;
109676             if ( ! ctypes && options.agent )
109677                 ctypes = options.agent.getContentTypes();
109678
109679             this.contentTypes = _.map(ctypes, function(e) {
109680                 if ( e instanceof ctype.ContentTypeInfo ) {
109681                     return e;
109682                 }
109683                 return ctype.ContentTypeInfo.fromStruct(e);
109684             });
109685
109686             // --- private attributes
109687             this.id       = options.id || common.makeID();
109688             this._a       = adapter;
109689         },
109690
109691         //-------------------------------------------------------------------------
109692         _load: function(cb) {
109693             cb();
109694         },
109695
109696         //-------------------------------------------------------------------------
109697         _getModel: function() {
109698             var self = this;
109699             var uri  = self._a.normUri(self.uri);
109700             return _.find(this._a._getModel().stores,
109701                     function(s) { return self._a.normUri(s.uri) == uri; });
109702         },
109703
109704         //-------------------------------------------------------------------------
109705         _updateModel: function(cb) {
109706             if ( ! this._a._model || ! this._a._model.stores )
109707                 return cb('store created on un-initialized adapter');
109708             // TODO: this squashes any data that may already be there, such
109709             //       as *BINDING* info!...
109710             this._a._model.stores = _.filter(this._a._model.stores, function(e) {
109711                 return e.uri != this.uri;
109712             }, this);
109713             this._a._model.stores.push({
109714                 id              : this.id,
109715                 uri             : this.uri,
109716                 displayName     : this.displayName,
109717                 syncTypes       : this.syncTypes,
109718                 maxGuidSize     : this.maxGuidSize,
109719                 maxObjSize      : this.maxObjSize,
109720                 conflictPolicy  : this.conflictPolicy,
109721                 contentTypes    : _.map(this.contentTypes, function(e) { return e.toStruct(); })
109722             });
109723             cb();
109724         },
109725
109726         //-------------------------------------------------------------------------
109727         _getBinding: function() {
109728             return this._getModel().binding;
109729         },
109730
109731         //-------------------------------------------------------------------------
109732         _setBinding: function(binding) {
109733             this._getModel().binding = binding;
109734         },
109735
109736         //-------------------------------------------------------------------------
109737         getContentTypes: function() {
109738             if ( this.agent != undefined ) {
109739                 return this.agent.getContentTypes();
109740             }
109741             return this.contentTypes;
109742         },
109743
109744         //-------------------------------------------------------------------------
109745         getPeerStore: function(peer) {
109746             var peerUri = null;
109747             if ( this._a.isLocal ) {
109748                 peerUri = this._a._c.router.getTargetUri(this._a, peer, this.uri);
109749             }
109750             else {
109751                 var binding = this.getBinding();
109752                 peerUri = binding ? binding.uri : null;
109753             }
109754             if ( ! peerUri ) {
109755                 return null;
109756             }
109757             return peer.getStore(peerUri);
109758         },
109759
109760         //-------------------------------------------------------------------------
109761         merge: function(store, cb) {
109762             if ( this.uri != store.uri )
109763                 return cb(new common.InternalError(
109764                                 'unexpected merging of stores with different URIs ("' + this.uri
109765                                     + '" != "' + store.uri + '")'));
109766             if ( ! _.isEqual(this.contentTypes, store.contentTypes) )
109767             {
109768                 // todo: this is a bit drastic... perhaps have an operational setting
109769                 //       which controls how paranoid to be?...
109770                 this._setBinding(null);
109771             }
109772             this.displayName    = store.displayName;
109773             this.contentTypes   = _.rest(store.contentTypes, 0);
109774             this.syncTypes      = _.rest(store.syncTypes, 0);
109775             this.maxGuidSize    = store.maxGuidSize;
109776             this.maxObjSize     = store.maxObjSize;
109777             this.agent          = store.agent;
109778             this.conflictPolicy = store.conflictPolicy;
109779             return cb();
109780         },
109781
109782         //-------------------------------------------------------------------------
109783         _clearAllMappings: function(cb) {
109784             if ( this._a.isLocal )
109785                 return cb(new common.InternalError(
109786                             'unexpected mapping request for local store'));
109787             var mapping = this._a._c._txn().objectStore('mapping');
109788             storage.deleteAll(mapping, {store_id: this.id}, cb);
109789         },
109790
109791         //-------------------------------------------------------------------------
109792         _setMapping: function(guid, luid, cb) {
109793             var self = this;
109794             if ( this._a.isLocal )
109795                 return cb(new common.InternalError(
109796                             'unexpected mapping request for local store'));
109797             // delete all previous mappings for this guid/store (there should
109798             // be at most one)... but paranoia rules.
109799             var mapping = this._a._c._txn().objectStore('mapping');
109800             storage.deleteAll(mapping, {store_id: this.id, guid: guid}, function(err) {
109801                 if ( err ) {
109802                     return cb(err);
109803                 }
109804                 storage.put(mapping, {store_id: self.id, guid: guid, luid: luid}, function(err) {
109805                     if ( err ) {
109806                         return cb(err);
109807                     }
109808                     cb();
109809                 });
109810             });
109811         },
109812
109813         //-------------------------------------------------------------------------
109814         _getMapping: function(guid, cb) {
109815             if ( this._a.isLocal )
109816                 return cb(new common.InternalError(
109817                             'unexpected mapping request for local store'));
109818             // todo: there must be a way to use IndexedDB since i have everything
109819             //       needed to generate the keyPath!... eg:
109820             //         objectStore.get({store_id:X,guid:Y})?...
109821             var mapdb = this._a._c._txn().objectStore('mapping').index('store_id');
109822             storage.getAll(this._a._c, mapdb, {only: this.id}, function(err, list) {
109823                 if ( err ) {
109824                     return cb(err);
109825                 }
109826                 var item = _.find(list, function(item) {
109827                     return item.guid == guid;
109828                 });
109829                 return cb(null, item ? item.luid : null);
109830             });
109831         },
109832
109833         //-------------------------------------------------------------------------
109834         _getMappings: function(cb) {
109835             if ( this._a.isLocal )
109836                 return cb(new common.InternalError(
109837                             'unexpected mapping request for local store'));
109838             var mapdb = this._a._c._txn().objectStore('mapping').index('store_id');
109839             storage.getAll(this._a._c, mapdb, {only: this.id}, function(err, list) {
109840                 if ( err )
109841                     return cb(err);
109842                 return cb(null, _.map(list, function(item) {
109843                     return [item.guid, item.luid];
109844                 }));
109845             });
109846         },
109847
109848         //-------------------------------------------------------------------------
109849         _getReverseMapping: function(luid, cb) {
109850             if ( this._a.isLocal )
109851                 return cb(new common.InternalError(
109852                             'unexpected mapping request for local store'));
109853             // todo: there must be a way to use IndexedDB since i have everything
109854             //       needed to generate the keyPath!... eg:
109855             //         objectStore.get({store_id:X,guid:Y})?...
109856             var mapdb = this._a._c._txn().objectStore('mapping').index('store_id');
109857             storage.getAll(this._a._c, mapdb, {only: this.id}, function(err, list) {
109858                 if ( err )
109859                     return cb(err);
109860                 var item = _.find(list, function(item) {
109861                     return item.luid == luid;
109862                 });
109863                 return cb(null, item ? item.guid : null);
109864             });
109865         },
109866
109867         //-------------------------------------------------------------------------
109868         registerChange: function(itemID, state, options, cb) {
109869             // options can include:
109870             //   - changeSpec (string)
109871             //   - excludePeerID (string)
109872
109873             if ( ! _.contains([constant.ITEM_ADDED, constant.ITEM_MODIFIED,
109874                         constant.ITEM_DELETED], state) )
109875                 return cb(new common.TypeError(
109876                             'registerChange: invalid state "' + state + '"'));
109877
109878             options = options || {};
109879             var self = this;
109880             if ( self._a.isLocal )
109881             {
109882                 // TODO: THIS NEEDS TO BE SIGNIFICANTLY OPTIMIZED!... either:
109883                 //         a) optimize this reverse lookup, or
109884                 //         b) use a query that targets exactly the set of stores needed
109885                 //       note that a pre-emptive model.session.flush() may be necessary.
109886                 common.cascade(self._a.getPeers(), function(peer, cb) {
109887                     if ( options.excludePeerID && options.excludePeerID == peer.id )
109888                         return cb();
109889                     common.cascade(peer.getStores(), function(store, cb) {
109890                         var binding = store._getBinding()
109891                         if ( ! binding || binding.uri != self.uri )
109892                             return cb();
109893                         store.registerChange(itemID, state, options, cb);
109894                     }, cb);
109895                 }, cb);
109896                 return;
109897             }
109898
109899             // todo: a non-ADD change event for an ID that has never been
109900             // seen does not create an error... should it??? that would mean
109901             // that syncml-js needs to track that. not a good idea.
109902
109903             itemID = '' + itemID;
109904             var handled = false;
109905
109906             // paranoia
109907             if ( options.changeSpec && state != constant.ITEM_MODIFIED )
109908             {
109909                 options.changeSpec = null;
109910             }
109911
109912             var check_update = function(cb) {
109913                 self._getChange(itemID, function(err, change) {
109914                     if ( err )
109915                         return cb(err);
109916                     if ( ! change)
109917                         return cb();
109918                     var badstate = function(action) {
109919                     };
109920                 // note: many of the following change.state / state combinations
109921                 // should never occur. the following tries to recover gracefully.
109922                 // todo: should i raise an error for "illogical" conditions?
109923                     switch ( change.state )
109924                     {
109925                     case constant.ITEM_ADDED:
109926                     {
109927                         if ( state != constant.ITEM_DELETED )
109928                         {
109929                             // ADD + anything except DELETE stays ADD
109930                             handled = true;
109931                             return cb();
109932                         }
109933                         // ADD + DELETE cancels out
109934                         handled = true;
109935                         var changeTab = self._a._c._txn().objectStore('change');
109936                         storage.deleteAll(changeTab, change, function(err) {
109937                             if ( err )
109938                                 return cb(err);
109939                             return cb();
109940                         });
109941                         return;
109942                     }
109943                     case constant.ITEM_MODIFIED:
109944                     {
109945                         if ( state == constant.ITEM_ADDED )
109946                         {
109947                             badstate('squelching changeSpec');
109948                             delete change.changeSpec;
109949                             break;
109950                         }
109951                         if ( state == constant.ITEM_DELETED )
109952                         {
109953                             change.state = state;
109954                             delete change.changeSpec;
109955                             break;
109956                         }
109957                         if ( change.changeSpec )
109958                         {
109959                             if ( options.changeSpec )
109960                                 change.changeSpec += ';' + options.changeSpec;
109961                             else
109962                                 delete change.changeSpec;
109963                         }
109964                         break;
109965                     }
109966                     case constant.ITEM_DELETED:
109967                     {
109968                         if ( state == constant.ITEM_DELETED )
109969                         {
109970                             badstate('ignoring');
109971                             handled = true;
109972                             return cb();
109973                         }
109974                         badstate('reverting to modified');
109975                         change.state = constant.ITEM_MODIFIED;
109976                         delete change.changeSpec;
109977                         break;
109978                     }
109979                     default:
109980                     {
109981                         return cb(new common.InternalError(
109982                                     'unexpected recorded change state "' + change.state
109983                                     + '" for item ID "' + itemID + '"'));
109984                     }
109985                     }
109986                     // update the change
109987                     // todo: do i need to delete it first?
109988                     handled = true;
109989                     return storage.put(
109990                         self._a._c._txn().objectStore('change'),
109991                         change,
109992                         cb);
109993                 });
109994             };
109995
109996             var check_mapping = ( self._a._isMapper() || state == constant.ITEM_ADDED )
109997                 ? common.noop
109998                 : function(cb) {
109999                     // doing a `_getMapping` for non-add events to make sure that
110000                     // the remote peer actually has this object before we tell it
110001                     // to modify or delete an item...
110002                     self._getMapping(itemID, function(err, luid) {
110003                         if ( err )
110004                         return cb(err);
110005                     if ( luid )
110006                         return cb();
110007                     // this item does not exist as (or has not been mapped to) an
110008                     // item on the remote peer and is not an `ADD` event, so can
110009                     // therefore be ignored - mark it as "handled".
110010                     handled = true;
110011                     return cb();
110012                     });
110013                 };
110014
110015             // todo: there is a weirdness here wrt `handled` in the case
110016             //       of check_mapping and deletes... ie. there is a bit of
110017             //       a responsibility violation (handled does not actually
110018             //       mean handled...)
110019
110020             check_update(function(err) {
110021                 if ( err )
110022                     return cb(err);
110023                 if ( handled )
110024                     return cb();
110025                 check_mapping(function(err) {
110026                     if ( err )
110027                         return cb(err);
110028                     if ( handled && state != constant.ITEM_DELETED )
110029                         return cb();
110030                     // note: if it is a delete event, and it has not been mapped
110031                     // yet, so does not yet exist on the peer, therefore
110032                     // propagate nothing -- continuing just to execute the
110033                     // deleteAll().
110034                     var changeTab = self._a._c._txn().objectStore('change');
110035                     change = {store_id: self.id, item_id: itemID};
110036                     // todo: is this deleteAll really necessary?... paranoia rules!
110037                     storage.deleteAll(changeTab, change, function(err) {
110038                         if ( err )
110039                             return cb(err);
110040                         if ( handled )
110041                             return cb();
110042                         change.state = state;
110043                         change.changeSpec = options.changeSpec;
110044                         storage.put(changeTab, change, cb);
110045                     });
110046                 });
110047             });
110048         },
110049
110050         //-------------------------------------------------------------------------
110051         _getChange: function(itemID, cb) {
110052             // returns cb(null, CHANGE)
110053             // change ::= { store_id: ID, item_id: GUID, state: STATE, changeSpec: SPEC }
110054             itemID = '' + itemID;
110055             var self = this;
110056             // todo: there must be a way to use IndexedDB since i have everything
110057             //       needed to generate the keyPath!... eg:
110058             //         objectStore.get({store_id:X,guid:Y})?...
110059             var changedb = self._a._c._txn().objectStore('change').index('store_id');
110060             storage.getAll(self._a._c, changedb, {only: self.id}, function(err, changes) {
110061                 if ( err )
110062                     return cb(err);
110063                 var change = _.find(changes, function(change) {
110064                     return change.item_id == itemID;
110065                 });
110066                 return cb(null, change);
110067             });
110068         },
110069
110070         //-------------------------------------------------------------------------
110071         _delChange: function(options, cb) {
110072             // - if options is null/empty, delete all changes recorded
110073             //   for this store
110074
110075             // // todo: this is *technically* subject to a race condition... but the
110076             // //       same peer should really not be synchronizing at the same time...
110077             // // todo: also potentially check Change.registered...
110078             // // TODO: this could be solved by:
110079             // //         a) never updating a Change record (only deleting and replacing)
110080             // //         b) deleting Change records by ID instead of by store/item/state...
110081
110082             // var objstore = session.context._txn().objectStore('change');
110083             // storage.iterateCursor(
110084             //   objstore.index('store_id').openCursor(peerStore.id),
110085             //   function(value, key, cb) {
110086             //     if ( value.itemID != chkcmd.source || value.state != constant.ITEM_ADDED )
110087             //       return;
110088             //     storage.delete(objstore, key, cb);
110089             //   }, cb);
110090
110091             var dbstore = this._a._c._txn().objectStore('change');
110092             var matches = {store_id: this.id};
110093             if ( options.itemID )
110094                 matches.item_id = options.itemID;
110095             if ( options.state )
110096                 matches.state = options.state;
110097             storage.deleteAll(dbstore, matches, cb);
110098         },
110099
110100         //-------------------------------------------------------------------------
110101         toSyncML: function() {
110102             var xstore = ET.Element('DataStore');
110103             if ( this.uri )
110104                 ET.SubElement(xstore, 'SourceRef').text = this.uri;
110105             if ( this.displayName )
110106                 ET.SubElement(xstore, 'DisplayName').text = this.displayName;
110107             if ( this.maxGuidSize )
110108             {
110109                 // todo: this should ONLY be sent by the client... (according to the
110110                 //       spec, but not according to funambol behavior...)
110111                 ET.SubElement(xstore, 'MaxGUIDSize').text = this.maxGuidSize;
110112             }
110113             if ( this.maxObjSize )
110114                 ET.SubElement(xstore, 'MaxObjSize').text = this.maxObjSize;
110115
110116             var ctypes = this.getContentTypes();
110117
110118             if ( ctypes && ctypes.length > 0 )
110119             {
110120                 var pref = _.filter(ctypes, function(ct) { return ct.receive && ct.preferred; });
110121
110122                 // todo: should i just take the first one?...
110123                 if ( pref.length > 1 )
110124                     throw new Error('agents can prefer at most one receive content-type');
110125
110126                 if ( pref.length == 1 )
110127                 {
110128                     pref = pref[0].toSyncML('Rx', true);
110129                     pref[0].tag = 'Rx-Pref';
110130                     _.each(pref, function(xnode) { xstore.append(xnode); });
110131                 }
110132
110133                 _.each(
110134                         _.filter(ctypes, function(ct) { return ct.receive && ! ct.preferred; }),
110135                         function(ct) {
110136                             _.each(ct.toSyncML('Rx', true), function(xnode) {
110137                                 xstore.append(xnode);
110138                             });
110139                         });
110140
110141                 var pref = _.filter(ctypes, function(ct) { return ct.transmit && ct.preferred; });
110142
110143                 // todo: should i just take the first one?...
110144                 if ( pref.length > 1 )
110145                     throw new Error('agents can prefer at most one transmit content-type');
110146
110147                 if ( pref.length == 1 )
110148                 {
110149                     pref = pref[0].toSyncML('Tx', true);
110150                     pref[0].tag = 'Tx-Pref';
110151                     _.each(pref, function(xnode) { xstore.append(xnode); });
110152                 }
110153
110154                 _.each(
110155                         _.filter(ctypes, function(ct) { return ct.transmit && ! ct.preferred; }),
110156                         function(ct) {
110157                             _.each(ct.toSyncML('Tx', true), function(xnode) {
110158                                 xstore.append(xnode);
110159                             });
110160                         });
110161
110162             }
110163
110164             if ( this.syncTypes && this.syncTypes.length > 0 )
110165             {
110166                 var xcap = ET.SubElement(xstore, 'SyncCap');
110167                 for ( var idx=0 ; idx<this.syncTypes.length ; idx++ )
110168                     ET.SubElement(xcap, 'SyncType').text = this.syncTypes[idx];
110169             }
110170             return xstore;
110171
110172         },
110173
110174         //-------------------------------------------------------------------------
110175         describe: function(stream, cb) {
110176             stream.writeln('URI: ' + this.uri);
110177             stream.writeln('Max ID size: ' + ( this.maxGuidSize || '(none)' ));
110178             stream.writeln('Max object size: ' + ( this.maxObjSize || '(none)' ));
110179             stream.writeln('Sync types: ' + this.syncTypes.join(', '));
110180             var cts = this.getContentTypes();
110181             if ( cts.length <= 0 )
110182             {
110183                 stream.writeln('Capabilities: (none)');
110184                 return cb();
110185             }
110186             stream.writeln('Capabilities:');
110187             var s1 = new common.IndentStream(stream);
110188             common.cascade(cts, function(ct, cb) {
110189                 s1.write('- ');
110190                 ct.describe(s1);
110191                 return cb();
110192             }, cb);
110193         }
110194     }, {
110195
110196         //-------------------------------------------------------------------------
110197         fromSyncML: function(xnode) {
110198             var options = {
110199                 uri          : xnode.findtext('SourceRef'),
110200                 displayName  : xnode.findtext('DisplayName'),
110201                 maxGuidSize  : common.int(xnode.findtext('MaxGUIDSize')),
110202                 maxObjSize   : common.int(xnode.findtext('MaxObjSize')),
110203                 contentTypes : [],
110204                 syncTypes    : _.map(xnode.findall('SyncCap/SyncType'), function(e) {
110205                     return common.int(e.text);
110206                 })
110207             };
110208             _.each(xnode.getchildren(), function(child) {
110209                 if ( _.indexOf(['Rx-Pref', 'Rx', 'Tx-Pref', 'Tx'], child.tag) < 0 )
110210                 return;
110211             var cti = ctype.ContentTypeInfo.fromSyncML(child);
110212             var merged = false;
110213             _.each(options.contentTypes, function(ct) {
110214                 if ( merged )
110215                 return;
110216             if ( ct.merge(cti) )
110217                 merged = true;
110218             });
110219             if ( ! merged )
110220                 options.contentTypes.push(cti);
110221             });
110222             return new exports.Store(null, options);
110223         },
110224     });
110225
110226     return exports;
110227
110228 })();
110229
110230 module.exports = _self;
110231
110232 });
110233 define('ripple/platform/tizen/2.0/syncml-js-lib/synchronizer', function (require, exports, module) {
110234 // -*- coding: utf-8 -*-
110235 //-----------------------------------------------------------------------------
110236 // file: $Id$
110237 // lib:  syncml-js.synchronizer
110238 // auth: griffin <griffin@uberdev.org>
110239 // date: 2012/11/05
110240 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
110241 //-----------------------------------------------------------------------------
110242
110243 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
110244     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
110245     ctype = require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'),
110246     state = require('ripple/platform/tizen/2.0/syncml-js-lib/state'),
110247     protocol = require('ripple/platform/tizen/2.0/syncml-js-lib/protocol'),
110248     storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'),
110249     _self;
110250
110251 _self = (function () {
110252
110253     var exports = {};
110254     var badStatus = protocol.badStatus;
110255
110256     //---------------------------------------------------------------------------
110257     exports.Synchronizer = common.Base.extend({
110258
110259         //-------------------------------------------------------------------------
110260         constructor: function(options) {
110261         },
110262
110263         //-------------------------------------------------------------------------
110264         initStoreSync: function(session, cb) {
110265             async.eachSeries(session.peer._getModel().stores, function(rstore, cb) {
110266                 // TODO: should the server-side be doing this? probably not
110267                 //       since store mapping is a client-side decision...
110268                 var ruri = session.peer.normUri(rstore.uri);
110269                 if ( session.info.dsstates[ruri] || ! rstore.binding )
110270                 return cb();
110271             var lstore = session.adapter.getStore(rstore.binding.uri);
110272             if ( ! lstore || ! lstore.agent )
110273                 return cb();
110274             var ds = state.makeStoreSyncState({
110275                 uri        : lstore.uri,
110276                 peerUri    : ruri,
110277                 lastAnchor : rstore.binding.localAnchor,
110278                 mode       : session.info.mode || constant.ALERT_TWO_WAY,
110279                 action     : 'alert'
110280             });
110281             if ( ! ds.lastAnchor )
110282             {
110283                 switch ( ds.mode )
110284             {
110285                 case constant.ALERT_SLOW_SYNC:
110286                 case constant.ALERT_REFRESH_FROM_CLIENT:
110287                 case constant.ALERT_REFRESH_FROM_SERVER:
110288                     {
110289                         break;
110290                     }
110291                 case constant.ALERT_TWO_WAY:
110292                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
110293                 case constant.ALERT_ONE_WAY_FROM_SERVER:
110294                     {
110295                         if ( session.info.mode == constant.SYNCTYPE_AUTO )
110296                         {
110297                             ds.mode = constant.ALERT_SLOW_SYNC;
110298                             break;
110299                         }
110300                         var uaEvent = {
110301                             session   : session,
110302                             store     : lstore,
110303                             peerStore : rstore,
110304                             modeReq   : ds.mode
110305                         };
110306                         return session.ua.chooseRefreshRequired(uaEvent, function(err, mode) {
110307                             if ( err )
110308                             return cb(err);
110309                         if ( ! _.contains([constant.ALERT_SLOW_SYNC,
110310                                 constant.ALERT_REFRESH_FROM_CLIENT,
110311                                 constant.ALERT_REFRESH_FROM_SERVER], mode) )
110312                             return cb(new common.TypeError(
110313                                     'invalid mode chosen for refresh: ' + common.j(mode)));
110314                         ds.mode = mode;
110315                         session.info.dsstates[ds.uri] = ds;
110316                         return cb();
110317                         });
110318                     }
110319                 default:
110320                     {
110321                         return cb(new common.InternalError(
110322                                     'unexpected sync mode "' + ds.mode + '" requested'));
110323                     }
110324             }
110325             }
110326             session.info.dsstates[ds.uri] = ds;
110327             return cb();
110328             }, cb);
110329         },
110330
110331         //-------------------------------------------------------------------------
110332         // SYNCHRONIZATION PHASE: ACTION
110333         //-------------------------------------------------------------------------
110334
110335         //-------------------------------------------------------------------------
110336         actions: function(session, commands, cb) {
110337             var self = this;
110338             common.cascade(_.keys(session.info.dsstates), function(uri, cb) {
110339                 var ds = session.info.dsstates[uri];
110340                 if ( ds.action == 'done' )
110341                 return cb();
110342             // TODO: is this the right handling of an "error" dsstate?...
110343             if ( ds.action == 'error' )
110344                 return cb();
110345             var func = self['_action_' + ds.action.toLowerCase()];
110346             if ( ! func )
110347                 return cb(new common.InternalError(
110348                         'unexpected store action "' + ds.action + '"'));
110349             try{
110350                 func.call(self, session, ds, function(err, cmds) {
110351                     if ( err )
110352                     return cb(err);
110353                 _.each(cmds, function(cmd) { commands.push(cmd); });
110354                 return cb();
110355                 });
110356             }catch(e){
110357                 return cb(new common.InternalError(
110358                         'failed invoking synchronizer action: ' + e, e));
110359             }
110360             }, function(err) {
110361                 if ( err )
110362                     return cb(err);
110363                 return cb(null, commands);
110364             });
110365         },
110366
110367         //-------------------------------------------------------------------------
110368         _action_alert: function(session, dsstate, cb) {
110369
110370             var src = session.adapter.getStore(dsstate.uri);
110371             var tgt = session.peer.getStore(dsstate.peerUri);
110372
110373             // TODO: ensure that mode is acceptable...
110374
110375             // todo: perhaps i should only specify maxObjSize if it differs from
110376             //       adapter.maxObjSize?...
110377
110378             return cb(null, [state.makeCommand({
110379                 name        : constant.CMD_ALERT,
110380                    cmdID       : session.nextCmdID(),
110381                    data        : dsstate.mode,
110382                    source      : src.uri,
110383                    target      : tgt.uri,
110384                    lastAnchor  : dsstate.lastAnchor,
110385                    nextAnchor  : dsstate.nextAnchor,
110386                    maxObjSize  : src.maxObjSize,
110387             })]);
110388
110389         },
110390
110391         //-------------------------------------------------------------------------
110392         _action_send: function(session, dsstate, cb) {
110393             var store = session.adapter.getStore(dsstate.uri);
110394             var agent = store.agent;
110395             var peerStore = session.peer.getStore(dsstate.peerUri);
110396
110397             var cmd = state.makeCommand({
110398                 name   : constant.CMD_SYNC,
110399                 cmdID  : session.nextCmdID(),
110400                 source : dsstate.uri,
110401                 // target : adapter.router.getTargetUri(uri),
110402                 target : dsstate.peerUri
110403             });
110404
110405             switch ( dsstate.mode )
110406             {
110407                 case constant.ALERT_TWO_WAY:
110408                 case constant.ALERT_SLOW_SYNC:
110409                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
110410                 case constant.ALERT_REFRESH_FROM_CLIENT:
110411                 case constant.ALERT_ONE_WAY_FROM_SERVER:
110412                 case constant.ALERT_REFRESH_FROM_SERVER:
110413                     // todo: these should only be received out-of-band, right?...
110414                     // case constant.ALERT_TWO_WAY_BY_SERVER:
110415                     // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER:
110416                     // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER:
110417                     // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER:
110418                     // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER:
110419                     {
110420                         break;
110421                     }
110422                 default:
110423                     {
110424                         return cb(new common.InternalError(
110425                                     'unexpected sync mode "' + common.mode2string(dsstate.mode) + '"'));
110426                     }
110427             }
110428
110429             if ( session.isServer )
110430             {
110431                 if ( dsstate.mode == constant.ALERT_REFRESH_FROM_CLIENT
110432                         || dsstate.mode == constant.ALERT_ONE_WAY_FROM_CLIENT )
110433                 {
110434                     cmd.noc = 0;
110435                     return cb(null, [cmd]);
110436                 }
110437             }
110438
110439             if ( ! session.isServer )
110440             {
110441                 if ( dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER
110442                         || dsstate.mode == constant.ALERT_ONE_WAY_FROM_SERVER )
110443                 {
110444                     cmd.noc = 0;
110445                     return cb(null, [cmd]);
110446                 }
110447             }
110448
110449             switch ( dsstate.mode )
110450             {
110451
110452                 case constant.ALERT_TWO_WAY:
110453                 case constant.ALERT_ONE_WAY_FROM_CLIENT: // when ! session.isServer
110454                 case constant.ALERT_ONE_WAY_FROM_SERVER: // when session.isServer
110455                     {
110456                         // send local changes
110457
110458                         storage.getAll(
110459                                 session.context,
110460                                 session.txn().objectStore('change').index('store_id'),
110461                                 {only: peerStore.id},
110462                                 function(err, changes) {
110463                                     if ( err )
110464                             return cb(err);
110465                         var ctype = session.context.router.getBestTransmitContentType(
110466                             session.adapter, session.peer, dsstate.uri);
110467                         cmd.data = [];
110468
110469                         // TODO: add support for hierarchical operations...
110470                         //       including MOVE, COPY, etc.
110471
110472                         // TODO: this assumes that the entire object set can fit in memory...
110473                         //       perhaps, as a work-around, just keep a reference to the object
110474                         //       and then stream-based serialize it actually gets converted to
110475                         //       XML.
110476
110477                         common.cascade(changes, function(change, cb) {
110478
110479                             if ( dsstate.conflicts && _.indexOf(dsstate.conflicts, change.item_id) >= 0 )
110480                             return cb();
110481
110482                         var scmdtype = null;
110483                         switch ( change.state )
110484                         {
110485                             case constant.ITEM_ADDED:    scmdtype = constant.CMD_ADD;     break;
110486                             case constant.ITEM_MODIFIED: scmdtype = constant.CMD_REPLACE; break;
110487                             case constant.ITEM_DELETED:  scmdtype = constant.CMD_DELETE;  break;
110488                             default:
110489                                                          {
110490                                                              return cb();
110491                                                          }
110492                         }
110493
110494                         // todo: do something with the ctype version (ie. ctype[1])?...
110495                         var scmd = state.makeCommand({
110496                             name    : scmdtype,
110497                             cmdID   : session.nextCmdID(),
110498                             format  : constant.FORMAT_AUTO,
110499                             type    : change.state != constant.ITEM_DELETED ? ctype[0] : null,
110500                             uri     : dsstate.uri
110501                         });
110502
110503                         // TODO: need to add hierarchical addition support here...
110504
110505                         var set_data = scmdtype == constant.CMD_DELETE ? common.noop : function(cb) {
110506
110507                             agent.getItem(change.item_id, function(err, item) {
110508                                 if ( err )
110509                                 return cb(err);
110510                             agent.dumpsItem(item, ctype[0], ctype[1], function(err, data, nct, nv) {
110511                                 if ( err )
110512                                 return cb(err);
110513                             scmd.data = data;
110514                             scmd.type = nct || scmd.type;
110515                             // todo: what to do with the content-type version?... eg.
110516                             //         scmd.version = nv || scmd.version;
110517                             // TODO: support hierarchical sync
110518                             // if ( agent.hierarchicalSync && item.parent )
110519                             //   scmd.sourceParent = '' + item.parent
110520                             return cb();
110521                             });
110522                             });
110523                         };
110524
110525                         var set_target = scmdtype == constant.CMD_ADD ? function(cb) {
110526                             scmd.source = change.item_id;
110527                             cb();
110528                         } : function(cb) {
110529                             if ( ! session.isServer )
110530                             {
110531                                 scmd.source = change.item_id;
110532                                 return cb();
110533                             }
110534                             peerStore._getMapping(change.item_id, function(err, luid) {
110535                                 if ( err )
110536                                 return cb(err);
110537                             if ( luid )
110538                                 scmd.target = luid;
110539                             else
110540                                 scmd.source = change.item_id;
110541                             cb();
110542                             });
110543                         };
110544
110545                         set_data(function(err) {
110546                             if ( err )
110547                             return cb(err);
110548                         set_target(function(err) {
110549                             if ( err )
110550                             return cb(err);
110551                         cmd.data.push(scmd);
110552                         return cb();
110553                         });
110554                         });
110555                         }, function(err) {
110556                             if ( err )
110557                                 return cb(err);
110558                             cmd.noc = cmd.data.length;
110559                             return cb(null, [cmd]);
110560                         });
110561                                 }
110562                         );
110563                         return;
110564                     }
110565                 case constant.ALERT_SLOW_SYNC:
110566                 case constant.ALERT_REFRESH_FROM_SERVER: // when session.isServer
110567                 case constant.ALERT_REFRESH_FROM_CLIENT: // when ! session.isServer
110568                     {
110569                         // todo: this approach assumes that the entire object set can fit
110570                         //       in memory... perhaps move to an iterator-based approach?...
110571                         cmd.data = [];
110572
110573                         agent.getAllItems(function(err, items) {
110574
110575                             if ( err )
110576                             return cb(err);
110577
110578                         // TODO: support hierarchical sync...
110579
110580                         if ( agent.hierarchicalSync )
110581                         {
110582                             return cb(new common.NotImplementedError('hierarchical-sync'));
110583                             //       orditems = []            # the ordered items
110584                             //       dunitems = dict()        # lut of the ordered items
110585                             //       curitems = dict()        # lut of current items (for loop detection)
110586                             //       lutitems = dict([(item.id, item) for item in items])
110587                             //       def appenditem(item):
110588                             //         if item.id in dunitems:
110589                             //           return
110590                             //         if item.id in curitems:
110591                             //           raise common.LogicalError('recursive item hierarchy detected at item %r' % (item,))
110592                             //         curitems[item.id] = True
110593                             //         if item.parent is not None:
110594                             //           appenditem(lutitems[item.parent])
110595                             //         orditems.append(item)
110596                             //         dunitems[item.id] = item
110597                             //       for item in items:
110598                             //         curitems = dict()
110599                             //         appenditem(item)
110600                         }
110601
110602                         var ctype = session.context.router.getBestTransmitContentType(
110603                                 session.adapter, session.peer, dsstate.uri);
110604
110605                         common.cascade(items, function(item, cb) {
110606
110607                             // TODO: these should all be non-deleted items, right?...
110608
110609                             if ( _.indexOf(dsstate.conflicts, '' + item.id) >= 0 )
110610                             return cb();
110611
110612                         // note: need to check for mappings since on slow-sync, the
110613                         // server will already have received the client's "add" commands
110614                         // at this point (and therefore should not send them back...)
110615                         var check_sync = function(cb) {
110616                             if ( ! session.isServer )
110617                             return cb(null, true);
110618                         peerStore._getMapping(item.id, function(err, luid) {
110619                             return cb(err, luid ? false : true);
110620                         });
110621                         };
110622
110623                         check_sync(function(err, dosync) {
110624                             if ( err )
110625                             return cb(err);
110626
110627                         if ( ! dosync )
110628                             return cb();
110629
110630                         agent.dumpsItem(
110631                             item, ctype[0], ctype[1],
110632                             function(err, data, new_ct, new_v) {
110633
110634                                 if ( err )
110635                             return cb(err);
110636
110637                         // todo: do something with the content-type version...
110638                         var scmd = state.makeCommand({
110639                             name    : constant.CMD_ADD,
110640                             cmdID   : session.nextCmdID(),
110641                             format  : constant.FORMAT_AUTO,
110642                             type    : new_ct || ctype[0],
110643                             uri     : dsstate.uri,
110644                             source  : '' + item.id,
110645                             data    : data
110646                         });
110647
110648                         if ( agent.hierarchicalSync )
110649                         {
110650                             // TODO: support hierarchical sync...
110651                             // if agent.hierarchicalSync and item.parent is not None:
110652                             //   scmd.sourceParent = str(item.parent)
110653                             return cb(new common.NotImplementedError('hierarchical-sync'));
110654                         }
110655
110656                         cmd.data.push(scmd);
110657                         return cb();
110658                             });
110659
110660                         });
110661
110662                         }, function(err) {
110663                             if ( err )
110664                                 return cb(err);
110665                             cmd.noc = cmd.data.length;
110666                             return cb(null, [cmd]);
110667                         });
110668
110669                         });
110670                         return;
110671                     }
110672             }
110673
110674             return cb(new common.InternalError(
110675                         'unexpected sync situation (action=' + dsstate.action
110676                             + ', mode=' + common.mode2string(dsstate.mode)
110677                             + ', isServer=' + ( session.isServer ? '1' : '0' ) + ')'));
110678                     },
110679
110680                     //-------------------------------------------------------------------------
110681                     _action_save: function(session, dsstate, cb) {
110682                         if ( ! session.isServer )
110683                 // TODO: for now, only servers should take the "save" action - the client
110684                 //       will explicitly do this at the end of the .sync() method.
110685                 //       ... mostly because clients don't call synchronizer.actions()
110686                 //       one final time ...
110687                 //       *BUT* perhaps that should be changed?... for example, .sync()
110688                 //       could call synchronizer.actions() to cause action_save's to occur
110689                 //       *AND* verify that synchronizer.actions() does not return anything...
110690                 return cb(new common.InternalError(
110691                         'unexpected sync save situation (action=' + dsstate.action
110692                             + ', mode=' + common.mode2string(dsstate.mode)
110693                             + ', isServer=' + ( session.isServer ? '1' : '0' ) + ')'));
110694
110695                     var peerStore = session.peer.getStore(dsstate.peerUri);
110696                     var binding = peerStore._getBinding();
110697                     binding.localAnchor  = dsstate.nextAnchor;
110698                     binding.remoteAnchor = dsstate.peerNextAnchor;
110699                     return cb(null);
110700                     },
110701
110702                     //-------------------------------------------------------------------------
110703                     // SYNCHRONIZATION PHASE: REACTION
110704                     //-------------------------------------------------------------------------
110705
110706                     //-------------------------------------------------------------------------
110707                     reactions: function(session, commands, cb) {
110708                         var self = this;
110709                         var ret  = [];
110710                         session.hierlut = null;
110711                         common.cascade(commands, function(cmd, cb) {
110712                             var func = self['_reaction_' + cmd.name.toLowerCase()];
110713                             if ( ! func )
110714                             return cb(new common.InternalError(
110715                                     'unexpected store reaction "' + cmd.name + '"'));
110716                         try{
110717                             func.call(self, session, cmd, function(err, cmds) {
110718                                 if ( err ) {
110719                                     return cb(err);
110720                                 }
110721                                 _.each(cmds, function(cmd) { ret.push(cmd); });
110722                                 return cb();
110723                             });
110724                         }catch(e){
110725                             return cb(new common.InternalError(
110726                                     'failed invoking synchronizer reaction: ' + e, e));
110727                         }
110728                         }, function(err) {
110729                             session.hierlut = null;
110730                             if ( err )
110731                                 return cb(err);
110732                             return cb(null, ret);
110733                         });
110734                     },
110735
110736                     //-------------------------------------------------------------------------
110737                     _reaction_sync: function(session, command, cb) {
110738                         var self = this;
110739                         var ret  = [state.makeCommand({
110740                             name       : constant.CMD_STATUS,
110741                             cmdID      : session.nextCmdID(),
110742                             msgRef     : command.msgID,
110743                             cmdRef     : command.cmdID,
110744                             targetRef  : command.target,
110745                             sourceRef  : command.source,
110746                             statusOf   : command.name,
110747                             statusCode : constant.STATUS_OK
110748                         })];
110749                         var store = session.adapter.getStore(session.adapter.normUri(command.target));
110750                         var dsstate = session.info.dsstates[store.uri];
110751                         if ( ! store.agent )
110752                         {
110753                             // todo: this is a bit different handling than anywhere else...
110754                             //       should everywhere else be like here, or the other way
110755                             //       round?...
110756                             //       the "REAL BIG ISSUE" is that atomicity of the changes
110757                             //       is a little vague at this point...
110758                             dsstate.stats.hereErr += 1;
110759                             dsstate.action = 'error';
110760                             dsstate.error  = {
110761                                 message:  'Sync agent for store "' + store.uri + '" not available',
110762                                 code:     'syncml-js.TypeError'
110763                             };
110764                             ret[0].statusCode = constant.STATUS_SERVICE_UNAVAILABLE;
110765                             ret[0].errorMsg   = dsstate.error.message;
110766                             ret[0].errorCode  = dsstate.error.code;
110767                             return cb(null, ret);
110768                         }
110769
110770                         if ( store.agent.hierarchicalSync )
110771                             session.hierlut = {};
110772
110773                         var preprocess = common.noop;
110774
110775                         if ( ( ! session.isServer && dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER )
110776                                 || ( session.isServer && dsstate.mode == constant.ALERT_REFRESH_FROM_CLIENT ) )
110777                         {
110778                             // delete all local items
110779                             preprocess = function(cb) {
110780                                 store.agent.getAllItems(function(err, items) {
110781                                     if ( err )
110782                                     return cb(err);
110783                                 common.cascade(items, function(item, cb) {
110784                                     store.agent.deleteItem(item.id, function(err) {
110785                                         if ( err )
110786                                         return cb(err);
110787                                     dsstate.stats.hereDel += 1;
110788                                     if ( ! session.isServer )
110789                                         return cb();
110790                                     store.registerChange(item.id, constant.ITEM_DELETED,
110791                                         {excludePeerID: session.peer.id}, cb);
110792                                     });
110793                                 }, function(err) {
110794                                     if ( err )
110795                                     return cb(err);
110796                                 return store.getPeerStore(session.peer)._delChange({}, cb);
110797                                 });
110798                                 });
110799                             };
110800                         }
110801
110802                         if ( dsstate.mode == constant.ALERT_SLOW_SYNC
110803                                 || ( session.isServer && dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER ) )
110804                         {
110805                             // delete all mappings and pending changes
110806                             var peerStore = store.getPeerStore(session.peer);
110807                             var prepreprocess = preprocess;
110808                             preprocess = function(cb) {
110809                                 prepreprocess(function(err) {
110810                                     if ( err )
110811                                     return cb(err);
110812                                 peerStore._delChange({}, function(err) {
110813                                     if ( err )
110814                                     return cb(err);
110815                                 peerStore._clearAllMappings(cb);
110816                                 });
110817                                 });
110818                             };
110819                         }
110820
110821                         preprocess(function(err) {
110822                             if ( err )
110823                             return cb(err);
110824
110825                         if ( command.data.length <= 0 )
110826                             return cb(null, ret);
110827
110828                         // paranoia: verify that i should be receiving data...
110829                         if ( ! ( dsstate.mode == constant.ALERT_TWO_WAY
110830                                 || dsstate.mode == constant.ALERT_SLOW_SYNC
110831                                 || ( ! session.isServer
110832                                     && ( dsstate.mode == constant.ALERT_ONE_WAY_FROM_SERVER
110833                                         || dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER ) )
110834                                 || ( session.isServer
110835                                     && ( dsstate.mode == constant.ALERT_ONE_WAY_FROM_CLIENT
110836                                         || dsstate.mode == constant.ALERT_REFRESH_FROM_CLIENT ) ) ) )
110837                             return cb(new common.ProtocolError(
110838                                     'unexpected sync data (role="'
110839                                         + ( session.isServer ? 'server' : 'client' )
110840                                         + '", mode="' + common.mode2string(dsstate.mode)
110841                                         + '")'));
110842
110843                         common.cascade(command.data, function(cmd, cb) {
110844
110845                             // NOTE: commented this paranoia setting out, since the server
110846                             //       *may* decide to update/delete a client item...
110847                             //       e.g. conflict-resolved-merge (207)
110848                             // TODO: perhaps i should only allow non-ADDs for those items
110849                             //       that i received a conflict-resolved-merge (207) for?...
110850
110851                             // // paranoia: non-'add' sync commands should only be received in non-refresh modes
110852                             // if ( cmd.name != constant.CMD_ADD
110853                             //      && _.indexOf([constant.ALERT_TWO_WAY,
110854                             //                    constant.ALERT_ONE_WAY_FROM_SERVER,
110855                             //                    constant.ALERT_ONE_WAY_FROM_CLIENT], dsstate.mode) < 0 )
110856                             //   return cb(new common.ProtocolError(
110857                             //     'unexpected non-add sync command (role="'
110858                             //       + ( session.isServer ? 'server' : 'client' )
110859                             //       + '", mode="' + common.mode2string(dsstate.mode)
110860                             //       + '", command="' + cmd.name
110861                             //       + '")'));
110862
110863                             self._reaction_syncdispatch(session, cmd, store, dsstate, function(err, cmds) {
110864                                 if ( err )
110865                                 return cb(err);
110866                             _.each(cmds, function(cmd) { ret.push(cmd); });
110867                             return cb();
110868                             });
110869
110870                         }, function(err) {
110871                             if ( err )
110872                                 return cb(err);
110873                             return cb(null, ret);
110874                         });
110875                         });
110876                     },
110877
110878                     //-------------------------------------------------------------------------
110879                     _reaction_syncdispatch: function(session, cmd, store, dsstate, cb) {
110880
110881                         var self = this;
110882                         var func = self['_reaction_sync_' + cmd.name.toLowerCase()];
110883                         if ( ! func )
110884                             return cb(new common.ProtocolError(
110885                                         'unexpected reaction requested for sync command "' + cmd.name + '"'));
110886
110887                         var check_for_conflicts = common.noop;
110888
110889                         if ( session.isServer
110890                                 && cmd.name != constant.CMD_ADD
110891                                 && dsstate.mode != constant.ALERT_REFRESH_FROM_CLIENT )
110892                         {
110893                             // server, non-add, non-slowsync, non-refresh commands: check for conflicts.
110894                             // note that certain types of content could be a conflict even if it is an
110895                             // "Add" command; for example, two files with the same name cannot be added
110896                             // from separate clients.
110897
110898                             check_for_conflicts = function(cb) {
110899
110900                                 // todo: allow agents to raise a ConflictError...
110901                                 //       ==> perhaps this is already covered by the .matchItem() API?...
110902
110903                                 var policy = store.conflictPolicy || session.adapter.conflictPolicy;
110904                                 var peerStore = session.peer.getStore(dsstate.peerUri);
110905                                 self.getSourceMapping(
110906                                         session, constant.CMD_SYNC, cmd, peerStore, cmd.source,
110907                                         function(err, itemID) {
110908
110909                                             if ( err )
110910                                     return cb(err);
110911                                 if ( ! itemID )
110912                                     // this shouldn't happen...
110913                                     return cb();
110914
110915                                 peerStore._getChange(itemID, function(err, change) {
110916                                     if ( err )
110917                                     return cb(err);
110918                                 if ( ! change )
110919                                     return cb();
110920
110921                                 var retcmd = state.makeCommand({
110922                                     name       : constant.CMD_STATUS,
110923                                     cmdID      : session.nextCmdID(),
110924                                     msgRef     : cmd.msgID,
110925                                     cmdRef     : cmd.cmdID,
110926                                     sourceRef  : cmd.source,
110927                                     targetRef  : cmd.target,
110928                                     statusOf   : cmd.name,
110929                                     // todo: make this error message a bit more descriptive...
110930                                     errorMsg   : 'command "' + cmd.name + '" conflict for item ID "'
110931                                     + itemID + '" (state: ' + common.state2string(change.state) + ')'
110932                                 });
110933
110934
110935                                     // four possible states: mod-mod, mod-del, del-mod, del-del
110936                                     if ( ! dsstate.conflicts )
110937                                     dsstate.conflicts = [];
110938
110939                                     // handle mod-mod (but only if change-tracking is enabled)
110940                                     if ( change.state == constant.ITEM_MODIFIED
110941                                         && cmd.name == constant.CMD_REPLACE )
110942                                     {
110943                                         cmd._conflict = retcmd;
110944                                         cmd._change   = change;
110945                                         return cb();
110946                                     }
110947
110948                                     // handle del-del
110949                                     if ( change.state == constant.ITEM_DELETED
110950                                             && cmd.name == constant.CMD_DELETE )
110951                                     {
110952                                         // both changes are deletes... that's not a conflict.
110953                                         // TODO: should i really be doing all this here?... it does not
110954                                         //       follow the pattern..
110955                                         peerStore._delChange({
110956                                             itemID: change.item_id,
110957                                             state:  change.state
110958                                         }, function(err) {
110959                                             if ( err )
110960                                             return cb(err);
110961                                         dsstate.stats.peerDel   += 1;
110962                                         dsstate.stats.hereDel   += 1;
110963                                         dsstate.stats.merged    += 1;
110964                                         retcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_MERGE;
110965                                         retcmd.errorCode  = null;
110966                                         retcmd.errorMsg   = null;
110967                                         return cb(null, [retcmd]);
110968                                         });
110969                                         return;
110970                                     }
110971
110972                                     // handle del-mod or mod-del
110973                                     if ( ( change.state == constant.ITEM_DELETED
110974                                                 || cmd.name == constant.CMD_DELETE )
110975                                             && policy != constant.POLICY_ERROR )
110976                                     {
110977                                         // one of them is a delete and a conflict that can be solved
110978                                         // by the framework
110979                                         cmd._conflict = retcmd;
110980                                         cmd._change   = change;
110981                                         return cb();
110982                                     }
110983
110984                                     dsstate.conflicts.push(itemID);
110985                                     dsstate.stats.peerErr   += 1;
110986                                     dsstate.stats.conflicts += 1;
110987                                     retcmd.statusCode = constant.STATUS_UPDATE_CONFLICT;
110988                                     retcmd.errorCode  = 'syncml-js.synchronizer.RSd.10';
110989                                     return cb(null, [retcmd]);
110990                                 });
110991                                         }
110992                                 );
110993                             };
110994                         }
110995
110996                         check_for_conflicts(function(err, cmds) {
110997                             if ( err || cmds )
110998                             return cb(err, cmds);
110999                         try{
111000                             func.call(self, session, cmd, store, dsstate, cb);
111001                         }catch(e){
111002                             return cb(new common.InternalError(
111003                                     'failed invoking synchronizer sync reaction: ' + e, e));
111004                         }
111005                         });
111006
111007                     },
111008
111009                     //-------------------------------------------------------------------------
111010                     _reaction_sync_add: function(session, cmd, store, dsstate, cb) {
111011                         var curitem = null;
111012                         var item    = null;
111013                         if ( store.agent.hierarchicalSync )
111014                         {
111015                             if ( cmd.targetParent )
111016                                 cmd.data.parent = cmd.targetParent;
111017                             else if ( cmd.sourceParent )
111018                                 cmd.data.parent = session.hierlut[cmd.sourceParent];
111019                         }
111020
111021                         var matcher = common.noop;
111022                         if ( session.isServer && dsstate.mode == constant.ALERT_SLOW_SYNC )
111023                         {
111024                             // TODO: if the matched item is already mapped to another client-side
111025                             //       object, then this should cancel the matching...
111026                             matcher = function(cb) {
111027                                 store.agent.matchItem(cmd.data, function(err, match) {
111028                                     if ( err )
111029                                     return cb(err);
111030                                 if ( ! match || ! match.compare )
111031                                     return cb();
111032                                 curitem = match;
111033                                 if ( match.compare(cmd.data) == 0 )
111034                                     return cb();
111035                                 store.agent.mergeItems(curitem, cmd.data, null, function(err) {
111036                                     // TODO: if there is a common.ConflictError, set
111037                                     //       curitem to null and continue without error...
111038                                     if ( err )
111039                                     return cb(err);
111040                                 store.registerChange(curitem.id, constant.ITEM_MODIFIED,
111041                                     {changeSpec: cspec, excludePeerID: session.peer.id},
111042                                     cb);
111043                                 });
111044                                 });
111045                             };
111046                         }
111047
111048                         matcher(function(err) {
111049                             if ( err )
111050                             return cb(err);
111051                         var adder = common.noop;
111052                         if ( ! curitem )
111053                             adder = function(cb) {
111054                                 store.agent.addItem(cmd.data, function(err, newitem) {
111055                                     if ( err )
111056                                     return cb(err);
111057                                 item = newitem;
111058                                 dsstate.stats.hereAdd += 1;
111059                                 store.registerChange(item.id, constant.ITEM_ADDED,
111060                                     {excludePeerID: session.peer.id}, cb);
111061                                 });
111062                             };
111063                         else
111064                             item = curitem;
111065                         return adder(function(err) {
111066                             if ( err )
111067                             return cb(err);
111068
111069                         if ( store.agent.hierarchicalSync )
111070                             session.hierlut[cmd.source] = item.id;
111071
111072                         var ret = [state.makeCommand({
111073                             name       : constant.CMD_STATUS,
111074                             cmdID      : session.nextCmdID(),
111075                             msgRef     : cmd.msgID,
111076                             cmdRef     : cmd.cmdID,
111077                             sourceRef  : cmd.source,
111078                             statusOf   : cmd.name,
111079                             statusCode : ( curitem
111080                                 ? constant.STATUS_ALREADY_EXISTS
111081                                 : constant.STATUS_ITEM_ADDED )
111082                         })];
111083
111084                         if ( ! session.isServer )
111085                         {
111086                             ret.push(state.makeCommand({
111087                                 name       : constant.CMD_MAP,
111088                                 cmdID      : session.nextCmdID(),
111089                                 source     : store.uri,
111090                                 target     : dsstate.peerUri,
111091                                 sourceItem : item.id,
111092                                 targetItem : cmd.source
111093                             }));
111094                             return cb(null, ret);
111095                         }
111096
111097                         var peerStore = session.peer.getStore(dsstate.peerUri);
111098                         peerStore._setMapping(item.id, cmd.source, function(err) {
111099                             if ( err )
111100                             return cb(err);
111101                         return cb(null, ret);
111102                         });
111103
111104                         });
111105                         });
111106
111107                     },
111108
111109                     //-------------------------------------------------------------------------
111110                     getSourceMapping: function(session, cmdctxt, cmd, peerStore, luid, cb) {
111111                         peerStore._getReverseMapping(luid, function(err, guid) {
111112
111113                             if ( err )
111114                             return cb(err);
111115
111116                         if ( guid )
111117                             return cb(null, guid);
111118
111119                         return cb(new common.InvalidItem(
111120                                 'unexpected "' + cmdctxt + '/' + cmd.name
111121                                 + '" request for unmapped item ID "' + luid + '"'));
111122
111123                         // todo: pysyncml generates a nice cmd-specific error node:
111124                         //       (which is probably over-kill)
111125
111126                         //     curmap = adapter._context._model.Mapping.q(store_id=peerStore.id, luid=luid).one()
111127                         //     return str(curmap.guid)
111128                         //   except NoResultFound:
111129                         //     msg = 'unexpected "%s/%s" request for unmapped item ID: %r' % (cmdctxt, cmd.name, luid)
111130                         //     # todo: this is a bit of a hack when cmdctxt == 'Status'...
111131                         //     return state.Command(
111132                         //       name       = constant.CMD_STATUS,
111133                         //       cmdID      = session.nextCmdID(),
111134                         //       msgRef     = cmd.msgID,
111135                         //       cmdRef     = cmd.cmdID,
111136                         //       sourceRef  = cmd.source,
111137                         //       targetRef  = cmd.target,
111138                         //       statusOf   = cmd.name if cmdctxt != constant.CMD_STATUS else cmdctxt,
111139                         //       statusCode = constant.STATUS_COMMAND_FAILED,
111140                         //       errorCode  = __name__ + '.' + self.__class__.__name__ + '.GSM.10',
111141                         //       errorMsg   = msg,
111142                         //       )
111143
111144                         });
111145                     },
111146
111147                     //-------------------------------------------------------------------------
111148                     _reaction_sync_replace: function(session, cmd, store, dsstate, cb) {
111149
111150                         // TODO: handle hierarchical-sync...
111151                         var self = this;
111152                         var item = cmd.data;
111153                         var get_item_id = ( ! session.isServer ) ? function(cb) {
111154                             item.id = cmd.target;
111155                             return cb();
111156                         } : function(cb) {
111157                             var peerStore = session.peer.getStore(dsstate.peerUri);
111158                             self.getSourceMapping(
111159                                     session, constant.CMD_SYNC, cmd, peerStore, cmd.source,
111160                                     function(err, guid) {
111161
111162                                         if ( err )
111163                                 return cb(err);
111164
111165                             // todo: what if guid is null?...
111166
111167                             item.id = guid;
111168                             return cb();
111169                                     }
111170                                     );
111171                         };
111172
111173                         var okcmd = state.makeCommand({
111174                             name       : constant.CMD_STATUS,
111175                             cmdID      : session.nextCmdID(),
111176                             msgRef     : cmd.msgID,
111177                             cmdRef     : cmd.cmdID,
111178                             targetRef  : cmd.target,
111179                             sourceRef  : cmd.source,
111180                             statusOf   : cmd.name,
111181                             statusCode : constant.STATUS_OK
111182                         });
111183
111184                         var handle_conflict = ( ! cmd._conflict ) ? common.noop : function(cb) {
111185
111186                             //   if cmd._conflict is not None:
111187                             //     try:
111188                             //       if cmd._change.state == constant.ITEM_DELETED:
111189                             //         raise common.ConflictError('item deleted')
111190                             //       if cmd._change.changeSpec is None:
111191                             //         raise common.ConflictError('no change tracking enabled - falling back to policy')
111192                             //       cspec = store.agent.mergeItems(store.agent.getItem(item.id), item, cmd._change.changeSpec)
111193                             //       dsstate.stats.hereMod += 1
111194                             //       store.registerChange(item.id, constant.ITEM_MODIFIED,
111195                             //                            changeSpec=cspec, excludePeerID=adapter.peer.id)
111196                             //       okcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_MERGE
111197                             //       # NOTE: *not* suppressing the change that is registered from server
111198                             //       #       to client, since the merge may have resulted in an item that
111199                             //       #       is not identical to the one on the client.
111200                             //       return [okcmd]
111201                             //     except common.ConflictError, e:
111202                             //       # conflict types: client=mod/server=mod or client=mod/server=del
111203                             //       if store.conflictPolicy == constant.POLICY_CLIENT_WINS:
111204                             //         adapter._context._model.session.delete(cmd._change)
111205                             //         dsstate.stats.merged += 1
111206                             //         okcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA
111207                             //         if cmd._change.state == constant.ITEM_DELETED:
111208                             //           # todo: this "re-creation" of a new item is detrimental to
111209                             //           #       clients that are tracking changes to an item (for
111210                             //           #       example, a SyncML svn client bridge...). but then, to
111211                             //           #       them, this item may already have been deleted. ugh.
111212                             //           dsstate.stats.hereMod += 1
111213                             //           item = store.agent.addItem(item)
111214                             //           peerStore = store.peer
111215                             //           adapter._context._model.Mapping.q(store_id=peerStore.id, guid=item.id).delete()
111216                             //           newmap = adapter._context._model.Mapping(store_id=peerStore.id,
111217                             //                                                    guid=item.id,
111218                             //                                                    luid=cmd.source)
111219                             //           adapter._context._model.session.add(newmap)
111220                             //           store.registerChange(item.id, constant.ITEM_ADDED,
111221                             //                                excludePeerID=adapter.peer.id)
111222                             //           return [okcmd]
111223                             //         # falling back to standard handling...
111224                             //       elif store.conflictPolicy == constant.POLICY_SERVER_WINS:
111225                             //         dsstate.stats.merged += 1
111226                             //         okcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA
111227                             //         return [okcmd]
111228                             //       else:
111229                             //         # store.conflictPolicy == constant.POLICY_ERROR or other...
111230                             //         dsstate.stats.peerErr    += 1
111231                             //         dsstate.stats.conflicts  += 1
111232                             //         cmd._conflict.errorMsg   += ', agent failed merge: ' + str(e)
111233                             //         cmd._conflict.statusCode = constant.STATUS_UPDATE_CONFLICT
111234                             //         cmd._conflict.errorCode  = common.fullClassname(self) + '.RSR.10'
111235                             //         dsstate.conflicts.append(str(item.id))
111236                             //         return [cmd._conflict]
111237
111238                             cb();
111239
111240                         };
111241
111242                         // TODO: support hierarchical-sync...
111243                         // if ( store.agent.hierarchicalSync )
111244                         //   session.hierlut[cmd.source] = item.id;
111245
111246                         get_item_id(function(err) {
111247                             if ( err )
111248                             return cb(err);
111249                         handle_conflict(function(err) {
111250                             if ( err )
111251                             return cb(err);
111252                         store.agent.replaceItem(item, session.isServer, function(err, cspec) {
111253                             if ( err )
111254                             return cb(err);
111255                         dsstate.stats.hereMod += 1;
111256                         store.registerChange(
111257                             item.id, constant.ITEM_MODIFIED,
111258                             {changeSpec: cspec, excludePeerID: session.peer.id},
111259                             function(err) {
111260                                 if ( err )
111261                             return cb(err);
111262                         return cb(null, [okcmd]);
111263                             }
111264                             );
111265                         });
111266                         });
111267                         });
111268
111269                     },
111270
111271                     //-------------------------------------------------------------------------
111272                     _reaction_sync_delete: function(session, cmd, store, dsstate, cb) {
111273
111274                         var self   = this;
111275                         var status = constant.STATUS_OK;
111276                         var itemID = null;
111277
111278                         var get_item_id = ( ! session.isServer ) ? function(cb) {
111279                             itemID = cmd.target;
111280                             return cb();
111281                         } : function(cb) {
111282                             var peerStore = session.peer.getStore(dsstate.peerUri);
111283                             self.getSourceMapping(
111284                                     session, constant.CMD_SYNC, cmd, peerStore, cmd.source,
111285                                     function(err, guid) {
111286
111287                                         // if not isinstance(itemID, basestring):
111288                                         //   return [itemID]
111289
111290                                         if ( err )
111291                                 return cb(err);
111292
111293                             // todo: what if guid is null?...
111294
111295                             itemID = guid;
111296                             if ( ! cmd._conflict )
111297                                 return cb();
111298                             var policy = store.conflictPolicy || session.adapter.conflictPolicy;
111299                             switch ( policy )
111300                             {
111301
111302                                 case constant.POLICY_CLIENT_WINS:
111303                                     {
111304
111305
111306                                         // TODO ::: implement these...
111307
111308                                         //   //     adapter._context._model.session.delete(cmd._change)
111309                                         //   //     status = constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA
111310                                         //   //     session.dsstates[store.uri].stats.merged += 1
111311                                         //   //     # falling back to standard handling...
111312
111313                                         //   break;
111314
111315                                     }
111316                                 case constant.POLICY_SERVER_WINS:
111317                                     {
111318
111319
111320                                         //   //     adapter._context._model.session.delete(cmd._change)
111321                                         //   //     store.peer.registerChange(itemID, constant.ITEM_ADDED)
111322                                         //   //     session.dsstates[store.uri].stats.merged += 1
111323                                         //   //     cmd._conflict.statusCode = constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA
111324                                         //   //     cmd._conflict.errorCode  = None
111325                                         //   //     cmd._conflict.errorMsg   = None
111326                                         //   //     return [cmd._conflict]
111327
111328                                         //   break;
111329
111330                                     }
111331
111332                                 default:
111333                                     {
111334                                         // a constant.POLICY_ERROR policy should have been handled by the dispatch
111335                                         return cb(new common.InternalError(
111336                                                     'unexpected conflictPolicy: %s', '' + policy));
111337                                     }
111338                             }
111339                                     }
111340                             );
111341
111342                         };
111343
111344                         get_item_id(function(err) {
111345                             if ( err )
111346                             return cb(err);
111347                         store.agent.deleteItem(itemID, function(err) {
111348                             if ( err )
111349                             return cb(err);
111350                         dsstate.stats.hereDel += 1;
111351                         store.registerChange(
111352                             itemID, constant.ITEM_DELETED, {excludePeerID: session.peer.id},
111353                             function(err) {
111354                                 if ( err )
111355                             return cb(err);
111356                         return cb(null, [state.makeCommand({
111357                             name       : constant.CMD_STATUS,
111358                                cmdID      : session.nextCmdID(),
111359                                msgRef     : cmd.msgID,
111360                                cmdRef     : cmd.cmdID,
111361                                targetRef  : cmd.target,
111362                                sourceRef  : cmd.source,
111363                                statusOf   : cmd.name,
111364                                // todo: should this return DELETE_WITHOUT_ARCHIVE instead of OK?...
111365                                // statusCode = constant.STATUS_DELETE_WITHOUT_ARCHIVE,
111366                                statusCode : status
111367                         })]);
111368                             }
111369                             );
111370                         });
111371                         });
111372
111373                     },
111374
111375                     //-------------------------------------------------------------------------
111376                     _reaction_map: function(session, command, cb) {
111377                         var peerStore = session.peer.getStore(command.source);
111378                         if ( command.target != peerStore._getBinding().uri )
111379                             return cb(new common.NoSuchRoute(
111380                                         'unexpected "Map" event for unbound stores (local: "'
111381                                             + command.target + ', remote: "' + command.source + '")'));
111382                         common.cascade(command.items, function(item, cb) {
111383                             // todo: support hierarchical sync...
111384                             peerStore._setMapping(item.target, item.source, cb);
111385                         }, function(err) {
111386                             if ( err )
111387                             return cb(err);
111388                         return cb(null, [state.makeCommand({
111389                             name       : constant.CMD_STATUS,
111390                                cmdID      : session.nextCmdID(),
111391                                msgRef     : command.msgID,
111392                                cmdRef     : command.cmdID,
111393                                targetRef  : command.target,
111394                                sourceRef  : command.source,
111395                                statusOf   : command.name,
111396                                statusCode : constant.STATUS_OK
111397                         })]);
111398                         });
111399                     },
111400
111401                     //-------------------------------------------------------------------------
111402                     // SYNCHRONIZATION PHASE: SETTLE
111403                     //-------------------------------------------------------------------------
111404
111405                     //-------------------------------------------------------------------------
111406                     settle: function(session, cmd, chkcmd, xnode, cb) {
111407
111408                         // TODO: remove the "xnode" parameter... it is a hack so that i can
111409                         //       call badStatus() the same way as in protocol.js
111410                         // todo: there is a bit of a disconnect between how action and reaction
111411                         //       phases are called (for a list of commands), whereas the settle
111412                         //       phase is called on a per-item basis... not ideal, but the protocol
111413                         //       is really set up that way :(
111414                         // TODO: check all valid values of ``data``...
111415                         // todo: anything else in common?...
111416                         // todo: trap errors...
111417
111418                         var func = this['_settle_' + cmd.name.toLowerCase()];
111419                         if ( ! func )
111420                             return cb(new common.ProtocolError('unexpected settle command "' + cmd.name + '"'));
111421                         return func.call(this, session, cmd, chkcmd, xnode, cb);
111422                     },
111423
111424                     //-------------------------------------------------------------------------
111425                     _settle_add: function(session, cmd, chkcmd, xnode, cb) {
111426                         switch ( cmd.data )
111427                         {
111428                             default:
111429                                 {
111430                                     return cb(badStatus(xnode));
111431                                 }
111432                             case constant.STATUS_OK:
111433                             case constant.STATUS_ITEM_ADDED:
111434                             case constant.STATUS_CONFLICT_RESOLVED_DUPLICATE:
111435                                 {
111436                                     session.info.dsstates[chkcmd.uri].stats.peerAdd += 1;
111437                                     break;
111438                                 }
111439                             case constant.STATUS_ALREADY_EXISTS:
111440                             case constant.STATUS_CONFLICT_RESOLVED_MERGE:
111441                                 // todo: should this conflict-resolved-merge status be stored so
111442                                 //       that only this item can have a non-"ADD" during initial
111443                                 //       sync?...
111444                             case constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA:
111445                                 {
111446                                     session.info.dsstates[chkcmd.uri].stats.merged += 1;
111447                                     break;
111448                                 }
111449                         }
111450
111451                         var peerStore = session.peer.getStore(
111452                                 session.context.router.getTargetUri(
111453                                     session.adapter, session.peer, chkcmd.uri));
111454
111455                         peerStore._delChange({
111456                             itemID: chkcmd.source,
111457                             state: constant.ITEM_ADDED
111458                         }, cb);
111459                     },
111460
111461                     //-------------------------------------------------------------------------
111462                     _settle_replace: function(session, cmd, chkcmd, xnode, cb) {
111463
111464                         var self = this;
111465                         var dsstate = session.info.dsstates[chkcmd.uri];
111466
111467                         if ( ! session.isServer && cmd.data == constant.STATUS_UPDATE_CONFLICT )
111468                         {
111469                             dsstate.stats.hereErr   += 1;
111470                             dsstate.stats.conflicts += 1;
111471                             return cb();
111472                         }
111473                         if ( cmd.data != constant.STATUS_OK
111474                                 && cmd.data != constant.STATUS_CONFLICT_RESOLVED_MERGE
111475                                 && cmd.data != constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA
111476                                 && cmd.data != constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA )
111477                             return cb(badStatus(xnode));
111478                         if ( cmd.data == constant.STATUS_CONFLICT_RESOLVED_MERGE
111479                                 || cmd.data == constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA
111480                                 || cmd.data == constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA )
111481                             dsstate.stats.merged += 1;
111482                         if ( cmd.data != constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA )
111483                             dsstate.stats.peerMod += 1;
111484
111485                         var peerStore = session.peer.getStore(
111486                                 session.context.router.getTargetUri(
111487                                     session.adapter, session.peer, chkcmd.uri));
111488
111489                         var get_item_id = ( ! session.isServer ) ? function(cb) {
111490                             return cb(null, chkcmd.source);
111491                         } : function(cb) {
111492                             // if not isinstance(locItemID, basestring):
111493                             //   return locItemID
111494
111495                             self.getSourceMapping(
111496                                     session, constant.CMD_STATUS, cmd, peerStore, chkcmd.target,
111497                                     function(err, guid) { return cb(err, guid); }
111498                                     );
111499                         };
111500
111501                         get_item_id(function(err, locItemID) {
111502
111503                             if ( err )
111504                             return cb(err);
111505
111506                         // todo: this is *technically* subject to a race condition... but the
111507                         //       same peer should really not be synchronizing at the same time...
111508                         // todo: also potentially check Change.registered...
111509                         // TODO: this could be solved by:
111510                         //         a) never updating a Change record (only deleting and replacing)
111511                         //         b) deleting Change records by ID instead of by store/item/state...
111512
111513                         peerStore._delChange({
111514                             itemID    : locItemID,
111515                             state     : constant.ITEM_MODIFIED,
111516                         }, cb);
111517
111518                         });
111519
111520                     },
111521
111522                     //-------------------------------------------------------------------------
111523                     _settle_delete: function(session, cmd, chkcmd, xnode, cb) {
111524                         var self    = this;
111525                         var dsstate = session.info.dsstates[chkcmd.uri];
111526                         if ( ! session.isServer && cmd.data == constant.STATUS_UPDATE_CONFLICT )
111527                         {
111528                             dsstate.stats.hereErr   += 1;
111529                             dsstate.stats.conflicts += 1;
111530                             return cb();
111531                         }
111532                         if ( ! session.isServer && cmd.data == constant.STATUS_CONFLICT_RESOLVED_MERGE )
111533                         {
111534                             dsstate.stats.hereDel   += 1;
111535                             dsstate.stats.peerDel   += 1;
111536                             dsstate.stats.merged    += 1;
111537                         }
111538                         else if ( ! session.isServer && cmd.data == constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA )
111539                         {
111540                             dsstate.stats.peerDel   += 1;
111541                             dsstate.stats.merged    += 1;
111542                         }
111543                         else if ( ! session.isServer && cmd.data == constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA )
111544                             dsstate.stats.merged    += 1;
111545                         else if ( cmd.data == constant.STATUS_ITEM_NOT_DELETED )
111546                         {
111547                             // note: the reason that this *may* be ok is that some servers (funambol)
111548                             //       will report ITEM_NOT_DELETED when the item did not exist, thus this
111549                             //       is "alright"...
111550                             // todo: perhaps this should be raised as an error if the
111551                             //       remote peer != funambol?...
111552                         }
111553                         else if ( cmd.data == constant.STATUS_OK )
111554                             dsstate.stats.peerDel += 1;
111555                         else
111556                             return cb(badStatus(xnode));
111557
111558                         var peerStore = session.peer.getStore(
111559                                 session.context.router.getTargetUri(
111560                                     session.adapter, session.peer, chkcmd.uri));
111561
111562                         // todo: handle hierarchical sync...
111563                         var get_locItemID = ( ! chkcmd.target ) ? function(cb) {
111564                             cb(null, chkcmd.source);
111565                         } : function(cb) {
111566                             self.getSourceMapping(
111567                                     session, constant.CMD_STATUS, cmd, peerStore, chkcmd.target,
111568                                     function(err, guid) { return cb(err, guid); }
111569                                     );
111570                         };
111571
111572                         // todo: this is *technically* subject to a race condition... but the
111573                         //       same peer should really not be synchronizing at the same time...
111574                         // todo: also potentially check Change.registered...
111575                         // TODO: this could be solved by:
111576                         //         a) never updating a Change record (only deleting and replacing)
111577                         //         b) deleting Change records by ID instead of by store/item/state...
111578
111579                         get_locItemID(function(err, locItemID) {
111580                             if ( err )
111581                             return cb(err);
111582                         peerStore._delChange({
111583                             itemID    : locItemID,
111584                             state     : constant.ITEM_DELETED,
111585                         }, cb);
111586                         });
111587
111588                     }
111589
111590     });
111591
111592     return exports;
111593
111594 })();
111595
111596 module.exports = _self;
111597
111598 });
111599 define('ripple/platform/tizen/2.0/syncml-js-lib/useragent', function (require, exports, module) {
111600 // -*- coding: utf-8 -*-
111601 //-----------------------------------------------------------------------------
111602 // file: $Id$
111603 // lib:  syncml-js.useragent
111604 // auth: griffin <griffin@uberdev.org>
111605 // date: 2013/06/07
111606 // copy: (C) CopyLoose 2013 UberDev <hardcore@uberdev.org>, No Rights Reserved.
111607 //-----------------------------------------------------------------------------
111608
111609 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
111610     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
111611     _self;
111612
111613 _self = (function () {
111614     var exports = {};
111615
111616     //---------------------------------------------------------------------------
111617     exports.UserAgent = common.Base.extend({
111618         // primary handlers:
111619         acceptSyncModeSwitch:  null, // function(EVENT, CALLBACK(ERR))
111620             acceptDevInfoSwap:     null, // function(EVENT, CALLBACK(ERR))
111621             chooseRefreshRequired: null, // function(EVENT, CALLBACK(ERR, TYPE))
111622             fetchCredentials:      null, // function(EVENT, CALLBACK(ERR, AUTH))
111623             // fallback handlers:
111624             accept:                null, // function(TYPE, EVENT, CALLBACK(ERR))
111625             choose:                null, // function(TYPE, EVENT, CALLBACK(ERR, CHOICE))
111626             fetch:                 null, // function(TYPE, EVENT, CALLBACK(ERR, STRUCT))
111627             // catchall handler:
111628             handle:                null  // function(ACTION, TYPE, EVENT, CALLBACK(ERR, RESULT...))
111629     });
111630
111631     //---------------------------------------------------------------------------
111632     exports.UserAgentMultiplexer = common.Base.extend({
111633
111634         //-------------------------------------------------------------------------
111635         constructor: function(uaList) {
111636             this.ualist = uaList;
111637         },
111638
111639         //-------------------------------------------------------------------------
111640         _getHandler: function(name) {
111641             for ( var idx=0 ; idx<this.ualist.length ; idx++ )
111642     {
111643         var ua = this.ualist[idx];
111644         if ( ua && _.isFunction(ua[name]) )
111645         return ua[name];
111646     }
111647     return null;
111648         },
111649
111650         //-------------------------------------------------------------------------
111651         hasHandler: function(name) {
111652             return !! this._getHandler(name);
111653         },
111654
111655         //-------------------------------------------------------------------------
111656         acceptSyncModeSwitch: function(event, cb) {
111657             return this._handle({
111658                 handler: 'acceptSyncModeSwitch',
111659             action:  'accept',
111660             type:    'sync.mode.switch'
111661             }, event, cb);
111662         },
111663
111664         //-------------------------------------------------------------------------
111665         acceptDevInfoSwap: function(event, cb) {
111666             return this._handle({
111667                 handler: 'acceptDevInfoSwap',
111668             action:  'accept',
111669             type:    'dev.info.swap'
111670             }, event, cb);
111671         },
111672
111673         //-------------------------------------------------------------------------
111674         chooseRefreshRequired: function(event, cb) {
111675             return this._handle({
111676                 handler: 'chooseRefreshRequired',
111677             action:  'choose',
111678             type:    'refresh.required',
111679             choices: [
111680             {value: constant.SYNCTYPE_SLOW_SYNC, default: true},
111681             {value: constant.SYNCTYPE_REFRESH_FROM_CLIENT},
111682             {value: constant.SYNCTYPE_REFRESH_FROM_SERVER}
111683             ]
111684             }, event, function(err, choice) {
111685                 if ( err )
111686                 return cb(err);
111687             // todo: catch the condition where `choice` is not a valid synctype
111688             return cb(err, common.synctype2alert(choice));
111689             });
111690         },
111691
111692         //-------------------------------------------------------------------------
111693         fetchCredentials: function(event, cb) {
111694             return this._handle({
111695                 handler: 'fetchCredentials',
111696             action:  'fetch',
111697             type:    'auth.challenge',
111698             choices: [
111699             {value: constant.SYNCTYPE_SLOW_SYNC, default: true},
111700             {value: constant.SYNCTYPE_REFRESH_FROM_CLIENT},
111701             {value: constant.SYNCTYPE_REFRESH_FROM_SERVER}
111702             ]
111703             }, event, cb);
111704         },
111705
111706         //-------------------------------------------------------------------------
111707         _handle: function(spec, event, cb) {
111708             event = _.extend({}, spec, event, {
111709                 type         : spec.type,
111710             context      : event.session.context,
111711             adapter      : event.session.adapter,
111712             peer         : event.session.peer,
111713             ua_handler   : spec.handler,
111714             ua_action    : spec.action
111715             });
111716             var handler = this._getHandler(spec.handler);
111717             if ( handler )
111718                 return handler(event, cb);
111719             handler = this._getHandler(spec.action);
111720             if ( handler )
111721                 return handler(spec.type, event, cb);
111722             handler = this._getHandler('handle');
111723             if ( handler )
111724                 return handler(spec.action, spec.type, event, cb);
111725             if ( spec.action == 'accept' )
111726             {
111727                 return cb();
111728             }
111729             if ( spec.action == 'choose'
111730                     && event.choices && event.choices.length > 0 )
111731             {
111732                 var choice = _.find(event.choices, function(c) { return c.default; });
111733                 if ( ! choice )
111734                     choice = event.choices[0];
111735                 if ( choice.value )
111736                     choice = choice.value;
111737                 return cb(null, choice);
111738             }
111739             if ( spec.type == 'auth.challenge' )
111740                 return cb();
111741             return cb(new common.NotImplementedError(
111742                         'user-agent handler for event type "' + spec.type + '" (action: "'
111743                             + spec.action + '") not found or defined'));
111744         }
111745
111746     });
111747
111748     return exports;
111749
111750 })();
111751
111752 module.exports = _self;
111753
111754 });
111755 define('ripple/platform/tizen/2.0/systeminfo', function (require, exports, module) {
111756 /*
111757  *  Copyright 2013 Intel Corporation.
111758  *
111759  * Licensed under the Apache License, Version 2.0 (the "License");
111760  * you may not use this file except in compliance with the License.
111761  * You may obtain a copy of the License at
111762  *
111763  * http://www.apache.org/licenses/LICENSE-2.0
111764  *
111765  * Unless required by applicable law or agreed to in writing, software
111766  * distributed under the License is distributed on an "AS IS" BASIS,
111767  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
111768  * See the License for the specific language governing permissions and
111769  * limitations under the License.
111770  */
111771
111772 var deviceSettings = require('ripple/deviceSettings'),
111773     db = require('ripple/db'),
111774     t = require('ripple/platform/tizen/2.0/typecast'),
111775     typedef = require('ripple/platform/tizen/2.0/typedef'),
111776     constants = require('ripple/constants'),
111777     event = require('ripple/event'),
111778     tizen_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
111779     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
111780     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
111781     SystemInfoDeviceCapability,
111782     _systemInfoProperties = typedef.SystemInfoPropertyId,
111783     _propertyMap = {}, // Object like: {"BATTERY": ["level", "isCharging"], ...}
111784     _batteryEvent = ["BatteryLevelChanged", "BatteryChargingChanged"],
111785     _watches = {},
111786     _firstCall_watches = {},
111787     _powerData = {},
111788     _systemInfoDeviceCapability = null,
111789     _security = {
111790         "http://tizen.org/privilege/system": ["SystemInfoSIM", "webApiVersion",
111791                 "nativeApiVersion", "platformVersion"],
111792         "http://tizen.org/privilege/systemmanager": ["NetworkImei"]
111793     },
111794     _self;
111795
111796 function _prepareObj(obj, aspect, property, value) {
111797     if ((aspect === "CELLULAR_NETWORK") && (property === "imei")) {
111798         obj.__defineGetter__("imei", function () {
111799             if (!_security.NetworkImei) {
111800                 throw new WebAPIException(errorcode.SECURITY_ERR);
111801             }
111802             return deviceSettings.retrieve("CELLULAR_NETWORK.imei");
111803         });
111804     } else {
111805         if (aspect === "WIFI_NETWORK" || aspect === "CELLULAR_NETWORK") {
111806             if (property === 'status') {
111807                 if (value === true) {
111808                     value = "ON";
111809                 } else {
111810                     value = "OFF";
111811                 }
111812             }
111813         }
111814         obj.__defineGetter__(property, function () {
111815             return value;
111816         });
111817     }
111818 }
111819
111820 function _getValue(aspect, successCallback) {
111821     var properties = [], value, index = 0, property, obj = {};
111822
111823     if ((aspect === "SIM") && !_security.SystemInfoSIM) {
111824         throw new WebAPIException(errorcode.SECURITY_ERR);
111825     }
111826
111827     if (aspect === "BATTERY") {
111828         successCallback(_powerData);
111829         return;
111830     }
111831
111832     properties = _propertyMap[aspect];
111833     for (; index < properties.length; index++) {
111834         property = properties[index];
111835         value = deviceSettings.retrieve(aspect + "." + property);
111836         _prepareObj(obj, aspect, property, value);
111837     }
111838
111839     if (aspect === "STORAGE") {
111840         obj.__defineGetter__("units", function () {
111841             return [obj];
111842         });
111843     }
111844
111845     successCallback(obj);
111846 }
111847
111848 function _initialize() {
111849     var aspectName, index, i, vol;
111850
111851     for (index = 0; index < _systemInfoProperties.length; index++) {
111852         aspectName = _systemInfoProperties[index];
111853         _propertyMap[aspectName] = [];
111854         for (i in deviceSettings.retrieve(aspectName)) {
111855             _propertyMap[aspectName].push(i);
111856         }
111857     }
111858
111859     _propertyMap.BATTERY.push("level");
111860     _propertyMap.BATTERY.push("isCharging");
111861
111862     _powerData.__defineGetter__("isCharging", function () {
111863         return false;
111864     });
111865
111866     vol = db.retrieve(constants.BATTERY.VOLUME) || 100.0;
111867     _powerData.__defineGetter__("level", function () {
111868         return Number((vol / 100.0).toFixed(4));
111869     });
111870
111871     event.on("BatteryEvent", function (status) {
111872         _powerData.__defineGetter__("isCharging", function () {
111873             return status.charging;
111874         });
111875         _powerData.__defineGetter__("level", function () {
111876             return Number(status.level.toFixed(4));
111877         });
111878     });
111879 }
111880
111881 function _isPropertyFound(property) {
111882     if (tizen_utils.isEmptyObject(_propertyMap)) {
111883         _initialize();
111884     }
111885
111886     if (_propertyMap[property]) {
111887         return true;
111888     }
111889
111890     return false;
111891 }
111892
111893 function _delayGetValue(timeout, property, successCallback, errorCallback) {
111894     return window.setInterval(function () {
111895         _getValue(property, successCallback, errorCallback);
111896     }, timeout);
111897 }
111898
111899 _self = function () {
111900     function getCapabilities() {
111901         if (_systemInfoDeviceCapability === null) {
111902             _systemInfoDeviceCapability = new SystemInfoDeviceCapability();
111903         }
111904         return _systemInfoDeviceCapability;
111905     }
111906
111907     function getPropertyValue(property, successCallback, errorCallback) {
111908         t.SystemInfo("getPropertyValue", arguments);
111909
111910         if (!_isPropertyFound(property)) {
111911             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
111912         }
111913
111914         window.setTimeout(function () {
111915             _getValue(property, successCallback, errorCallback);
111916         }, 1);
111917     }
111918
111919     function addPropertyValueChangeListener(property, successCallback, options) {
111920         var WatchOBJ, watchId = Number(Math.uuid(8, 10)),
111921             _options = new Object(options), properties, prop, index = 0,
111922             deviceEventType, watchObj, firstCallWatchObj;
111923
111924         t.SystemInfo("addPropertyValueChangeListener", arguments);
111925
111926         if (!_isPropertyFound(property)) {
111927             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
111928         }
111929
111930         WatchOBJ = function (deviceEventType, property, successCallback) {
111931             var obj = this;
111932
111933             this.eventType = deviceEventType;
111934             this.onEvent = function (newValue) {
111935                 if (obj.timeout) {
111936                     window.clearInterval(obj.intervalId);
111937                     obj.intervalId = window.setInterval(function () {
111938                         _getValue(property, successCallback, null);
111939                     }, obj.timeout);
111940                 }
111941
111942                 if ((obj.highThreshold && (newValue < obj.highThreshold)) ||
111943                     (obj.lowThreshold && (newValue > obj.lowThreshold))) {
111944                     return;
111945                 }
111946
111947                 _getValue(property, successCallback, null);
111948             };
111949         };
111950
111951         // A listener will listen all the properties of one aspect, each of the property
111952         // will have an internal watchObj to record the information.
111953         _watches[watchId] = [];
111954
111955         if (property === "BATTERY") {
111956             properties = _batteryEvent;
111957         } else {
111958             properties = _propertyMap[property];
111959         }
111960
111961         for (; index < properties.length; index++) {
111962             prop = properties[index];
111963             if (property === "BATTERY") {
111964                 deviceEventType = prop;
111965             } else {
111966                 deviceEventType = deviceSettings.retrieve(property)[prop].event;
111967             }
111968
111969             if (deviceEventType === undefined) continue;
111970             // These two items are needed when delete an event listener.
111971             watchObj = new WatchOBJ(deviceEventType, property, successCallback);
111972
111973             if (options && _options.timeout) {
111974                 watchObj.intervalId = _delayGetValue(_options.timeout, property,
111975                         successCallback, null);
111976             }
111977
111978             if ((watchObj.eventType === "CpuLoadChanged") ||
111979                     (watchObj.eventType === "DisplayBrightnessChanged") ||
111980                     (watchObj.eventType === "BatteryLevelChanged")) {
111981                 if (options && _options.highThreshold) {
111982                     watchObj.highThreshold = _options.highThreshold;
111983                 }
111984
111985                 if (options && _options.lowThreshold) {
111986                     watchObj.lowThreshold = _options.lowThreshold;
111987                 }
111988             }
111989
111990             _watches[watchId].push(watchObj);
111991             if (watchObj.eventType) {
111992                 event.on(watchObj.eventType, watchObj.onEvent);
111993             }
111994         }
111995
111996         firstCallWatchObj = window.setTimeout(function () {
111997             _getValue(property, successCallback, null);
111998             delete _firstCall_watches[watchId];
111999         }, 1);
112000
112001         _firstCall_watches[watchId] = firstCallWatchObj;
112002
112003         return watchId;
112004     }
112005
112006     function removePropertyValueChangeListener(listenerID) {
112007         var _handler = listenerID, index = 0, watchObjs = [], watchObj;
112008
112009         if (!_watches[_handler])
112010             return;
112011
112012         watchObjs = _watches[_handler];
112013         if (watchObjs) {
112014             for (; index < watchObjs.length; index++) {
112015                 watchObj = watchObjs[index];
112016                 event.deleteEventHandler(watchObj.eventType, watchObj.onEvent);
112017                 if (watchObj.intervalId) {
112018                     window.clearInterval(watchObj.intervalId);
112019                 }
112020             }
112021             delete _watches[_handler];
112022         }
112023
112024         if (_firstCall_watches[_handler]) {
112025             window.clearTimeout(_firstCall_watches[_handler]);
112026             delete _firstCall_watches[_handler];
112027         }
112028     }
112029
112030     function handleSubFeatures(subFeatures) {
112031         var i, subFeature;
112032
112033         for (subFeature in subFeatures) {
112034             for (i in _security[subFeature]) {
112035                 _security[_security[subFeature][i]] = true;
112036             }
112037         }
112038     }
112039
112040     var systeminfo = {
112041         getCapabilities: getCapabilities,
112042         getPropertyValue: getPropertyValue,
112043         addPropertyValueChangeListener: addPropertyValueChangeListener,
112044         removePropertyValueChangeListener: removePropertyValueChangeListener,
112045         handleSubFeatures: handleSubFeatures
112046     };
112047
112048     return systeminfo;
112049 };
112050
112051 SystemInfoDeviceCapability = function () {
112052     this.__defineGetter__("bluetooth", function () {
112053         return true;
112054     });
112055     this.__defineGetter__("nfc", function () {
112056         return true;
112057     });
112058     this.__defineGetter__("nfcReservedPush", function () {
112059         return false;
112060     });
112061     this.__defineGetter__("multiTouchCount", function () {
112062         return 5;
112063     });
112064     this.__defineGetter__("inputKeyboard", function () {
112065         return false;
112066     });
112067     this.__defineGetter__("inputKeyboardLayout", function () {
112068         return false;
112069     });
112070     this.__defineGetter__("wifi", function () {
112071         return true;
112072     });
112073     this.__defineGetter__("wifiDirect", function () {
112074         return true;
112075     });
112076     this.__defineGetter__("opengles", function () {
112077         return false;
112078     });
112079     this.__defineGetter__("openglestextureFormat", function () {
112080         return "";
112081     });
112082     this.__defineGetter__("openglesVersion1_1", function () {
112083         return false;
112084     });
112085     this.__defineGetter__("openglesVersion2_0", function () {
112086         return false;
112087     });
112088     this.__defineGetter__("fmRadio", function () {
112089         return false;
112090     });
112091     this.__defineGetter__("platformVersion", function () {
112092         if (!_security.platformVersion) {
112093             throw new WebAPIException(errorcode.SECURITY_ERR);
112094         }
112095         return "2.2.0";
112096     });
112097     this.__defineGetter__("webApiVersion", function () {
112098         if (!_security.webApiVersion) {
112099             throw new WebAPIException(errorcode.SECURITY_ERR);
112100         }
112101         return "2.2";
112102     });
112103     this.__defineGetter__("nativeApiVersion", function () {
112104         if (!_security.nativeApiVersion) {
112105             throw new WebAPIException(errorcode.SECURITY_ERR);
112106         }
112107         return "2.2";
112108     });
112109     this.__defineGetter__("platformName", function () {
112110         return "Tizen";
112111     });
112112     this.__defineGetter__("camera", function () {
112113         return false;
112114     });
112115     this.__defineGetter__("cameraFront", function () {
112116         return false;
112117     });
112118     this.__defineGetter__("cameraFrontFlash", function () {
112119         return false;
112120     });
112121     this.__defineGetter__("cameraBack", function () {
112122         return false;
112123     });
112124     this.__defineGetter__("cameraBackFlash", function () {
112125         return false;
112126     });
112127     this.__defineGetter__("location", function () {
112128         return true;
112129     });
112130     this.__defineGetter__("locationGps", function () {
112131         return true;
112132     });
112133     this.__defineGetter__("locationWps", function () {
112134         return false;
112135     });
112136     this.__defineGetter__("microphone", function () {
112137         return false;
112138     });
112139     this.__defineGetter__("usbHost", function () {
112140         return true;
112141     });
112142     this.__defineGetter__("usbAccessory", function () {
112143         return false;
112144     });
112145     this.__defineGetter__("screenOutputRca", function () {
112146         return false;
112147     });
112148     this.__defineGetter__("screenOutputHdmi", function () {
112149         return false;
112150     });
112151     this.__defineGetter__("platformCoreCpuArch", function () {
112152         return "x86";
112153     });
112154     this.__defineGetter__("platformCoreFpuArch", function () {
112155         return "ssse3";
112156     });
112157     this.__defineGetter__("sipVoip", function () {
112158         return false;
112159     });
112160     this.__defineGetter__("duid", function () {
112161         return "device unique ID";
112162     });
112163     this.__defineGetter__("speechRecognition", function () {
112164         return false;
112165     });
112166     this.__defineGetter__("speechSynthesis", function () {
112167         return false;
112168     });
112169     this.__defineGetter__("accelerometer", function () {
112170         return true;
112171     });
112172     this.__defineGetter__("accelerometerWakeup", function () {
112173         return false;
112174     });
112175     this.__defineGetter__("barometer", function () {
112176         return false;
112177     });
112178     this.__defineGetter__("barometerWakeup", function () {
112179         return false;
112180     });
112181     this.__defineGetter__("gyroscope", function () {
112182         return true;
112183     });
112184     this.__defineGetter__("gyroscopeWakeup", function () {
112185         return false;
112186     });
112187     this.__defineGetter__("magnetometer", function () {
112188         return false;
112189     });
112190     this.__defineGetter__("magnetometerWakeup", function () {
112191         return false;
112192     });
112193     this.__defineGetter__("photometer", function () {
112194         return false;
112195     });
112196     this.__defineGetter__("photometerWakeup", function () {
112197         return false;
112198     });
112199     this.__defineGetter__("proximity", function () {
112200         return false;
112201     });
112202     this.__defineGetter__("proximityWakeup", function () {
112203         return false;
112204     });
112205     this.__defineGetter__("tiltmeter", function () {
112206         return false;
112207     });
112208     this.__defineGetter__("tiltmeterWakeup", function () {
112209         return false;
112210     });
112211     this.__defineGetter__("dataEncryption", function () {
112212         return false;
112213     });
112214     this.__defineGetter__("graphicsAcceleration", function () {
112215         return false;
112216     });
112217     this.__defineGetter__("push", function () {
112218         return true;
112219     });
112220     this.__defineGetter__("telephony", function () {
112221         return true;
112222     });
112223     this.__defineGetter__("telephonyMms", function () {
112224         return true;
112225     });
112226     this.__defineGetter__("telephonySms", function () {
112227         return true;
112228     });
112229     this.__defineGetter__("screenSizeNormal", function () {
112230         return true;
112231     });
112232     this.__defineGetter__("screenSize480_800", function () {
112233         return true;
112234     });
112235     this.__defineGetter__("screenSize720_1280", function () {
112236         return true;
112237     });
112238     this.__defineGetter__("autoRotation", function () {
112239         return true;
112240     });
112241     this.__defineGetter__("shellAppWidget", function () {
112242         return false;
112243     });
112244     this.__defineGetter__("visionImageRecognition", function () {
112245         return false;
112246     });
112247     this.__defineGetter__("visionQrcodeGeneration", function () {
112248         return false;
112249     });
112250     this.__defineGetter__("visionQrcodeRecognition", function () {
112251         return false;
112252     });
112253     this.__defineGetter__("visionFaceRecognition", function () {
112254         return false;
112255     });
112256     this.__defineGetter__("secureElement", function () {
112257         return false;
112258     });
112259     this.__defineGetter__("nativeOspCompatible", function () {
112260         return false;
112261     });
112262     this.__defineGetter__("profile", function () {
112263         return "MOBILE_WEB";
112264     });
112265 };
112266
112267 module.exports = _self;
112268
112269 });
112270 define('ripple/platform/tizen/2.0/systemsetting', function (require, exports, module) {
112271 /*
112272  *  Copyright 2013 Intel Corporation.
112273  *
112274  * Licensed under the Apache License, Version 2.0 (the "License");
112275  * you may not use this file except in compliance with the License.
112276  * You may obtain a copy of the License at
112277  *
112278  * http://www.apache.org/licenses/LICENSE-2.0
112279  *
112280  * Unless required by applicable law or agreed to in writing, software
112281  * distributed under the License is distributed on an "AS IS" BASIS,
112282  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
112283  * See the License for the specific language governing permissions and
112284  * limitations under the License.
112285  */
112286
112287 var db = require('ripple/db'),
112288     event = require('ripple/event'),
112289     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
112290     t = require('ripple/platform/tizen/2.0/typecast'),
112291     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
112292     _systemSettings = null,
112293     DBSYSTEMSETTING_KEY = "tizen2-systemsetting",
112294     _security = {
112295         "http://tizen.org/privilege/setting": ["setProperty"]
112296     },
112297     _self;
112298
112299 function _initialize() {
112300     _systemSettings = db.retrieveObject(DBSYSTEMSETTING_KEY);
112301     if (!_systemSettings) {
112302         _systemSettings = {"HOME_SCREEN": "images/home_screen.jpg", "LOCK_SCREEN": "images/lock_screen.jpg", "INCOMING_CALL": "sounds/incoming.wav", "NOTIFICATION_EMAIL": "sounds/notification.wav"};
112303         db.saveObject(DBSYSTEMSETTING_KEY, _systemSettings);
112304         event.trigger("SystemSettingChanged");
112305     }
112306 }
112307
112308 _self = function () {
112309     var systemSetting;
112310
112311     function setProperty(type, value, successCallback, errorCallback) {
112312         if (!_security.setProperty) {
112313             throw new WebAPIException(errorcode.SECURITY_ERR);
112314         }
112315
112316         t.SystemSettingManager("setProperty", arguments);
112317
112318         _systemSettings = db.retrieveObject(DBSYSTEMSETTING_KEY);
112319         _systemSettings[type] = value;
112320         db.saveObject(DBSYSTEMSETTING_KEY, _systemSettings);
112321         event.trigger("SystemSettingChanged");
112322         window.setTimeout(function () {
112323             successCallback();
112324         }, 1);
112325     }
112326
112327     function getProperty(type, successCallback, errorCallback) {
112328         t.SystemSettingManager("getProperty", arguments);
112329
112330         _systemSettings = db.retrieveObject(DBSYSTEMSETTING_KEY);
112331         window.setTimeout(function () {
112332             successCallback(_systemSettings[type]);
112333         }, 1);
112334     }
112335
112336     function handleSubFeatures(subFeatures) {
112337         var i, subFeature;
112338
112339         for (subFeature in subFeatures) {
112340             for (i in _security[subFeature]) {
112341                 _security[_security[subFeature][i]] = true;
112342             }
112343         }
112344     }
112345
112346     systemSetting = {
112347         setProperty:       setProperty,
112348         getProperty:       getProperty,
112349         handleSubFeatures: handleSubFeatures
112350     };
112351
112352     return systemSetting;
112353 };
112354
112355 _initialize();
112356
112357 module.exports = _self;
112358
112359 });
112360 define('ripple/platform/tizen/2.0/time', function (require, exports, module) {
112361 /*
112362  *  Copyright 2012 Intel Corporation.
112363  *
112364  * Licensed under the Apache License, Version 2.0 (the "License");
112365  * you may not use this file except in compliance with the License.
112366  * You may obtain a copy of the License at
112367  *
112368  * http://www.apache.org/licenses/LICENSE-2.0
112369  *
112370  * Unless required by applicable law or agreed to in writing, software
112371  * distributed under the License is distributed on an "AS IS" BASIS,
112372  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
112373  * See the License for the specific language governing permissions and
112374  * limitations under the License.
112375  */
112376
112377 var t = require('ripple/platform/tizen/2.0/typecast'),
112378     TZDate = require('ripple/platform/tizen/2.0/TZDate'),
112379     db = require('ripple/db'),
112380     tz = require('ripple/platform/tizen/2.0/timezone_info'),
112381     _timeFormat = "h:m:s ap", _shortDateFormat = "d/m/y",
112382     _longDateFormat = "D, M d, y", _self;
112383
112384 _self = {
112385     getCurrentDateTime: function () {
112386         t.TimeUtil("getCurrentDateTime", arguments);
112387         return new TZDate();
112388     },
112389     getLocalTimezone: function () {
112390         t.TimeUtil("getLocalTimezone", arguments);
112391         var localtz = db.retrieve("tizen-timezone") || "UTC";
112392         return localtz;
112393     },
112394     getAvailableTimezones: function () {
112395         t.TimeUtil("getAvailableTimezones", arguments);
112396         var ret = tz.getAllTimezone();
112397         return ret;
112398     },
112399     getDateFormat: function (shortformat) {
112400         t.TimeUtil("getDateFormat", arguments);
112401
112402         if (shortformat) {
112403             return _shortDateFormat;
112404         } else {
112405             return _longDateFormat;
112406         }
112407     },
112408     getTimeFormat: function () {
112409         t.TimeUtil("getTimeFormat", arguments);
112410         return _timeFormat;
112411     },
112412     isLeapYear: function (year) {
112413         t.TimeUtil("isLeapYear", arguments);
112414         return ((year % 4 === 0) && (year % 100 !== 0 || year % 400 === 0));
112415     }
112416 };
112417
112418 module.exports = _self;
112419
112420 });
112421 define('ripple/platform/tizen/2.0/timezone_info', function (require, exports, module) {
112422 /*
112423  *  Copyright 2012 Intel Corporation.
112424  *
112425  * Licensed under the Apache License, Version 2.0 (the "License");
112426  * you may not use this file except in compliance with the License.
112427  * You may obtain a copy of the License at
112428  *
112429  * http://www.apache.org/licenses/LICENSE-2.0
112430  *
112431  * Unless required by applicable law or agreed to in writing, software
112432  * distributed under the License is distributed on an "AS IS" BASIS,
112433  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
112434  * See the License for the specific language governing permissions and
112435  * limitations under the License.
112436  */
112437
112438 var _timezone_data = {
112439     "UTC": {diff: 0, abbr: "UTC"},
112440     "Africa/Cairo": {diff: 2, abbr: "EET"},
112441     "Africa/Casablanca": {diff: 0, abbr: "UTC"},
112442     "Africa/Dakar": {diff: 0, abbr: "UTC"},
112443     "Africa/Freetown": {diff: 0, abbr: "UTC"},
112444     "Africa/Johannesburg": {diff: 2, abbr: "SAST"},
112445     "Africa/Luanda": {diff: 1, abbr: "WAT"},
112446     "America/Anchorage": {diff: -9, abbr: "AKDT"},
112447     "America/Antigua": {diff: -4, abbr: "AST"},
112448     "America/Aruba": {diff: -4, abbr: "AST"},
112449     "America/Barbados": {diff: -4, abbr: "AST"},
112450     "America/Belize": {diff: -6, abbr: "CST"},
112451     "America/Bogota": {diff: -5, abbr: "COT"},
112452     "America/Buenos_Aires": {diff: -3, abbr: "ART"},
112453     "America/Cancun": {diff: -6, abbr: "CDT"},
112454     "America/Cayenne": {diff: -3, abbr: "GFT"},
112455     "America/Cayman": {diff: -5, abbr: "EST"},
112456     "America/Chicago": {diff: -6, abbr: "CST"},
112457     "America/Chihuahua": {diff: -7, abbr: "MST"},
112458     "America/Costa_Rica": {diff: -6, abbr: "CST"},
112459     "America/Denver": {diff: -7, abbr: "MST"},
112460     "America/Detroit": {diff: -5, abbr: "EST"},
112461     "America/Dominica": {diff: -4, abbr: "AST"},
112462     "America/Edmonton": {diff: -7, abbr: "MST"},
112463     "America/El_Salvador": {diff: -6, abbr: "CST"},
112464     "America/Guatemala": {diff: -6, abbr: "CST"},
112465     "America/Havana": {diff: -5, abbr: "CST"},
112466     "America/Indianapolis": {diff: -5, abbr: "EST"},
112467     "America/Jamaica": {diff: -5, abbr: "EST"},
112468     "America/Lima": {diff: -5, abbr: "PET"},
112469     "America/Los_Angeles": {diff: -8, abbr: "PST"},
112470     "America/Louisville": {diff: -5, abbr: "EST"},
112471     "America/Mexico_City": {diff: -6, abbr: "CST"},
112472     "America/Montevideo": {diff: -2, abbr: "UYST"},
112473     "America/Montreal": {diff: -5, abbr: "EST"},
112474     "America/New_York": {diff: -5, abbr: "EST"},
112475     "America/Panama": {diff: -5, abbr: "EST"},
112476     "America/Phoenix": {diff: -7, abbr: "MST"},
112477     "America/Puerto_Rico": {diff: -4, abbr: "AST"},
112478     "America/Santiago": {diff: -3, abbr: "CLST"},
112479     "America/Santo_Domingo": {diff: -4, abbr: "AST"},
112480     "America/Sao_Paulo": {diff: -4, abbr: "AST"},
112481     "America/Tijuana": {diff: -8, abbr: "PST"},
112482     "America/Vancouver": {diff: -8, abbr: "PST"},
112483     "America/Winnipeg": {diff: -6, abbr: "CST"},
112484     "Antarctica/South_Pole": {diff: 13, abbr: "NZDT"},
112485     "Arctic/Longyearbyen": {diff: 13, abbr: "CET"},
112486     "Asia/Amman": {diff: 2, abbr: "EET"},
112487     "Asia/Baghdad": {diff: 3, abbr: "AST"},
112488     "Asia/Bahrain": {diff: 3, abbr: "AST"},
112489     "Asia/Bangkok": {diff: 7, abbr: "ICT"},
112490     "Asia/Beirut": {diff: 2, abbr: "EET"},
112491     "Asia/Chungking": {diff: 8, abbr: "CST"},
112492     "Asia/Dubai": {diff: 4, abbr: "GST", desc:"GMT+0400 United Arab Emirates Time"},
112493     "Asia/Harbin": {diff: 8, abbr: "CST"},
112494     "Asia/Ho_Chi_Minh": {diff: 7, abbr: "IST"},
112495     "Asia/Hong_Kong": {diff: 8, abbr: "HKT"},
112496     "Asia/Istanbul": {diff: 2, abbr: "EET"},
112497     "Asia/Jakarta": {diff: 7, abbr: "WIT"},
112498     "Asia/Jerusalem": {diff: 2, abbr: "IST"},
112499     "Asia/Karachi": {diff: 5, abbr: "PKT"},
112500     "Asia/Kuala_Lumpur": {diff: 8, abbr: "MYT"},
112501     "Asia/Kuwait": {diff: 3, abbr: "AST"},
112502     "Asia/Macao": {diff: 8, abbr: "CST"},
112503     "Asia/Manila": {diff: 8, abbr: "PHT"},
112504     "Asia/Pyongyang": {diff: 9, abbr: "KST"},
112505     "Asia/Qatar": {diff: 3, abbr: "AST"},
112506     "Asia/Saigon": {diff: 7, abbr: "ICT"},
112507     "Asia/Seoul": {diff: 9, abbr: "KST", desc:"GMT+0900 South Korea Time"},
112508     "Asia/Shanghai": {diff: 8, abbr: "CST"},
112509     "Asia/Singapore": {diff: 8, abbr: "SGT"},
112510     "Asia/Taipei": {diff: 8, abbr: "CST"},
112511     "Asia/Tel_Aviv": {diff: 2, abbr: "IST"},
112512     "Asia/Tokyo": {diff: 9, abbr: "JST"},
112513     "Asia/Urumqi": {diff: 8, abbr: "CST"},
112514     "Atlantic/Bermuda": {diff: -4, abbr: "AST"},
112515     "Atlantic/Canary": {diff: 0, abbr: "WET"},
112516     "Atlantic/Cape_Verde": {diff: -1, abbr: "CVT"},
112517     "Atlantic/Reykjavik": {diff: 0, abbr: "GMT"},
112518     "Australia/Brisbane": {diff: 10, abbr: "EST"},
112519     "Australia/Canberra": {diff: 11, abbr: "EST"},
112520     "Australia/Darwin": {diff: 9.5, abbr: "CST"},
112521     "Australia/Melbourne": {diff: 11, abbr: "EST"},
112522     "Australia/North": {diff: 9.5, abbr: "CST"},
112523     "Australia/Perth": {diff: 8, abbr: "WST"},
112524     "Australia/Queensland": {diff: 10, abbr: "EST"},
112525     "Australia/South": {diff: 10.5, abbr: "CST"},
112526     "Australia/Sydney": {diff: 11, abbr: "EST"},
112527     "Australia/West": {diff: 8, abbr: "WST"},
112528     "Australia/Victoria": {diff: 11, abbr: "EST"},
112529     "Europe/Amsterdam": {diff: 1, abbr: "CET"},
112530     "Europe/Athens": {diff: 2, abbr: "EET"},
112531     "Europe/Belgrade": {diff: 1, abbr: "CET"},
112532     "Europe/Berlin": {diff: 1, abbr: "CET"},
112533     "Europe/Brussels": {diff: 1, abbr: "CET"},
112534     "Europe/Bucharest": {diff: 2, abbr: "EET"},
112535     "Europe/Budapest": {diff: 1, abbr: "CET"},
112536     "Europe/Copenhagen": {diff: 1, abbr: "CET"},
112537     "Europe/Dublin": {diff: 0, abbr: "GMT"},
112538     "Europe/Helsinki": {diff: 2, abbr: "EET"},
112539     "Europe/Istanbul": {diff: 2, abbr: "EET"},
112540     "Europe/Kaliningrad": {diff: 3, abbr: "FET"},
112541     "Europe/Kiev": {diff: 2, abbr: "EET"},
112542     "Europe/Lisbon": {diff: 0, abbr: "WET"},
112543     "Europe/London": {diff: 0, abbr: "GMT"},
112544     "Europe/Luxembourg": {diff: 1, abbr: "CET"},
112545     "Europe/Madrid": {diff: 1, abbr: "CET"},
112546     "Europe/Minsk": {diff: 3, abbr: "FET"},
112547     "Europe/Monaco": {diff: 1, abbr: "CET"},
112548     "Europe/Moscow": {diff: 4, abbr: "MSK"},
112549     "Europe/Oslo": {diff: 1, abbr: "CET"},
112550     "Europe/Paris": {diff: 1, abbr: "CET"},
112551     "Europe/Prague": {diff: 1, abbr: "CET"},
112552     "Europe/Rome": {diff: 1, abbr: "CET"},
112553     "Europe/San_Marino": {diff: 1, abbr: "CET"},
112554     "Europe/Sarajevo": {diff: 1, abbr: "CET"},
112555     "Europe/Stockholm": {diff: 1, abbr: "CET"},
112556     "Europe/Vatican": {diff: 1, abbr: "CET"},
112557     "Europe/Vienna": {diff: 1, abbr: "CET"},
112558     "Europe/Warsaw": {diff: 1, abbr: "CET"},
112559     "Europe/Zurich": {diff: 2, abbr: "EET"},
112560     "Indian/Christmas": {diff: 7, abbr: "CXT"},
112561     "Indian/Maldives": {diff: 5, abbr: "MVT"},
112562     "Pacific/Auckland": {diff: 12, abbr: "NZST"},
112563     "Pacific/Easter": {diff: -6, abbr: "EAST"},
112564     "Pacific/Fiji": {diff: 12, abbr: "FJT"},
112565     "Pacific/Guam": {diff: 10, abbr: "ChST"},
112566     "Pacific/Honolulu": {diff: -10, abbr: "HST"},
112567     "Pacific/Midway": {diff: -11, abbr: "SST"},
112568     "Pacific/Saipan": {diff: 10, abbr: "ChST"},
112569     "Pacific/Samoa": {diff: -11, abbr: "SST"},
112570     "Pacific/Tahiti": {diff: -10, abbr: "TAHT"},
112571     "UCT": {diff: 0, abbr: "UCT"},
112572     "SST": {diff: 0, abbr: "SST"},
112573     "GMT": {diff: 0, abbr: "GMT"},
112574     "Greenwich": {diff: 0, abbr: "GMT"},
112575     "US/Alaska": {diff: -9, abbr: "AKST"},
112576     "US/Eastern": {diff: -5, abbr: "EST"},
112577     "US/Central": {diff: -6, abbr: "CST"},
112578     "US/Mountain": {diff: -7, abbr: "MST"},
112579     "US/Pacific": {diff: -8, abbr: "PST"},
112580     "Universal": {diff: 0, abbr: "UTC"},
112581     "Zulu": {diff: 0, abbr: "UTC"},
112582     "Etc/GMT": {diff: 0, abbr: "Etc/GMT"},
112583     "Etc/GMT+0": {diff: 0, abbr: "Etc/GMT+0"},
112584     "Etc/GMT+1": {diff: -1, abbr: "Etc/GMT+1"},
112585     "Etc/GMT+10": {diff: -10, abbr: "Etc/GMT+10"},
112586     "Etc/GMT+11": {diff: -11, abbr: "Etc/GMT+11"},
112587     "Etc/GMT+12": {diff: -12, abbr: "Etc/GMT+12"},
112588     "Etc/GMT+2": {diff: -2, abbr: "Etc/GMT+2"},
112589     "Etc/GMT+3": {diff: -3, abbr: "Etc/GMT+3"},
112590     "Etc/GMT+4": {diff: -4, abbr: "Etc/GMT+4"},
112591     "Etc/GMT+5": {diff: -5, abbr: "Etc/GMT+5"},
112592     "Etc/GMT+6": {diff: -6, abbr: "Etc/GMT+6"},
112593     "Etc/GMT+7": {diff: -7, abbr: "Etc/GMT+7"},
112594     "Etc/GMT+8": {diff: -8, abbr: "Etc/GMT+8"},
112595     "Etc/GMT+9": {diff: -9, abbr: "Etc/GMT+9"},
112596     "Etc/GMT-0": {diff: 0, abbr: "Etc/GMT-0"},
112597     "Etc/GMT-1": {diff: 1, abbr: "Etc/GMT-1"},
112598     "Etc/GMT-10": {diff: 10, abbr: "Etc/GMT-10"},
112599     "Etc/GMT-11": {diff: 11, abbr: "Etc/GMT-11"},
112600     "Etc/GMT-12": {diff: 12, abbr: "Etc/GMT-12"},
112601     "Etc/GMT-13": {diff: 13, abbr: "Etc/GMT-13"},
112602     "Etc/GMT-14": {diff: 14, abbr: "Etc/GMT-14"},
112603     "Etc/GMT-2": {diff: 2, abbr: "Etc/GMT-2"},
112604     "Etc/GMT-3": {diff: 3, abbr: "Etc/GMT-3"},
112605     "Etc/GMT-4": {diff: 4, abbr: "Etc/GMT-4"},
112606     "Etc/GMT-5": {diff: 5, abbr: "Etc/GMT-5"},
112607     "Etc/GMT-6": {diff: 6, abbr: "Etc/GMT-6"},
112608     "Etc/GMT-7": {diff: 7, abbr: "Etc/GMT-7"},
112609     "Etc/GMT-8": {diff: 8, abbr: "Etc/GMT-8"},
112610     "Etc/GMT-9": {diff: 9, abbr: "Etc/GMT-9"},
112611     "Etc/GMT0": {diff: 0, abbr: "Etc/GMT0"},
112612     "Etc/Greenwich": {diff: 0, abbr: "GMT"}
112613 };
112614
112615 module.exports = {
112616     getAllTimezone: function () {
112617         var i, ret = [];
112618         for (i in _timezone_data)
112619             ret.push(i);
112620         return ret;
112621     },
112622     getTimezoneDiff: function (zone) {
112623         return _timezone_data[zone].diff;
112624     },
112625     getTimezoneAbbr: function (zone) {
112626         return _timezone_data[zone].abbr;
112627     },
112628     getTimezoneDesc: function (zone) {
112629         if (_timezone_data[zone].desc) {
112630             return _timezone_data[zone].desc;
112631         } else {
112632             return null;
112633         }
112634     },
112635     isValidTimezone: function (zone) {
112636         return (_timezone_data[zone] === undefined) ? false : true;
112637     }
112638 };
112639
112640
112641 });
112642 define('ripple/platform/tizen/2.0/tizen1_utils', function (require, exports, module) {
112643 /*
112644  *  Copyright 2011 Intel Corporation.
112645  *
112646  * Licensed under the Apache License, Version 2.0 (the "License");
112647  * you may not use this file except in compliance with the License.
112648  * You may obtain a copy of the License at
112649  *
112650  * http://www.apache.org/licenses/LICENSE-2.0
112651  *
112652  * Unless required by applicable law or agreed to in writing, software
112653  * distributed under the License is distributed on an "AS IS" BASIS,
112654  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
112655  * See the License for the specific language governing permissions and
112656  * limitations under the License.
112657  */
112658
112659 var self,
112660     utils = require('ripple/utils'),
112661     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
112662     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException');
112663
112664 self = module.exports = {
112665     _wac2_regexSanitize: function (regexString) {
112666         var escapePattern = /([^\\]|^)(%)/g, percentPattern = /\\%/g;
112667         return regexString.replace("^", "\\^")
112668                 .replace("$", "\\$")
112669                 .replace("(", "\\(")
112670                 .replace(")", "\\)")
112671                 .replace("<", "\\<")
112672                 .replace("[", "\\[")
112673                 .replace("{", "\\{")
112674                 .replace(/\\([^%])/, "\\\\$1")    /* don't replace \\% */
112675                 .replace("|", "\\|")
112676                 .replace(">", "\\>")
112677                 .replace(".", "\\.")
112678                 .replace("*", "\\*")
112679                 .replace("+", "\\+")
112680                 .replace("?", "\\?")
112681                 .replace(escapePattern, "$1.*")  /* replace % with .* */
112682                 .replace(percentPattern, "%");   /* strip excape of % */
112683     },
112684
112685     isValidDate: function (d) {
112686         if (Object.prototype.toString.call(d) !== "[object Date]")
112687             return false;
112688         return !isNaN(d.getTime());
112689     },
112690     isValidTZDate: function (d) {
112691         if (d &&  (d instanceof tizen.TZDate)) {
112692             return true;
112693         }
112694         return false;
112695     },
112696     isValidArray: function (a) {
112697         return (Object.prototype.toString.call(a) === "[object Array]");
112698     },
112699
112700     matchOptionArrayString: function (src, attr, pattern) {
112701         /* src.obj[attr] is a StringArray */
112702         var _pattern, re, _stringMatch;
112703         _pattern = this._wac2_regexSanitize(pattern);
112704         re = new RegExp("^" + _pattern + "$", "i");
112705
112706         _stringMatch = function (obj, index) {
112707             if (pattern.search(/^%*$/i) === 0)
112708                 return true;
112709             if (obj[attr] === undefined || obj[attr] === null)
112710                 return false;
112711             return obj[attr].some(function (f) {
112712                 return f.search(re) !== -1;
112713             });
112714         };
112715         return utils.filter(src, _stringMatch);
112716     },
112717
112718     matchAttributeBooleanFilter: function (src, attr, value) {
112719         // only support EXACTLY matchFlag
112720         var _booleanMatch, atr = attr.split(".");
112721
112722         if (atr.length === 2) {
112723             _booleanMatch = function (obj, index) {
112724                 if (!obj[atr[0]])
112725                     return false;
112726
112727                 return (obj[atr[0]][atr[1]] === value);
112728             };
112729         } else {
112730             _booleanMatch = function (obj, index) {
112731                 return (obj[attr] === value);
112732             };
112733         }
112734
112735         return utils.filter(src, _booleanMatch);
112736     },
112737
112738     matchAttributeArrayFilter: function (src, attr, matchFlag, value) {
112739         var _re, _arrayMatch, atr = attr.split("."), _existMatch;
112740
112741         if (atr.length === 2) {
112742             _existMatch = function (obj, index) {
112743                 if (!obj[atr[0]])
112744                     return false;
112745
112746                 return (obj[atr[0]][atr[1]] !== undefined);
112747             };
112748         } else {
112749             _existMatch = function (obj, index) {
112750                 return (obj[attr] !== undefined);
112751             };
112752         }
112753
112754         if (value === undefined || value === null) {
112755             return utils.filter(src, _existMatch);
112756         }
112757
112758         switch (matchFlag)
112759         {
112760         case "EXACTLY":
112761             _re = new RegExp("^" + value + "$");
112762             break;
112763         case "FULLSTRING":
112764             _re = new RegExp("^" + value + "$", "i");
112765             break;
112766         case "CONTAINS":
112767             _re = new RegExp(value, "i");
112768             break;
112769         case "STARTSWITH":
112770             _re = new RegExp("^" + value, "i");
112771             break;
112772         case "ENDSWITH":
112773             _re = new RegExp(value + "$", "i");
112774             break;
112775         case "EXISTS":
112776             return utils.filter(src, _existMatch);
112777         default:
112778             return [];
112779         }
112780
112781         if (atr.length === 2) {
112782             _arrayMatch = function (obj, index) {
112783                 if (!obj[atr[0]])
112784                     return false;
112785
112786                 return (obj[atr[0]][atr[1]] && obj[atr[0]][atr[1]].some(function (o) {
112787                     return (o.search(_re) !== -1);
112788                 }));
112789             };
112790         } else {
112791             _arrayMatch = function (obj, index) {
112792                 return (obj[attr] && obj[attr].some(function (o) {
112793                     return (o.search(_re) !== -1);
112794                 }));
112795             };
112796         }
112797
112798         return utils.filter(src, _arrayMatch);
112799     },
112800
112801     matchAttributeRangeFilter: function (src, attr, low, high) {
112802         var _rangeMatch, atr = attr.split(".");
112803
112804         if (atr.length === 2) {
112805             _rangeMatch = function (obj, index) {
112806                 var matched = true;
112807
112808                 if (!obj[atr[0]])
112809                     return false;
112810
112811                 if (low !== null && low !== undefined) {
112812                     matched = (obj[atr[0]][atr[1]] >= low);
112813                 }
112814                 if (matched && (high !== null && high !== undefined)) {
112815                     matched = (obj[atr[0]][atr[1]] <= high);
112816                 }
112817                 return matched;
112818             };
112819         } else {
112820             _rangeMatch = function (obj, index) {
112821                 var matched = true;
112822
112823                 if (low !== null && low !== undefined) {
112824                     matched = (obj[attr] >= low);
112825                 }
112826                 if (matched && (high !== null && high !== undefined)) {
112827                     matched = (obj[attr] <= high);
112828                 }
112829                 return matched;
112830             };
112831         }
112832         return utils.filter(src, _rangeMatch);
112833     },
112834
112835     matchAttributeFilter: function (src, attr, matchFlag, value) {
112836         var _re, _stringMatch, atr = attr.split("."),
112837             _existMatch;
112838
112839         if (atr.length === 2) {
112840             _existMatch = function (obj, index) {
112841                 if (!obj[atr[0]])
112842                     return false;
112843
112844                 return (obj[atr[0]][atr[1]] !== undefined);
112845             };
112846         } else {
112847             _existMatch = function (obj, index) {
112848                 return (obj[attr] !== undefined);
112849             };
112850         }
112851
112852         if (value === undefined || value === null) {
112853             return utils.filter(src, _existMatch);
112854         }
112855
112856         switch (matchFlag)
112857         {
112858         case "EXACTLY":
112859             _re = new RegExp("^" + value + "$");
112860             break;
112861         case "FULLSTRING":
112862             _re = new RegExp("^" + value + "$", "i");
112863             break;
112864         case "CONTAINS":
112865             _re = new RegExp(value, "i");
112866             break;
112867         case "STARTSWITH":
112868             _re = new RegExp("^" + value, "i");
112869             break;
112870         case "ENDSWITH":
112871             _re = new RegExp(value + "$", "i");
112872             break;
112873         case "EXISTS":
112874             return utils.filter(src, _existMatch);
112875         default:
112876             return [];
112877         }
112878         if (atr.length === 2) {
112879             _stringMatch = function (obj, index) {
112880                 if (!obj[atr[0]])
112881                     return false;
112882
112883                 if (matchFlag === "EXACTLY") {
112884                     return (obj[atr[0]][atr[1]] === value);
112885                 } else if (typeof obj[atr[0]][atr[1]] !== 'string') {
112886                     return false;
112887                 }
112888
112889                 return (obj[atr[0]][atr[1]].search(_re) !== -1);
112890             };
112891         } else {
112892             _stringMatch = function (obj, index) {
112893                 if (matchFlag === "EXACTLY") {
112894                     return (obj[attr] === value);
112895                 } else if (typeof obj[attr] !== 'string') {
112896                     return false;
112897                 }
112898
112899                 return (obj[attr].search(_re) !== -1);
112900             };
112901         }
112902         return utils.filter(src, _stringMatch);
112903     },
112904
112905     matchOptionString: function (src, attr, pattern) {
112906         /* src.obj[attr] is a string */
112907         var _stringMatch, _pattern, _re;
112908         _pattern = this._wac2_regexSanitize(pattern);
112909         _re = new RegExp("^" + _pattern + "$", "mi");
112910
112911         _stringMatch = function (obj, index) {
112912             return (obj[attr].search(_re) !== -1);
112913         };
112914         return utils.filter(src, _stringMatch);
112915     },
112916
112917     matchOptionDate: function (src, attr, filterStart, filterEnd) {
112918         var _dateMatch;
112919         _dateMatch = function (obj, index) {
112920             var matched = true, valueDate = obj[attr];
112921
112922             if (filterStart !== undefined && filterStart !== null) {
112923                 matched = (valueDate.getTime() >= filterStart.getTime());
112924             }
112925             if (matched && (filterEnd !== undefined && filterEnd !== null)) {
112926                 matched = (valueDate.getTime() <= filterEnd.getTime());
112927             }
112928             return matched;
112929         };
112930         return utils.filter(src, _dateMatch);
112931     },
112932
112933     matchOptionShortArray: function (src, attr, filterArray) {
112934         /* src.obj[attr] is a short, filterArray is an array
112935            i.e. find status is [CONFRIMED or TENTATIVE] */
112936         var arraySome = function (obj, index) {
112937             return filterArray.some(function (f) {
112938                 return f === obj[attr];
112939             });
112940         };
112941         return utils.filter(src, arraySome);
112942     },
112943
112944     validateArgumentType: function (arg, argType, errorObj) {
112945         var invalidArg = false;
112946
112947         switch (argType) {
112948         case "array":
112949             if (!arg instanceof Array) {
112950                 invalidArg = true;
112951             }
112952             break;
112953         case "date":
112954             if (!arg instanceof Date) {
112955                 invalidArg = true;
112956             }
112957             break;
112958         case "integer":
112959             if (typeof Number(arg) !== "number" || Number(arg) !== Math.floor(arg)) {
112960                 invalidArg = true;
112961             }
112962             break;
112963         default:
112964             if (typeof arg !== argType) {
112965                 invalidArg = true;
112966             }
112967             break;
112968         }
112969
112970         if (invalidArg) {
112971             throw errorObj;
112972         }
112973     },
112974
112975     validateCallbackType: function (successCallback, errorCallback) {
112976         if (successCallback) {
112977             this.validateArgumentType(successCallback, "function",
112978                 new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
112979         }
112980         if (errorCallback) {
112981             this.validateArgumentType(errorCallback, "function",
112982                 new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
112983         }
112984     },
112985
112986     validateEqualArrays: function (arrayOne, arrayTwo) {
112987         var isEqual = false, i;
112988
112989         if (Object.prototype.toString.call(arrayTwo) === "[object Array]" &&
112990             Object.prototype.toString.call(arrayTwo) === "[object Array]" &&
112991             arrayOne.length === arrayTwo.length) {
112992             isEqual = true;
112993             for (i in arrayOne) {
112994                 if (arrayOne[i] !== arrayTwo[i]) {
112995                     isEqual = false;
112996                     break;
112997                 }
112998             }
112999         }
113000         return isEqual;
113001     },
113002
113003     validateTypeMismatch: function (onSuccess, onError, name, callback) {
113004
113005         if (onSuccess === undefined || onSuccess === null) {
113006             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
113007         }
113008         this.validateArgumentType(onSuccess, "function",
113009                                   new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
113010         if (onError !== null && onError !== undefined) {
113011             this.validateArgumentType(onError, "function",
113012                                       new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
113013         }
113014
113015         return callback && callback();
113016     },
113017
113018     isEmptyObject: function (obj) {
113019         var prop;
113020
113021         for (prop in obj) {
113022             return false;
113023         }
113024         return true;
113025     },
113026
113027     arrayComposite: function (mode, arrayA, arrayB) {
113028         var combinedArray = arrayA.concat(arrayB),
113029             intersectionArray = arrayA.filter(function (value) {
113030                 if (utils.arrayContains(arrayB, value)) {
113031                     return true;
113032                 }
113033
113034                 return false;
113035             });
113036
113037         switch (mode) {
113038         case "AND":
113039         case "INTERSECTION":
113040             return intersectionArray;
113041         case "OR":
113042         case "UNION":
113043             return intersectionArray.concat(combinedArray.filter(function (value) {
113044                 if (utils.arrayContains(intersectionArray, value)) {
113045                     return false;
113046                 }
113047
113048                 return true;
113049             }));
113050         default:
113051             return undefined;
113052         }
113053     },
113054
113055     isEqual: function (srcObj, aimObj) {
113056         var i;
113057
113058         if (typeof srcObj !== typeof aimObj) {
113059             return false;
113060         }
113061
113062         if (srcObj === null || srcObj === undefined || typeof srcObj === 'number' ||
113063             typeof srcObj === 'string' || typeof srcObj === 'boolean') {
113064             return srcObj === aimObj;
113065         }
113066
113067         for (i in srcObj) {
113068             if (!aimObj.hasOwnProperty(i) || !self.isEqual(srcObj[i], aimObj[i])) {
113069                 return false;
113070             }
113071         }
113072
113073         return true;
113074     },
113075
113076     query: function (objects, filter, sortMode, count, offset) {
113077         function isCompositeFilter(filter) {
113078             return (filter.type) ? true : false;
113079         }
113080
113081         function isAttributeFilter(filter) {
113082             return (filter.matchFlag) ? true : false;
113083         }
113084
113085         function getValue(obj, key) {
113086             var keys = key.split("."),
113087                 value = obj[keys[0]],
113088                 i;
113089
113090             for (i = 1; i < keys.length; i++) {
113091                 if (value[keys[i]]) {
113092                     value = value[keys[i]];
113093                 }
113094             }
113095
113096             return value;
113097         }
113098
113099         function _filter(objects, filter) {
113100             var i, results, eachResult, filterFunc;
113101
113102             if (isCompositeFilter(filter)) {
113103                 for (i in filter.filters) {
113104                     eachResult = _filter(objects, filter.filters[i]);
113105                     results = (results === undefined) ? eachResult : self.arrayComposite(filter.type, results, eachResult);
113106                 }
113107                 return results;
113108             }
113109
113110             if (isAttributeFilter(filter)) {
113111                 for (i in objects) {
113112                     if (filter.attributeName in objects[i])
113113                         break;
113114                 }
113115                 filterFunc = self.isValidArray(objects[i][filter.attributeName]) ? self.matchAttributeArrayFilter : self.matchAttributeFilter;
113116                 results = filterFunc(objects, filter.attributeName, filter.matchFlag, filter.matchValue);
113117             } else {
113118                 results = self.matchAttributeRangeFilter(objects, filter.attributeName, filter.initialValue, filter.endValue);
113119             }
113120
113121             return results;
113122         }
113123
113124         function _sort(objects, sortMode) {
113125             objects.sort(function (a, b) {
113126                 return (sortMode.order === "ASC") ?
113127                     (getValue(a, sortMode.attributeName) < getValue(b, sortMode.attributeName) ? -1 : 1):
113128                     (getValue(a, sortMode.attributeName) > getValue(b, sortMode.attributeName) ? -1 : 1);
113129             });
113130
113131             return objects;
113132         }
113133
113134         var res = objects;
113135
113136         if (filter) {
113137             res = _filter(res, filter);
113138         }
113139
113140         if (sortMode) {
113141             _sort(res, sortMode);
113142         }
113143
113144         if (offset || count) {
113145             offset = (offset > 0) ? offset : 0;
113146             res = (count > 0) ? res.slice(offset, offset + count) : res.slice(offset);
113147         }
113148
113149         return res;
113150     },
113151
113152     copyString: function (str) {
113153         var newStr, charConvert = [], i;
113154
113155         if (typeof str !== 'string') {
113156             return str;
113157         }
113158         for (i = 0; i < str.length; i++) {
113159             charConvert[i] = str.charAt(i);
113160         }
113161         newStr = charConvert.join("");
113162
113163         return newStr;
113164     },
113165
113166     copy: function (obj) {
113167         var i,
113168             newObj = jQuery.isArray(obj) ? [] : {};
113169
113170         if (typeof obj === 'number' ||
113171             typeof obj === 'string' ||
113172             typeof obj === 'boolean' ||
113173             obj === null ||
113174             obj === undefined) {
113175             return obj;
113176         }
113177
113178         if (obj instanceof Date) {
113179             return new Date(obj);
113180         }
113181
113182         if (obj instanceof RegExp) {
113183             return new RegExp(obj);
113184         }
113185
113186         for (i in obj) {
113187             if (obj.hasOwnProperty(i)) {
113188                 if (obj.__lookupGetter__(i)) {
113189                     newObj.__defineGetter__(i, (function (key) {
113190                         return function () {
113191                             return self.copy(obj[key]);
113192                         };
113193                     }(i)));
113194                 }
113195                 else {
113196                     newObj[i] = self.copy(obj[i]);
113197                 }
113198             }
113199         }
113200
113201         return newObj;
113202     }
113203 };
113204
113205 });
113206 define('ripple/platform/tizen/2.0/touchEvent', function (require, exports, module) {
113207 /*
113208  *  Copyright 2012 Intel Corporation
113209  *
113210  * Licensed under the Apache License, Version 2.0 (the "License");
113211  * you may not use this file except in compliance with the License.
113212  * You may obtain a copy of the License at
113213  *
113214  * http://www.apache.org/licenses/LICENSE-2.0
113215  *
113216  * Unless required by applicable law or agreed to in writing, software
113217  * distributed under the License is distributed on an "AS IS" BASIS,
113218  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113219  * See the License for the specific language governing permissions and
113220  * limitations under the License.
113221  */
113222
113223 var emulatorBridge = require('ripple/emulatorBridge'),
113224     event = require('ripple/event'),
113225     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
113226     Touch,
113227     TouchList,
113228     TouchEvent,
113229     _touchCanvasElements = [],
113230     _dataEnlargeRatio = 4,
113231     _self;
113232
113233 function _isValidTouch(touches) {
113234     var touche, _touches = [], i;
113235     if (!touches) {
113236         return false;
113237     }
113238     if (!tizen1_utils.isValidArray(touches)) {
113239         _touches = [touches];
113240     }
113241
113242     for (i = 0; i < _touches.length; i++) {
113243         touche = _touches[i];
113244         if ((touche !== undefined) &&
113245             ((typeof touche !== "object") ||
113246             (typeof touche.target !== "object") ||
113247             (touche.identifier !== undefined) && (typeof touche.identifier !== "number") ||
113248             (touche.screenX !== undefined) && (typeof touche.screenX !== "number") ||
113249             (touche.screenY !== undefined) && (typeof touche.screenY !== "number") ||
113250             (touche.clientX !== undefined) && (typeof touche.clientX !== "number") ||
113251             (touche.clientY !== undefined) && (typeof touche.clientY !== "number") ||
113252             (touche.pageX !== undefined) && (typeof touche.pageX !== "number") ||
113253             (touche.pageY !== undefined) && (typeof touche.pageY !== "number")))
113254             return false;
113255     }
113256     return true;
113257 }
113258
113259 function _dispatchAllEvents(event) {
113260     _touchCanvasElements.forEach(function (value) {
113261         if (value !== undefined) {
113262             value.dispatchEvent(event);
113263         }
113264     });
113265 }
113266
113267 function _touchMove(event) {
113268     var data = event.data,
113269         touches = [],
113270         removedTouches = [],
113271         touchList,
113272         simulatedEvent,
113273         dataId,
113274         ids = [],
113275         intervalId,
113276         currentIndex,
113277         item = {};
113278
113279     if (_touchCanvasElements.length === 0)
113280         return;
113281
113282     for (dataId in data) {
113283         if (!data[dataId].length || data[dataId].length === 0)
113284             return;
113285
113286         ids.push(dataId);
113287         item = data[dataId][0];
113288         touches.push(new Touch(item.target, dataId, item.pageX * _dataEnlargeRatio, item.pageY * _dataEnlargeRatio, item.screenX * _dataEnlargeRatio,
113289                                item.screenY * _dataEnlargeRatio, item.offsetX * _dataEnlargeRatio, item.offsetY * _dataEnlargeRatio));
113290     }
113291
113292     // touch start
113293     touchList = new TouchList(touches);
113294     simulatedEvent = new TouchEvent("touchstart", true, true, touchList, touchList, touchList, event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
113295     _dispatchAllEvents(simulatedEvent);
113296     currentIndex = 0;
113297
113298     // touch move and touch end
113299     intervalId = setInterval(function () {
113300         touches = [];
113301         removedTouches = [];
113302
113303         ids.forEach(function (id) {
113304             var points = data[id],
113305                 touchItem, removedItem;
113306
113307             if (currentIndex < points.length) {
113308                 touchItem = points[currentIndex];
113309             } else {
113310                 removedItem = points[points.length - 1];
113311             }
113312
113313             if (touchItem)
113314                 touches.push(new Touch(touchItem.target, id, touchItem.pageX * _dataEnlargeRatio, touchItem.pageY * _dataEnlargeRatio, touchItem.screenX * _dataEnlargeRatio,
113315                                        touchItem.screenY * _dataEnlargeRatio, touchItem.offsetX * _dataEnlargeRatio, touchItem.offsetY * _dataEnlargeRatio));
113316             if (removedItem)
113317                 removedTouches.push(new Touch(removedItem.target, id, removedItem.pageX * _dataEnlargeRatio, removedItem.pageY * _dataEnlargeRatio, removedItem.screenX * _dataEnlargeRatio,
113318                                     removedItem.screenY * _dataEnlargeRatio, removedItem.offsetX * _dataEnlargeRatio, removedItem.offsetY * _dataEnlargeRatio));
113319         });
113320
113321         if (touches.length > 0) {
113322             simulatedEvent = new TouchEvent("touchmove", true, true, new TouchList(touches), new TouchList(touches), new TouchList(touches),
113323                 event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
113324             _dispatchAllEvents(simulatedEvent);
113325         } else {
113326             clearInterval(intervalId);
113327         }
113328
113329         if (removedTouches.length > 0) {
113330             simulatedEvent = new TouchEvent("touchend", true, true, new TouchList(removedTouches), new TouchList(removedTouches), new TouchList(removedTouches),
113331                 event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
113332             _dispatchAllEvents(simulatedEvent);
113333         }
113334         currentIndex++;
113335     }, 50);
113336 }
113337
113338 function _touchCancel(event) {
113339     var mousedownEvent = event.touchEvent,
113340         simulatedEvent;
113341
113342     simulatedEvent = new TouchEvent("touchcancel", true, true, new TouchList([]), new TouchList([]), new TouchList([]),
113343         event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
113344     _dispatchAllEvents(simulatedEvent);
113345 }
113346
113347 function _initialize() {
113348     event.on("touchCancel", _touchCancel);
113349     event.on("touchEvent", _touchMove);
113350 }
113351
113352 Touch = function (target, identifier, pageX, pageY, screenX, screenY, clientX, clientY) {
113353     var _identifier = Number(identifier) || 0,
113354         _screenX = Number(screenX) || 0,
113355         _screenY = Number(screenY) || 0,
113356         _clientX = Number(clientX) || 0,
113357         _clientY = Number(clientY) || 0,
113358         _pageX = Number(pageX) || 0,
113359         _pageY = Number(pageY) || 0;
113360
113361     this.__defineGetter__("identifier", function () {
113362         return _identifier;
113363     });
113364     this.__defineGetter__("target", function () {
113365         return target;
113366     });
113367     this.__defineGetter__("screenX", function () {
113368         return _screenX;
113369     });
113370     this.__defineGetter__("screenY", function () {
113371         return _screenY;
113372     });
113373     this.__defineGetter__("clientX", function () {
113374         return _clientX;
113375     });
113376     this.__defineGetter__("clientY", function () {
113377         return _clientY;
113378     });
113379     this.__defineGetter__("pageX", function () {
113380         return _pageX;
113381     });
113382     this.__defineGetter__("pageY", function () {
113383         return _pageY;
113384     });
113385 };
113386
113387 TouchList = function (touches) {
113388     var _touches = _isValidTouch(touches) ? tizen1_utils.copy(touches) : [],
113389         i, _self;
113390
113391     _self = {
113392         item : function (index) {
113393             if (typeof index !== "number") {
113394                 return null;
113395             }
113396             if (index.toString().indexOf(".") !== -1) {
113397                 return null;
113398             }
113399             if (/^\\d+$/.test(index) || index >= _touches.length) {
113400                 return null;
113401             }
113402             if (!_touches) {
113403                 return null;
113404             }
113405             return _touches[index];
113406         },
113407
113408         identifiedTouch : function (identifier) {
113409             if (typeof identifier !== "number") {
113410                 return null;
113411             }
113412             if (!_touches) {
113413                 return null;
113414             }
113415             for (var i in _touches) {
113416                 if (_touches[i].identifier === identifier) {
113417                     return _touches[i];
113418                 }
113419             }
113420             return null;
113421         }
113422     };
113423
113424     for (i = 0; i < _touches.length; i++) {
113425         _self.__defineGetter__(i, (function (index) {
113426             return function () {
113427                 return _touches[index];
113428             };
113429         }(i)));
113430     }
113431
113432     _self.__defineGetter__("length", function () {
113433         return _touches.length;
113434     });
113435
113436     return _self;
113437 };
113438
113439 TouchEvent = function (type, canBubble, cancelable, touches, targetTouches, changedTouches, altKey, metaKey, ctrlKey, shiftKey) {
113440     var touchEvent = emulatorBridge.document().createEvent("UIEvents");
113441     touchEvent.initUIEvent(type, canBubble, cancelable, emulatorBridge.window(), 1);
113442
113443     touchEvent.__defineGetter__("touches", function () {
113444         return touches;
113445     });
113446     touchEvent.__defineGetter__("targetTouches", function () {
113447         return targetTouches;
113448     });
113449     touchEvent.__defineGetter__("changedTouches", function () {
113450         return changedTouches;
113451     });
113452     touchEvent.__defineGetter__("altKey", function () {
113453         return altKey;
113454     });
113455     touchEvent.__defineGetter__("metaKey", function () {
113456         return metaKey;
113457     });
113458     touchEvent.__defineGetter__("ctrlKey", function () {
113459         return ctrlKey;
113460     });
113461     touchEvent.__defineGetter__("shiftKey", function () {
113462         return shiftKey;
113463     });
113464     return touchEvent;
113465 };
113466
113467 _self = {
113468     mask: function (frame) {
113469         frame.addEventListener("DOMContentLoaded", function () {
113470             /*
113471             var widgetDocument = frame.contentDocument,
113472                 getElementByIdOri = widgetDocument.getElementById;
113473
113474             widgetDocument.getElementById = function () {
113475                 var element, addEventListenerOri;
113476
113477                 element = getElementByIdOri.apply(widgetDocument, Array.prototype.slice.call(arguments));
113478
113479                 if (element) {
113480                     addEventListenerOri = element.addEventListener;
113481                     element.addEventListener = function (event, callback, useCapture) {
113482                         if (event === "touchstart") {
113483                             _touchCanvasElements.push(element);
113484                         }
113485                         addEventListenerOri.apply(element, arguments);
113486                     };
113487                 }
113488                 return element;
113489             };
113490
113491             widgetDocument.createTouch = function (view, target, identifier, pageX, pageY, screenX, screenY) {
113492                 return new Touch(view, target, identifier, pageX, pageY, screenX, screenY);
113493             };
113494
113495             widgetDocument.createTouchList = function (pattern) {
113496                 if (arguments.length !== 1) {
113497                     return null;
113498                 }
113499                 return new TouchList(pattern);
113500             };
113501             */
113502         });
113503     }
113504 };
113505
113506 _initialize();
113507
113508 module.exports = _self;
113509
113510 });
113511 define('ripple/platform/tizen/2.0/typecast', function (require, exports, module) {
113512 /*
113513  *  Copyright 2013 Intel Corporation.
113514  *
113515  * Licensed under the Apache License, Version 2.0 (the "License");
113516  * you may not use this file except in compliance with the License.
113517  * You may obtain a copy of the License at
113518  *
113519  * http://www.apache.org/licenses/LICENSE-2.0
113520  *
113521  * Unless required by applicable law or agreed to in writing, software
113522  * distributed under the License is distributed on an "AS IS" BASIS,
113523  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113524  * See the License for the specific language governing permissions and
113525  * limitations under the License.
113526  */
113527
113528 var typedef = require('ripple/platform/tizen/2.0/typedef'),
113529     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
113530     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
113531     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
113532     _self = {};
113533
113534 function _cast(pattern, obj, isDuplicate) {
113535     var tc, tcFunc;
113536
113537     if (pattern === null)
113538         return;
113539
113540     tc = new TypeCoerce(pattern);
113541     tcFunc = isDuplicate ? tc.copy : tc.cast;
113542
113543     if ((obj = tcFunc(obj)) === null) {
113544         throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
113545     }
113546
113547     return obj;
113548 }
113549
113550 function _castType(pattern) {
113551     /*
113552      * Type cast for each known type. The function name is the exact name of the
113553      * corresponding type.
113554      *
113555      * obj
113556      *    Variable to be casted
113557      *
113558      * aux
113559      *    Auxiliary descriptor of obj. It can be any one or combination of below
113560      *    strings, or ignored in most cases.
113561      *
113562      *    "?"     Nullable types
113563      *    "[]"    Array
113564      *    "+"     Deep copy
113565      *
113566      * Return
113567      *    Casted or duplicated object.
113568      */
113569
113570     return function (obj, aux) {
113571         var type, isNullable, isDuplicate;
113572
113573         aux = aux ? String(aux) : "";
113574         type = (aux.indexOf("[]") !== -1) ? [pattern] : pattern;
113575         isNullable = (aux.indexOf("?") !== -1);
113576         isDuplicate = (aux.indexOf("+") !== -1);
113577
113578         if ((obj === null) || (obj === undefined)) {
113579             if (!isNullable) {
113580                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
113581             }
113582             return obj;
113583         }
113584
113585         return _cast(type, obj, isDuplicate);
113586     };
113587 }
113588
113589 function _castConstructor(name) {
113590     var constructors, hook, vtc, isOverloaded, castConstructor;
113591
113592     /*
113593      * Type cast for constructor. The function name is the exact name of the
113594      * object type.
113595      *
113596      * argv
113597      *    arguments. The keyword 'arguments' will always be passed in.
113598      */
113599
113600     function castUnique(argv) {
113601         _cast(constructors, argv, false);
113602     }
113603
113604     /*
113605      * Type cast for overloaded constructors. The function name is the exact
113606      * name of the object type.
113607      *
113608      * argv
113609      *    arguments. The keyword 'arguments' will always be passed in.
113610      *
113611      * scope
113612      *    'this' of the original constructor.
113613      *
113614      * voc
113615      *    Array of overloaded constructors callback
113616      */
113617
113618     function castOverload(argv, scope, voc) {
113619         var iOverload;
113620
113621         if (!vtc) {
113622             vtc = [];
113623             constructors.forEach(function (c) {
113624                 vtc.push((c === null) ? null : new TypeCoerce(c));
113625             });
113626         }
113627
113628         vtc.some(function (tc, index) {
113629             if (tc && (tc.cast(argv) === null))
113630                 return false;
113631
113632             iOverload = index;
113633             return true;
113634         });
113635
113636         if (iOverload === undefined) {
113637             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
113638         }
113639
113640         return (voc && voc[iOverload].apply(scope, argv));
113641     }
113642
113643     constructors = typedef.constructor[name];
113644
113645     if (name in _self) {
113646         hook = _self[name];
113647     }
113648
113649     isOverloaded = (Object.prototype.toString.call(constructors) ===
113650             "[object Array]");
113651     castConstructor = isOverloaded ? castOverload : castUnique;
113652
113653     return function (argv, scope) {
113654         if (Object.prototype.toString.call(argv) !== "[object Arguments]") {
113655             return (hook && hook.apply(this, arguments));
113656         }
113657
113658         if (!(scope instanceof argv.callee)) {
113659             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR, null, "TypeError");
113660         }
113661
113662         castConstructor.apply(this, arguments);
113663     };
113664 }
113665
113666 function _castInterface(name) {
113667     var interface, hook;
113668
113669     interface = typedef.interface[name];
113670
113671     if (name in _self) {
113672         hook = _self[name];
113673     }
113674
113675     /*
113676      * Type cast for each known method of interface. The function name is the
113677      * exact name of the corresponding interface.
113678      *
113679      * method
113680      *    String of method name
113681      *
113682      * argv
113683      *    arguments. The keyword 'arguments' will always be passed in.
113684      *
113685      * isDuplicate
113686      *    A boolean value to indicate whether arguments will be copied or not.
113687      */
113688
113689     return function (method, argv, isDuplicate) {
113690         if ((typeof method !== "string") || (typeof argv !== "object")) {
113691             return (hook && hook.apply(this, arguments));
113692         }
113693
113694         _cast(interface[method], argv, isDuplicate);
113695     };
113696 }
113697
113698 (function () {
113699     var i;
113700
113701     for (i in typedef) {
113702         _self[i] = _castType(typedef[i]);
113703     }
113704
113705     for (i in typedef.constructor) {
113706         _self[i] = _castConstructor(i);
113707         typedef[i]._constructor = i;
113708     }
113709
113710     for (i in typedef.interface) {
113711         _self[i] = _castInterface(i);
113712     }
113713 }());
113714
113715 module.exports = _self;
113716
113717 });
113718 define('ripple/platform/tizen/2.0/typecoerce', function (require, exports, module) {
113719 /*
113720  *  Copyright 2013 Intel Corporation.
113721  *
113722  * Licensed under the Apache License, Version 2.0 (the "License");
113723  * you may not use this file except in compliance with the License.
113724  * You may obtain a copy of the License at
113725  *
113726  * http://www.apache.org/licenses/LICENSE-2.0
113727  *
113728  * Unless required by applicable law or agreed to in writing, software
113729  * distributed under the License is distributed on an "AS IS" BASIS,
113730  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113731  * See the License for the specific language governing permissions and
113732  * limitations under the License.
113733  */
113734
113735 var t = require('ripple/platform/tizen/2.0/typedef'),
113736     _self;
113737
113738 _self = function (pattern) {
113739     var typeCoerce, typeOfPattern;
113740
113741     // private
113742     function getExtendedType(val) {
113743         var type, attr;
113744
113745         if (typeof val === "object") {
113746             if ("_dictionary" in val) {
113747                 return "dictionary";
113748             }
113749
113750             type = "Object";
113751
113752             for (attr in val) {
113753                 if (attr === "0") {
113754                     type = "Arguments";
113755                 } else if (val[attr] === "Callback") {
113756                     type = "Callback";
113757                 }
113758                 break;
113759             }
113760
113761             return type;
113762         }
113763
113764         switch (val) {
113765         case "Callback":
113766             type = "Function";
113767             break;
113768
113769         case "TZDate":
113770         case "any": // Any type
113771         case "byte":
113772         case "octet":
113773         case "unsigned long":
113774         case "unsigned short":
113775             type = val;
113776             break;
113777
113778         case "double":
113779         case "float":
113780             type = "float";
113781             break;
113782
113783         default:    // Derivative type name: e.g., "AbstractFilter"
113784             type = "";
113785             break;
113786         }
113787
113788         return type;
113789     }
113790
113791     function getType(val, isPattern) {
113792         var type = Object.prototype.toString.call(val);
113793
113794         switch (type) {
113795         case "[object Array]":
113796             type = (isPattern && (val.length > 1) &&
113797                 (typeof val[0] === "string")) ? "enum" : "Array";
113798             break;
113799
113800         case "[object Arguments]":
113801             type = "Arguments";
113802             break;
113803
113804         case "[object Boolean]":
113805             type = "boolean";
113806             break;
113807
113808         case "[object Date]":
113809             type = "Date";
113810             break;
113811
113812         case "[object Function]":
113813             type = "Function";
113814             break;
113815
113816         case "[object Number]":
113817             type = "Number";
113818             break;
113819
113820         case "[object Object]":
113821             type = isPattern ? getExtendedType(val) : "Object";
113822             break;
113823
113824         case "[object String]":
113825             type = (isPattern && !!val) ? getExtendedType(val) : "DOMString";
113826             break;
113827         }
113828
113829         return type;
113830     }
113831
113832     function instanceOfPattern(pattern, obj) {
113833         var ret, i, derived;
113834
113835         if ("_constructor" in pattern) {
113836             if (obj instanceof window.tizen[pattern._constructor]) {
113837                 return -1;
113838             }
113839             ret = NaN;
113840         } else {
113841             ret = -1;
113842         }
113843
113844         if (!("_derived" in pattern)) {
113845             return ret;
113846         }
113847
113848         for (i in pattern._derived) {
113849             derived = pattern._derived[i];
113850
113851             if (typeof derived !== "object") {
113852                 return (typeof derived === typeof obj) ? i : NaN;
113853             }
113854             if (!isNaN(instanceOfPattern(derived, obj))) {
113855                 return i;
113856             }
113857         }
113858
113859         return NaN;
113860     }
113861
113862     function toInteger(x) {
113863         return (x < 0) ? Math.ceil(x) : Math.floor(x);
113864     }
113865
113866     function modulo(a, b) {
113867         return a - Math.floor(a / b) * b;
113868     }
113869
113870     function toUInt(x, bits) {
113871         x = Number(x);
113872
113873         if (isNaN(x) || !isFinite(x))
113874             return null;
113875
113876         return modulo(toInteger(x), Math.pow(2, bits));
113877     }
113878
113879     function toUInt16(x) {
113880         return toUInt(x, 16);
113881     }
113882
113883     function toUInt32(x) {
113884         return toUInt(x, 32);
113885     }
113886
113887     // public
113888     function cast(obj) {
113889         var typeMap,
113890             typeOfObj = getType(obj, false);
113891
113892         typeMap = {
113893             "Arguments": function () {
113894                 var i, isNullable, ret;
113895
113896                 for (i in pattern) {
113897                     if (i === "_optional")
113898                         continue;
113899
113900                     isNullable = !!(pattern._optional && pattern._optional[i]);
113901
113902                     if (i > obj.length - 1) {
113903                         if (!isNullable) {
113904                             return null;
113905                         }
113906                         obj[i] = null;
113907                         continue;
113908                     }
113909
113910                     if ((obj[i] === null) || (obj[i] === undefined)) {
113911                         if (!isNullable || ((i in obj) && (obj[i] !== null))) {
113912                             return null;
113913                         }
113914                     } else {
113915                         ret = _self(pattern[i]).cast(obj[i]);
113916                         if (ret === null) {
113917                             return null;
113918                         }
113919                         obj[i] = ret;
113920                     }
113921                 }
113922
113923                 return obj;
113924             },
113925
113926             "Array": function () {
113927                 var elementType, i, ret;
113928
113929                 if (typeOfObj !== typeOfPattern) {
113930                     return null;
113931                 }
113932
113933                 elementType = _self(pattern[0]);
113934                 for (i in obj) {
113935                     ret = elementType.cast(obj[i]);
113936                     if (ret === null) {
113937                         return null;
113938                     }
113939                     obj[i] = ret;
113940                 }
113941
113942                 return obj;
113943             },
113944
113945             "Callback": function () {
113946                 var attr;
113947
113948                 if (typeOfObj !== "Object") {
113949                     return null;
113950                 }
113951
113952                 for (attr in pattern) {
113953                     if (attr in obj) {
113954                         obj[attr] = _self(pattern[attr]).cast(obj[attr]);
113955                         if (obj[attr] === null) {
113956                             return null;
113957                         }
113958                     }
113959                 }
113960
113961                 return obj;
113962             },
113963
113964             "DOMString": function () {
113965                 switch (typeOfObj) {
113966                 case "Date":
113967                 case "DOMString":
113968                 case "Number":
113969                     obj = String(obj).trim();
113970                     break;
113971
113972                 default:
113973                     obj = null;
113974                     break;
113975                 }
113976
113977                 return obj;
113978             },
113979
113980             "Date": function () {
113981                 return (typeOfObj === typeOfPattern) ? obj : null;
113982             },
113983
113984             "Function": function () {
113985                 return (typeOfObj === typeOfPattern) ? obj : null;
113986             },
113987
113988             "Number": function () {
113989                 var n = toInteger(obj);
113990
113991                 if (isNaN(n))
113992                     return null;
113993
113994                 return (obj === n) ? n : parseFloat(obj);
113995             },
113996
113997             "Object": function () {
113998                 var attr, iInstance, ret;
113999
114000                 if (!("_derived" in pattern) &&
114001                         (typeOfObj !== typeOfPattern)) {
114002                     return null;
114003                 }
114004
114005                 iInstance = instanceOfPattern(pattern, obj);
114006                 if (isNaN(iInstance)) {
114007                     return null;
114008                 }
114009
114010                 for (attr in pattern) {
114011                     switch (attr) {
114012                     case "_optional":
114013                     case "_constructor":
114014                         break;
114015
114016                     case "_derived":
114017                         if (iInstance !== -1) {
114018                             ret = _self(pattern._derived[iInstance]).cast(obj);
114019                             if (ret === null) {
114020                                 return null;
114021                             }
114022                         }
114023                         break;
114024
114025                     default:
114026                         if (!pattern._optional || !pattern._optional[attr] ||
114027                                 (obj[attr] !== undefined) &&
114028                                 (obj[attr] !== null)) {
114029                             ret = _self(pattern[attr]).cast(obj[attr]);
114030                             if (ret === null) {
114031                                 return null;
114032                             }
114033                             obj[attr] = ret;
114034                         }
114035                         break;
114036                     }
114037                 }
114038
114039                 return obj;
114040             },
114041
114042             "TZDate": function () {
114043                 if (typeOfObj !== "Object") {
114044                     return null;
114045                 }
114046                 return (obj instanceof window.tizen.TZDate) ? obj : null;
114047             },
114048
114049             "any": function () {
114050                 return obj;
114051             },
114052
114053             "boolean": function () {
114054                 return (typeOfObj === typeOfPattern) ? obj : null;
114055             },
114056
114057             "dictionary": function () {
114058                 var attr, ret;
114059
114060                 if (typeOfObj !== "Object") {
114061                     return null;
114062                 }
114063
114064                 for (attr in pattern) {
114065                     switch (attr) {
114066                     case "_dictionary":
114067                         if (pattern._dictionary !== null) {
114068                             ret = _self(pattern._dictionary).cast(obj);
114069                             if (ret === null) {
114070                                 return null;
114071                             }
114072                         }
114073                         break;
114074
114075                     default:
114076                         if ((attr in obj) && (obj[attr] !== null) &&
114077                                 (obj[attr] !== undefined)) {
114078                             ret = _self(pattern[attr]).cast(obj[attr]);
114079                             if (ret === null) {
114080                                 return null;
114081                             }
114082                             obj[attr] = ret;
114083                         }
114084                         break;
114085                     }
114086                 }
114087
114088                 return obj;
114089             },
114090
114091             "enum": function () {
114092                 var i;
114093
114094                 obj = String(obj).trim();
114095                 for (i in pattern) {
114096                     if (obj === pattern[i]) {
114097                         return obj;
114098                     }
114099                 }
114100
114101                 return null;
114102             },
114103
114104             "float": function () {
114105                 var f = parseFloat(obj, 10);
114106
114107                 return (isNaN(f) ? null : f);
114108             },
114109
114110             "unsigned long": function () {
114111                 var n;
114112
114113                 n = toUInt32(obj);
114114
114115                 return (n === null) ? null : n;
114116             },
114117
114118             "unsigned short": function () {
114119                 var n;
114120
114121                 n = toUInt16(obj);
114122
114123                 return (n === null) ? null : n;
114124             },
114125
114126             "octet": function () {
114127                 var n;
114128
114129                 try {
114130                     n = Number(obj);
114131
114132                     return ((!isNaN(n) && (n == obj) &&
114133                             (0 <= n) && (n <= 0xff)) ? n : null);
114134                 } catch (e) {
114135                     return null;
114136                 }
114137             },
114138
114139             "byte": function () {
114140                 var n, ch;
114141
114142                 switch (typeOfObj) {
114143                 case "Number":
114144                     try {
114145                         n = Number(obj);
114146
114147                         return ((!isNaN(n) && (n == obj) &&
114148                                 (0 <= n) && (n <= 0xff)) ? n : null);
114149                     } catch (e) {
114150                         return null;
114151                     }
114152                     break;
114153
114154                 case "DOMString":
114155                     if (obj.length > 1)
114156                         return null;
114157
114158                     try {
114159                         ch = obj.charCodeAt();
114160
114161                         return ((!isNaN(ch) && (0 <= ch) &&
114162                                 (ch <= 0xff)) ? String(obj) : null);
114163                     } catch (e) {
114164                         return null;
114165                     }
114166                     break;
114167
114168                 default:
114169                     break;
114170                 }
114171
114172                 return null;
114173             },
114174
114175             "": function () {
114176                 return _self(t[pattern]).cast(obj);
114177             }
114178         };
114179
114180         return typeMap[typeOfPattern]();
114181     }
114182
114183     function copy(obj) {
114184         var typeMap,
114185             typeOfObj = getType(obj, false);
114186
114187         typeMap = {
114188             "Arguments": function () {
114189                 var i, isNullable, ret = [];
114190
114191                 for (i in pattern) {
114192                     if (i === "_optional")
114193                         continue;
114194
114195                     isNullable = !!(pattern._optional && pattern._optional[i]);
114196
114197                     if (i > obj.length - 1) {
114198                         if (!isNullable) {
114199                             return null;
114200                         }
114201                         ret[i] = null;
114202                         continue;
114203                     }
114204
114205                     if ((obj[i] === null) || (obj[i] === undefined)) {
114206                         if (!isNullable || ((i in obj) && (obj[i] !== null))) {
114207                             return null;
114208                         }
114209                     } else if ((ret[i] = _self(pattern[i])
114210                             .copy(obj[i])) === null) {
114211                         return null;
114212                     }
114213                 }
114214
114215                 for (i in ret) {
114216                     obj[i] = ret[i];
114217                 }
114218
114219                 return obj;
114220             },
114221
114222             "Array": function () {
114223                 var arr = [], elementType, i;
114224
114225                 if (typeOfObj !== typeOfPattern) {
114226                     return null;
114227                 }
114228
114229                 elementType = _self(pattern[0]);
114230                 for (i in obj) {
114231                     if (obj[i]) {
114232                         arr[i] = elementType.copy(obj[i]);
114233                         if (arr[i] === null)
114234                             return null;
114235                     }
114236                 }
114237
114238                 return arr;
114239             },
114240
114241             "Callback": function () {
114242                 var ret = {}, attr;
114243
114244                 if (typeOfObj !== "Object") {
114245                     return null;
114246                 }
114247
114248                 for (attr in pattern) {
114249                     if (attr in obj) {
114250                         ret[attr] = _self(pattern[attr]).copy(obj[attr]);
114251                         if (ret[attr] === null) {
114252                             return null;
114253                         }
114254                     }
114255                 }
114256
114257                 return ret;
114258             },
114259
114260             "Object": function () {
114261                 var ret = {}, iInstance, attr, derived, i;
114262
114263                 if (typeOfObj !== typeOfPattern) {
114264                     return null;
114265                 }
114266
114267                 iInstance = instanceOfPattern(pattern, obj);
114268                 if (isNaN(iInstance)) {
114269                     return null;
114270                 }
114271
114272                 if ("_constructor" in pattern) {
114273                     ret.__proto__ = window.tizen[pattern._constructor].prototype;
114274                 }
114275
114276                 for (attr in pattern) {
114277                     switch (attr) {
114278                     case "_optional":
114279                     case "_constructor":
114280                         break;
114281
114282                     case "_derived":
114283                         if (iInstance !== -1) {
114284                             derived = _self(pattern._derived[iInstance])
114285                                     .copy(obj);
114286
114287                             for (i in derived) {
114288                                 ret[i] = derived[i];
114289                             }
114290                         }
114291                         break;
114292
114293                     default:
114294                         if (!pattern._optional || !pattern._optional[attr] ||
114295                                 (obj[attr] !== undefined) &&
114296                                 (obj[attr] !== null)) {
114297                             ret[attr] = _self(pattern[attr]).copy(obj[attr]);
114298                             if (ret[attr] === null) {
114299                                 return null;
114300                             }
114301                         }
114302                         break;
114303                     }
114304                 }
114305
114306                 return ret;
114307             },
114308
114309             "dictionary": function () {
114310                 var ret = {}, attr, base, i;
114311
114312                 if (typeOfObj !== "Object") {
114313                     return null;
114314                 }
114315
114316                 for (attr in pattern) {
114317                     switch (attr) {
114318                     case "_dictionary":
114319                         if (pattern._dictionary !== null) {
114320                             base = _self(pattern._dictionary).copy(obj);
114321                             if (base === null) {
114322                                 return null;
114323                             }
114324                             for (i in base) {
114325                                 ret[i] = base[i];
114326                             }
114327                         }
114328                         break;
114329
114330                     default:
114331                         if ((attr in obj) && (obj[attr] !== null) &&
114332                                 (obj[attr] !== undefined)) {
114333                             ret[attr] = _self(pattern[attr]).copy(obj[attr]);
114334                             if (ret[attr] === null) {
114335                                 return null;
114336                             }
114337                         }
114338                         break;
114339                     }
114340                 }
114341
114342                 return ret;
114343             },
114344
114345             "": function () {
114346                 return _self(t[pattern]).copy(obj);
114347             }
114348         };
114349
114350         return (typeOfPattern in typeMap) ? typeMap[typeOfPattern]() :
114351                 cast(obj);
114352     }
114353
114354     function match(obj) {
114355         var typeMap,
114356             typeOfObj = getType(obj, false);
114357
114358         typeMap = {
114359             "Array": function () {
114360                 var elementType, i;
114361
114362                 if (typeOfObj !== typeOfPattern)
114363                     return false;
114364
114365                 elementType = _self(pattern[0]);
114366                 for (i in obj) {
114367                     if (!elementType.match(obj[i])) {
114368                         return false;
114369                     }
114370                 }
114371
114372                 return true;
114373             },
114374
114375             "Callback": function () {
114376                 var attr, isMatched = true;
114377
114378                 if (typeOfObj !== "Object") {
114379                     return false;
114380                 }
114381
114382                 for (attr in pattern) {
114383                     if (attr in obj) {
114384                         isMatched = _self(pattern[attr]).match(obj[attr]);
114385                         if (!isMatched) {
114386                             break;
114387                         }
114388                     }
114389                 }
114390
114391                 return isMatched;
114392             },
114393
114394             "DOMString": function () {
114395                 return (typeOfObj === typeOfPattern);
114396             },
114397
114398             "Date": function () {
114399                 return (typeOfObj === typeOfPattern);
114400             },
114401
114402             "Function": function () {
114403                 return (typeOfObj === typeOfPattern);
114404             },
114405
114406             "Number": function () {
114407                 return (typeOfObj === typeOfPattern);
114408             },
114409
114410             "Object": function () {
114411                 var iInstance, attr, isMatched = false;
114412
114413                 if (typeOfObj !== typeOfPattern)
114414                     return false;
114415
114416                 iInstance = instanceOfPattern(pattern, obj);
114417                 if (isNaN(iInstance)) {
114418                     return false;
114419                 }
114420
114421                 for (attr in pattern) {
114422                     switch (attr) {
114423                     case "_optional":
114424                     case "_constructor":
114425                         break;
114426
114427                     case "_derived":
114428                         if (iInstance !== -1) {
114429                             isMatched = _self(pattern._derived[iInstance])
114430                                     .match(obj);
114431                         }
114432                         break;
114433
114434                     default:
114435                         if (pattern._optional && pattern._optional[attr]) {
114436                             isMatched = ((obj[attr] === null) ||
114437                                     (obj[attr] === undefined) ||
114438                                     _self(pattern[attr]).match(obj[attr]));
114439                         } else {
114440                             isMatched = (obj[attr] !== undefined) &&
114441                                     _self(pattern[attr]).match(obj[attr]);
114442                         }
114443                         break;
114444                     }
114445
114446                     if (!isMatched)
114447                         break;
114448                 }
114449
114450                 /*// Check if verbose attributes are present
114451                 if (isMatched) {
114452                     for (attr in obj) {
114453                         if (pattern[attr] === undefined) {
114454                             isMatched = false;
114455                             break;
114456                         }
114457                     }
114458                 }*/
114459
114460                 return isMatched;
114461             },
114462
114463             "any": function () {
114464                 return true;
114465             },
114466
114467             "boolean": function () {
114468                 return (typeOfObj === typeOfPattern);
114469             },
114470
114471             "dictionary": function () {
114472                 var attr, isMatched = true;
114473
114474                 if (typeOfObj !== "Object") {
114475                     return false;
114476                 }
114477
114478                 for (attr in pattern) {
114479                     switch (attr) {
114480                     case "_dictionary":
114481                         if (pattern._dictionary !== null) {
114482                             isMatched = _self(pattern._dictionary).match(obj);
114483                             if (!isMatched)
114484                                 break;
114485                         }
114486                         break;
114487
114488                     default:
114489                         if ((attr in obj) && (obj[attr] !== null) &&
114490                                 (obj[attr] !== undefined)) {
114491                             isMatched = _self(pattern[attr]).match(obj[attr]);
114492                             if (!isMatched)
114493                                 break;
114494                         }
114495                         break;
114496                     }
114497                 }
114498
114499                 return isMatched;
114500             },
114501
114502             "enum": function () {
114503                 for (var i in pattern) {
114504                     if (obj === pattern[i]) {
114505                         return true;
114506                     }
114507                 }
114508
114509                 return false;
114510             },
114511
114512             "float": function () {
114513                 return (typeOfObj === "Number");
114514             },
114515
114516             "unsigned long": function () {
114517                 var n;
114518
114519                 n = toUInt32(obj);
114520
114521                 return (n !== null);
114522             },
114523
114524             "unsigned short": function () {
114525                 var n;
114526
114527                 n = toUInt16(obj);
114528
114529                 return (n !== null);
114530             },
114531
114532             "octet": function () {
114533                 var n;
114534
114535                 try {
114536                     n = Number(obj);
114537
114538                     return (!isNaN(n) && (n == obj) &&
114539                             (0 <= n) && (n <= 0xff));
114540                 } catch (e) {
114541                     return false;
114542                 }
114543             },
114544
114545             "byte": function () {
114546                 var n, ch;
114547
114548                 switch (typeOfObj) {
114549                 case "Number":
114550                     try {
114551                         n = Number(obj);
114552
114553                         return (!isNaN(n) && (n == obj) &&
114554                                 (0 <= n) && (n <= 0xff));
114555                     } catch (e) {
114556                         return false;
114557                     }
114558                     break;
114559
114560                 case "DOMString":
114561                     if (obj.length > 1)
114562                         return false;
114563
114564                     try {
114565                         ch = obj.charCodeAt();
114566
114567                         return (!isNaN(ch) && (0 <= ch) && (ch <= 0xff));
114568                     } catch (e) {
114569                         return false;
114570                     }
114571                     break;
114572
114573                 default:
114574                     break;
114575                 }
114576
114577                 return false;
114578             },
114579
114580             "Arguments": function () {
114581                 return true;
114582             },
114583
114584             "": function () {
114585                 return _self(t[pattern]).match(obj);
114586             }
114587         };
114588
114589         return typeMap[typeOfPattern]();
114590     }
114591
114592     typeOfPattern = getType(pattern, true);
114593
114594     typeCoerce = {
114595         cast:  cast,
114596         copy:  copy,
114597         match: match
114598     };
114599
114600     return typeCoerce;
114601 };
114602
114603 module.exports = _self;
114604
114605 });
114606 define('ripple/platform/tizen/2.0/typedef', function (require, exports, module) {
114607 /*
114608  *  Copyright 2013 Intel Corporation.
114609  *
114610  * Licensed under the Apache License, Version 2.0 (the "License");
114611  * you may not use this file except in compliance with the License.
114612  * You may obtain a copy of the License at
114613  *
114614  * http://www.apache.org/licenses/LICENSE-2.0
114615  *
114616  * Unless required by applicable law or agreed to in writing, software
114617  * distributed under the License is distributed on an "AS IS" BASIS,
114618  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114619  * See the License for the specific language governing permissions and
114620  * limitations under the License.
114621  */
114622
114623 var _t, _c, _i;
114624
114625 /*
114626  * Primitive type definition
114627  */
114628
114629 _t = {
114630     // Basic
114631     Callback:                           "Callback",
114632     DOMString:                          "",
114633     Date:                               new Date(),
114634     Function:                           function () {},
114635     TZDate:                             "TZDate",
114636     any:                                "any",
114637     boolean:                            false,
114638     byte:                               "byte",
114639     double:                             "double",
114640     float:                              "float",
114641     long:                               0,
114642     octet:                              "octet",
114643     short:                              0,
114644     long_long:                          0,
114645     unsigned_long:                      "unsigned long",
114646     unsigned_long_long:                 0,
114647     unsigned_short:                     "unsigned short",
114648
114649     // Common
114650     FilterMatchFlag:                    ["EXACTLY", "FULLSTRING", "CONTAINS",
114651                                          "STARTSWITH", "ENDSWITH", "EXISTS"],
114652     SortModeOrder:                      ["ASC", "DESC"],
114653     CompositeFilterType:                ["UNION", "INTERSECTION"],
114654
114655     // Bluetooth
114656     BluetoothSocketState:               ["CLOSED", "OPEN"],
114657     BluetoothProfileType:               ["HEALTH", "HEALTH"],
114658     BluetoothHealthChannelType:         ["RELIABLE", "STREAMING"],
114659
114660     // Calendar
114661     CalendarType:                       ["EVENT", "TASK"],
114662     CalendarTextFormat:                 ["ICALENDAR_20", "VCALENDAR_10"],
114663     AlarmMethod:                        ["SOUND", "DISPLAY"],
114664     RecurrenceRuleFrequency:            ["DAILY", "WEEKLY", "MONTHLY",
114665                                          "YEARLY"],
114666     ByDayValue:                         ["MO", "TU", "WE", "TH", "FR", "SA",
114667                                          "SU"],
114668     EventAvailability:                  ["BUSY", "FREE"],
114669     AttendeeType:                       ["INDIVIDUAL", "GROUP", "RESOURCE",
114670                                          "ROOM", "UNKNOWN"],
114671     AttendeeStatus:                     ["PENDING", "ACCEPTED", "DECLINED",
114672                                          "TENTATIVE", "DELEGATED", "COMPLETED",
114673                                          "IN_PROCESS"],
114674     AttendeeRole:                       ["REQ_PARTICIPANT", "OPT_PARTICIPANT",
114675                                          "NON_PARTICIPANT", "CHAIR"],
114676     CalendarItemPriority:               ["HIGH", "MEDIUM", "LOW"],
114677     CalendarItemVisibility:             ["PUBLIC", "PRIVATE", "CONFIDENTIAL"],
114678     CalendarItemStatus:                 ["TENTATIVE", "CONFIRMED", "CANCELLED",
114679                                          "NEEDS_ACTION", "IN_PROCESS",
114680                                          "COMPLETED"],
114681
114682     // Contact
114683     ContactTextFormat:                  ["VCARD_30", "VCARD_30"],    // Enum must has more than one value
114684
114685     // Content
114686     ContentDirectoryStorageType:        ["INTERNAL", "EXTERNAL"],
114687     ContentType:                        ["IMAGE", "VIDEO", "AUDIO", "OTHER"],
114688     AudioContentLyricsType:             ["SYNCHRONIZED", "UNSYNCHRONIZED"],
114689     ImageContentOrientation:            ["NORMAL", "FLIP_HORIZONTAL",
114690                                          "ROTATE_180", "FLIP_VERTICAL",
114691                                          "TRANSPOSE", "ROTATE_90", "TRANSVERSE",
114692                                          "ROTATE_270"],
114693
114694     // Data Control
114695     DataType:                           ["MAP", "SQL"],
114696
114697     // Data Synchronization
114698     SyncMode:                           ["MANUAL", "PERIODIC", "PUSH"],
114699     SyncType:                           ["TWO_WAY", "SLOW",
114700                                          "ONE_WAY_FROM_CLIENT",
114701                                          "REFRESH_FROM_CLIENT",
114702                                          "ONE_WAY_FROM_SERVER",
114703                                          "REFRESH_FROM_SERVER"],
114704     SyncInterval:                       ["5_MINUTES", "15_MINUTES", "1_HOUR",
114705                                          "4_HOURS", "12_HOURS", "1_DAY",
114706                                          "1_WEEK", "1_MONTH"],
114707     SyncServiceType:                    ["CONTACT", "EVENT"],
114708     SyncStatus:                         ["SUCCESS", "FAIL", "STOP", "NONE"],
114709
114710     // Download
114711     DownloadState:                      ["QUEUED", "DOWNLOADING", "PAUSED",
114712                                          "CANCELED", "COMPLETED", "FAILED"],
114713     DownloadNetworkType:                ["CELLULAR", "WIFI", "ALL"],
114714
114715     // Messaging
114716     MessageServiceTag:                  ["messaging.sms", "messaging.mms",
114717                                          "messaging.email"],
114718
114719     // Network Bearer Selection
114720     NetworkType:                        ["CELLULAR", "UNKNOWN"],
114721
114722     // NFC
114723     NDEFRecordTextEncoding:             ["UTF8", "UTF16"],
114724     NFCTagType:                         ["GENERIC_TARGET", "ISO14443_A",
114725                                          "ISO14443_4A", "ISO14443_3A",
114726                                          "MIFARE_MINI", "MIFARE_1K",
114727                                          "MIFARE_4K", "MIFARE_ULTRA",
114728                                          "MIFARE_DESFIRE", "ISO14443_B",
114729                                          "ISO14443_4B", "ISO14443_BPRIME",
114730                                          "FELICA", "JEWEL", "ISO15693",
114731                                          "UNKNOWN_TARGET"],
114732
114733     // Notification
114734     NotificationType:                   ["STATUS", "STATUS"],
114735     StatusNotificationType:             ["SIMPLE", "THUMBNAIL", "ONGOING",
114736                                          "PROGRESS"],
114737     NotificationProgressType:           ["PERCENTAGE", "BYTE"],
114738
114739     // System Info
114740     SystemInfoPropertyId:               ["BATTERY", "CPU", "STORAGE", "DISPLAY",
114741                                          "DEVICE_ORIENTATION", "BUILD",
114742                                          "LOCALE", "NETWORK", "WIFI_NETWORK",
114743                                          "CELLULAR_NETWORK", "SIM",
114744                                          "PERIPHERAL"],
114745     SystemInfoNetworkType:              ["NONE", "2G", "2.5G", "3G", "4G",
114746                                          "WIFI", "ETHERNET", "UNKNOWN"],
114747     SystemInfoDeviceOrientationStatus:  ["PORTRAIT_PRIMARY",
114748                                          "PORTRAIT_SECONDARY",
114749                                          "LANDSCAPE_PRIMARY",
114750                                          "LANDSCAPE_SECONDARY"],
114751     SystemInfoSimState:                 ["ABSENT", "INITIALIZING", "READY",
114752                                          "PIN_REQUIRED", "PUK_REQUIRED",
114753                                          "NETWORK_LOCKED", "SIM_LOCKED",
114754                                          "UNKNOWN"],
114755     SystemInfoProfile:                  ["MOBILE_FULL", "MOBILE_WEB"],
114756
114757     // System Setting
114758     SystemSettingType:                  ["HOME_SCREEN", "LOCK_SCREEN",
114759                                          "INCOMING_CALL", "NOTIFICATION_EMAIL"],
114760
114761     // Time
114762     TimeDurationUnit:                   ["MSECS", "SECS", "MINS", "HOURS",
114763                                          "DAYS"]
114764 };
114765
114766 /*
114767  * Derivative type definition
114768  */
114769
114770 /*
114771  * Object attributes
114772  *     Contruct a prototype of an object. Specify a primitive type for each
114773  *     attribute.
114774  *
114775  * _optional
114776  *     Optional attributes table, which consists of two types of attributes,
114777  *
114778  *     nullable
114779  *         Nullable attributes, marked as '?' in IDL.
114780  *
114781  *     undefined
114782  *         Array type attributes, that not definitely specified to be
114783  *         initialized as an empty array, i.e., undefined-initialized array.
114784  *
114785  * _derived
114786  *     Derived types, which used in two cases of definition,
114787  *
114788  *     Subtype list
114789  *         An array consists of derived subtypes. It exists in the definition of
114790  *         a base type.
114791  *
114792  *     Union types
114793  *         An array consists of member types. It exists in the definition of
114794  *         a union type.
114795  *
114796  * _dictionary
114797  *     Dictionary type, which indicates that the object is a dictionary type.
114798  */
114799
114800 /*
114801  * Common
114802  */
114803
114804 _t.AttributeFilter = {
114805     attributeName: _t.DOMString,
114806     matchFlag:     _t.FilterMatchFlag,
114807     matchValue:    _t.any,
114808
114809     _optional: {
114810         // nullable
114811         matchValue: true
114812     }
114813 };
114814
114815 _t.AttributeRangeFilter = {
114816     attributeName: _t.DOMString,
114817     initialValue:  _t.any,
114818     endValue:      _t.any,
114819
114820     _optional: {
114821         // nullable
114822         initialValue: true,
114823         endValue:     true
114824     }
114825 };
114826
114827 _t.CompositeFilter = {
114828     type:    _t.CompositeFilterType,
114829     filters: ["AbstractFilter"]     // Recursive expansion
114830 };
114831
114832 _t.AbstractFilter = {
114833     _derived: [_t.AttributeFilter, _t.AttributeRangeFilter, _t.CompositeFilter]
114834 };
114835
114836 _t.SortMode = {
114837     attributeName: _t.DOMString,
114838     order:         _t.SortModeOrder
114839 };
114840
114841 _t.SimpleCoordinates = {
114842     latitude:  _t.double,
114843     longitude: _t.double
114844 };
114845
114846 _t.SuccessCallback = _t.Function;
114847 _t.ErrorCallback   = _t.Function;
114848
114849 /*
114850  * Time
114851  */
114852
114853 _t.TimeDuration = {
114854     length:      _t.long_long,
114855     unit:        _t.TimeDurationUnit,
114856     difference:  _t.Function,
114857     equalsTo:    _t.Function,
114858     lessThan:    _t.Function,
114859     greaterThan: _t.Function
114860 };
114861
114862 /*
114863  * Alarm
114864  */
114865
114866 _t.AlarmId = _t.DOMString;
114867
114868 _t.AlarmRelative = {
114869     delay:               _t.unsigned_long_long,
114870     period:              _t.unsigned_long_long,
114871     getRemainingSeconds: _t.Function,
114872
114873     _optional: {
114874         // nullable
114875         period:              true,
114876         getRemainingSeconds: true
114877     }
114878 };
114879
114880 _t.AlarmAbsolute = {
114881     date:                 _t.Date,
114882     period:               _t.unsigned_long_long,
114883     daysOfTheWeek:        [_t.ByDayValue],
114884     getNextScheduledDate: _t.Function,
114885
114886     _optional: {
114887         // nullable
114888         period:               true,
114889         getNextScheduledDate: true
114890     }
114891 };
114892
114893 _t.Alarm = {
114894     id: _t.AlarmId,
114895
114896     _optional: {
114897         // nullable
114898         id: true
114899     },
114900
114901     _derived: [_t.AlarmRelative, _t.AlarmAbsolute]
114902 };
114903
114904 /*
114905  * Application
114906  */
114907
114908 _t.ApplicationId                              = _t.DOMString;
114909 _t.ApplicationContextId                       = _t.DOMString;
114910 _t.ApplicationInformationArraySuccessCallback = _t.Function;
114911 _t.FindAppControlSuccessCallback              = _t.Function;
114912 _t.ApplicationContextArraySuccessCallback     = _t.Function;
114913
114914 _t.ApplicationControlData = {
114915     key:   _t.DOMString,
114916     value: [_t.DOMString]
114917 };
114918
114919 _t.ApplicationControl = {
114920     operation: _t.DOMString,
114921     uri:       _t.DOMString,
114922     mime:      _t.DOMString,
114923     category:  _t.DOMString,
114924     data:      [_t.ApplicationControlData],
114925
114926     _optional: {
114927         // nullable
114928         uri:      true,
114929         mime:     true,
114930         category: true
114931     }
114932 };
114933
114934 _t.ApplicationControlDataArrayReplyCallback = {
114935     onsuccess: _t.Callback,
114936     onfailure: _t.Callback
114937 };
114938
114939 _t.ApplicationInformationEventCallback = {
114940     oninstalled:   _t.Callback,
114941     onupdated:     _t.Callback,
114942     onuninstalled: _t.Callback
114943 };
114944
114945 /*
114946  * Bluetooth
114947  */
114948
114949 _t.BluetoothAddress                          = _t.DOMString;
114950 _t.BluetoothUUID                             = _t.DOMString;
114951 _t.BluetoothDeviceSuccessCallback            = _t.Function;
114952 _t.BluetoothDeviceArraySuccessCallback       = _t.Function;
114953 _t.BluetoothSocketSuccessCallback            = _t.Function;
114954 _t.BluetoothServiceSuccessCallback           = _t.Function;
114955 _t.BluetoothHealthApplicationSuccessCallback = _t.Function;
114956 _t.BluetoothHealthChannelSuccessCallback     = _t.Function;
114957
114958 _t.BluetoothClass = {
114959     major:      _t.octet,
114960     minor:      _t.octet,
114961     services:   [_t.unsigned_short],
114962     hasService: _t.Function
114963 };
114964
114965 _t.BluetoothDevice = {
114966     name:                   _t.DOMString,
114967     address:                _t.BluetoothAddress,
114968     deviceClass:            _t.BluetoothClass,
114969     isBonded:               _t.boolean,
114970     isTrusted:              _t.boolean,
114971     isConnected:            _t.boolean,
114972     uuids:                  [_t.BluetoothUUID],
114973     connectToServiceByUUID: _t.Function
114974 };
114975
114976 _t.BluetoothHealthApplication = {
114977     dataType:   _t.unsigned_short,
114978     name:       _t.DOMString,
114979     onconnect:  _t.BluetoothHealthChannelSuccessCallback,
114980     unregister: _t.Function,
114981
114982     _optional: {
114983         onconnect: true
114984     }
114985 };
114986
114987 _t.BluetoothAdapterChangeCallback = {
114988     onstatechanged:      _t.Callback,
114989     onnamechanged:       _t.Callback,
114990     onvisibilitychanged: _t.Callback
114991 };
114992
114993 _t.BluetoothDiscoverDevicesSuccessCallback = {
114994     onstarted:           _t.Callback,
114995     ondevicefound:       _t.Callback,
114996     ondevicedisappeared: _t.Callback,
114997     onfinished:          _t.Callback
114998 };
114999
115000 _t.BluetoothHealthChannelChangeCallback = {
115001     onmessage: _t.Callback,
115002     onclose:   _t.Callback
115003 };
115004
115005 /*
115006  * Bookmark
115007  */
115008
115009 _t.BookmarkFolder = {
115010     parent: "BookmarkFolder",
115011     title:  _t.DOMString,
115012
115013     _optional: {
115014         // nullable
115015         parent: true
115016     }
115017 };
115018
115019 _t.BookmarkItem = {
115020     parent: _t.BookmarkFolder,
115021     title:  _t.DOMString,
115022     url:    _t.DOMString,
115023
115024     _optional: {
115025         // nullable
115026         parent: true
115027     }
115028 };
115029
115030 _t.Bookmark = {
115031     _derived: [_t.BookmarkItem, _t.BookmarkFolder]
115032 };
115033
115034 /*
115035  * Contact
115036  */
115037
115038 _t.AddressBookId  = _t.DOMString;
115039 _t.ContactId      = _t.DOMString;
115040 _t.PersonId       = _t.DOMString;
115041 _t.ContactGroupId = _t.DOMString;
115042
115043 _t.Person = {
115044     id:               _t.PersonId,
115045     displayName:      _t.DOMString,
115046     contactCount:     _t.long,
115047     hasPhoneNumber:   _t.boolean,
115048     hasEmail:         _t.boolean,
115049     isFavorite:       _t.boolean,
115050     photoURI:         _t.DOMString,
115051     ringtoneURI:      _t.DOMString,
115052     displayContactId: _t.ContactId,
115053
115054     _optional: {
115055         // nullable
115056         photoURI:    true,
115057         ringtoneURI: true
115058     }
115059 };
115060
115061 _t.ContactRef = {
115062     addressBookId: _t.AddressBookId,
115063     contactId:     _t.ContactId
115064 };
115065
115066 _t.ContactName = {
115067     prefix:            _t.DOMString,
115068     suffix:            _t.DOMString,
115069     firstName:         _t.DOMString,
115070     middleName:        _t.DOMString,
115071     lastName:          _t.DOMString,
115072     nicknames:         [_t.DOMString],
115073     phoneticFirstName: _t.DOMString,
115074     phoneticLastName:  _t.DOMString,
115075     displayName:       _t.DOMString,
115076
115077     _optional: {
115078         // nullable
115079         prefix:            true,
115080         suffix:            true,
115081         firstName:         true,
115082         middleName:        true,
115083         lastName:          true,
115084         phoneticFirstName: true,
115085         phoneticLastName:  true,
115086         displayName:       true
115087     }
115088 };
115089
115090 _t.ContactOrganization = {
115091     name:       _t.DOMString,
115092     department: _t.DOMString,
115093     title:      _t.DOMString,
115094     role:       _t.DOMString,
115095     logoURI:    _t.DOMString,
115096
115097     _optional: {
115098         // nullable
115099         name:       true,
115100         department: true,
115101         title:      true,
115102         role:       true,
115103         logoURI:    true
115104     }
115105 };
115106
115107 _t.ContactWebSite = {
115108     url:  _t.DOMString,
115109     type: _t.DOMString,
115110
115111     _optional: {
115112         // nullable
115113         type: true
115114     }
115115 };
115116
115117 _t.ContactAnniversary = {
115118     date:  _t.Date,
115119     label: _t.DOMString,
115120
115121     _optional: {
115122         // nullable
115123         label: true
115124     }
115125 };
115126
115127 _t.ContactAddress = {
115128     country:               _t.DOMString,
115129     region:                _t.DOMString,
115130     city:                  _t.DOMString,
115131     streetAddress:         _t.DOMString,
115132     additionalInformation: _t.DOMString,
115133     postalCode:            _t.DOMString,
115134     isDefault:             _t.boolean,
115135     types:                 [_t.DOMString],
115136
115137     _optional: {
115138         // nullable
115139         country:               true,
115140         region:                true,
115141         city:                  true,
115142         streetAddress:         true,
115143         additionalInformation: true,
115144         postalCode:            true,
115145         // undefined
115146         types:                 true
115147     }
115148 };
115149
115150 _t.ContactPhoneNumber = {
115151     number:    _t.DOMString,
115152     isDefault: _t.boolean,
115153     types:     [_t.DOMString],
115154
115155     _optional: {
115156         // undefined
115157         types: true
115158     }
115159 };
115160
115161 _t.ContactEmailAddress = {
115162     email:     _t.DOMString,
115163     isDefault: _t.boolean,
115164     types:     [_t.DOMString],
115165
115166     _optional: {
115167         // undefined
115168         types: true
115169     }
115170 };
115171
115172 _t.Contact = {
115173     id:              _t.ContactId,
115174     personId:        _t.PersonId,
115175     addressBookId:   _t.AddressBookId,
115176     lastUpdated:     _t.Date,
115177     isFavorite:      _t.boolean,
115178     name:            _t.ContactName,
115179     addresses:       [_t.ContactAddress],
115180     photoURI:        _t.DOMString,
115181     phoneNumbers:    [_t.ContactPhoneNumber],
115182     emails:          [_t.ContactEmailAddress],
115183     birthday:        _t.Date,
115184     anniversaries:   [_t.ContactAnniversary],
115185     organizations:   [_t.ContactOrganization],
115186     notes:           [_t.DOMString],
115187     urls:            [_t.ContactWebSite],
115188     ringtoneURI:     _t.DOMString,
115189     groupIds:        [_t.ContactGroupId],
115190     convertToString: _t.Function,
115191     clone:           _t.Function,
115192
115193     _optional: {
115194         // nullable
115195         id:            true,
115196         personId:      true,
115197         addressBookId: true,
115198         lastUpdated:   true,
115199         name:          true,
115200         photoURI:      true,
115201         birthday:      true,
115202         ringtoneURI:   true
115203     }
115204 };
115205
115206 _t.ContactGroup = {
115207     id:            _t.ContactGroupId,
115208     addressBookId: _t.AddressBookId,
115209     name:          _t.DOMString,
115210     ringtoneURI:   _t.DOMString,
115211     photoURI:      _t.DOMString,
115212     readOnly:      _t.boolean,
115213
115214     _optional: {
115215         // nullable
115216         id:            true,
115217         addressBookId: true,
115218         ringtoneURI:   true,
115219         photoURI:      true
115220     }
115221 };
115222
115223 _t.PersonArraySuccessCallback      = _t.Function;
115224 _t.ContactArraySuccessCallback     = _t.Function;
115225 _t.AddressBookArraySuccessCallback = _t.Function;
115226
115227 _t.AddressBookChangeCallback = {
115228     oncontactsadded:   _t.Callback,
115229     oncontactsupdated: _t.Callback,
115230     oncontactsremoved: _t.Callback
115231 };
115232
115233 _t.PersonsChangeCallback = {
115234     onpersonsadded:   _t.Callback,
115235     onpersonsupdated: _t.Callback,
115236     onpersonsremoved: _t.Callback
115237 };
115238
115239 _t.ContactInit = {
115240     name:          _t.ContactName,
115241     addresses:     [_t.ContactAddress],
115242     photoURI:      _t.DOMString,
115243     phoneNumbers:  [_t.ContactPhoneNumber],
115244     emails:        [_t.ContactEmailAddress],
115245     birthday:      _t.Date,
115246     anniversaries: [_t.ContactAnniversary],
115247     organizations: [_t.ContactOrganization],
115248     notes:         [_t.DOMString],
115249     urls:          [_t.ContactWebSite],
115250     ringtoneURI:   _t.DOMString,
115251     groupIds:      [_t.ContactGroupId],
115252
115253     _dictionary: null
115254 };
115255
115256 _t.ContactNameInit = {
115257     prefix:            _t.DOMString,
115258     suffix:            _t.DOMString,
115259     firstName:         _t.DOMString,
115260     middleName:        _t.DOMString,
115261     lastName:          _t.DOMString,
115262     nicknames:         [_t.DOMString],
115263     phoneticFirstName: _t.DOMString,
115264     phoneticLastName:  _t.DOMString,
115265
115266     _dictionary: null
115267 };
115268
115269 _t.ContactOrganizationInit = {
115270     name:       _t.DOMString,
115271     department: _t.DOMString,
115272     title:      _t.DOMString,
115273     role:       _t.DOMString,
115274     logoURI:    _t.DOMString,
115275
115276     _dictionary: null
115277 };
115278
115279 _t.ContactAddressInit = {
115280     country:               _t.DOMString,
115281     region:                _t.DOMString,
115282     city:                  _t.DOMString,
115283     streetAddress:         _t.DOMString,
115284     additionalInformation: _t.DOMString,
115285     postalCode:            _t.DOMString,
115286     isDefault:             _t.boolean,
115287     types:                 [_t.DOMString],
115288
115289     _dictionary: null
115290 };
115291
115292 /*
115293  * Calendar
115294  */
115295
115296 _t.CalendarId                        = _t.DOMString;
115297 _t.CalendarTaskId                    = _t.DOMString;
115298 _t.CalendarEventArraySuccessCallback = _t.Function;
115299 _t.CalendarItemArraySuccessCallback  = _t.Function;
115300 _t.CalendarArraySuccessCallback      = _t.Function;
115301
115302 _t.CalendarEventId = {
115303     uid: _t.DOMString,
115304     rid: _t.DOMString,
115305
115306     _optional: {
115307         // nullable
115308         rid: true
115309     }
115310 };
115311
115312 _t.CalendarItemId = {
115313     _derived: [_t.CalendarEventId, _t.CalendarTaskId]
115314 };
115315
115316 _t.CalendarAlarm = {
115317     absoluteDate: _t.TZDate,
115318     before:       _t.TimeDuration,
115319     method:       _t.AlarmMethod,
115320     description:  _t.DOMString,
115321
115322     _optional: {
115323         // nullable
115324         absoluteDate: true,
115325         before:       true,
115326         description:  true
115327     }
115328 };
115329
115330 _t.CalendarAttendee = {
115331     uri:          _t.DOMString,
115332     name:         _t.DOMString,
115333     role:         _t.AttendeeRole,
115334     status:       _t.AttendeeStatus,
115335     RSVP:         _t.boolean,
115336     type:         _t.AttendeeType,
115337     group:        _t.DOMString,
115338     delegatorURI: _t.DOMString,
115339     delegateURI:  _t.DOMString,
115340     contactRef:   _t.ContactRef,
115341
115342     _optional: {
115343         // nullable
115344         name:         true,
115345         group:        true,
115346         delegatorURI: true,
115347         delegateURI:  true,
115348         contactRef:   true
115349     }
115350 };
115351
115352 _t.CalendarRecurrenceRule = {
115353     frequency:       _t.RecurrenceRuleFrequency,
115354     interval:        _t.unsigned_short,
115355     untilDate:       _t.TZDate,
115356     occurrenceCount: _t.long,
115357     daysOfTheWeek:   [_t.ByDayValue],
115358     setPositions:    [_t.short],
115359     exceptions:      [_t.TZDate],
115360
115361     _optional: {
115362         // nullable
115363         untilDate: true
115364     }
115365 };
115366
115367 _t.CalendarTask = {
115368     dueDate:       _t.TZDate,
115369     completedDate: _t.TZDate,
115370     progress:      _t.unsigned_short,
115371
115372     _optional: {
115373         // nullable
115374         dueDate:       true,
115375         completedDate: true
115376     }
115377 };
115378
115379 _t.CalendarEvent = {
115380     isDetached:       _t.boolean,
115381     endDate:          _t.TZDate,
115382     availability:     _t.EventAvailability,
115383     recurrenceRule:   _t.CalendarRecurrenceRule,
115384     expandRecurrence: _t.Function,
115385
115386     _optional: {
115387         // nullable
115388         endDate:        true,
115389         recurrenceRule: true
115390     }
115391 };
115392
115393 _t.CalendarItem = {
115394     id:                   _t.CalendarItemId,
115395     calendarId:           _t.CalendarId,
115396     lastModificationDate: _t.TZDate,
115397     description:          _t.DOMString,
115398     summary:              _t.DOMString,
115399     isAllDay:             _t.boolean,
115400     startDate:            _t.TZDate,
115401     duration:             _t.TimeDuration,
115402     location:             _t.DOMString,
115403     geolocation:          _t.SimpleCoordinates,
115404     organizer:            _t.DOMString,
115405     visibility:           _t.CalendarItemVisibility,
115406     status:               _t.CalendarItemStatus,
115407     priority:             _t.CalendarItemPriority,
115408     alarms:               [_t.CalendarAlarm],
115409     categories:           [_t.DOMString],
115410     attendees:            [_t.CalendarAttendee],
115411     convertToString:      _t.Function,
115412     clone:                _t.Function,
115413
115414     _optional: {
115415         // nullable
115416         id:                   true,
115417         calendarId:           true,
115418         lastModificationDate: true,
115419         description:          true,
115420         summary:              true,
115421         startDate:            true,
115422         duration:             true,
115423         location:             true,
115424         geolocation:          true,
115425         organizer:            true
115426     },
115427
115428     _derived: [_t.CalendarTask, _t.CalendarEvent]
115429 };
115430
115431 _t.CalendarItemInit = {
115432     description: _t.DOMString,
115433     summary:     _t.DOMString,
115434     isAllDay:    _t.boolean,
115435     startDate:   _t.TZDate,
115436     duration:    _t.TimeDuration,
115437     location:    _t.DOMString,
115438     geolocation: _t.SimpleCoordinates,
115439     organizer:   _t.DOMString,
115440     visibility:  _t.CalendarItemVisibility,
115441     status:      _t.CalendarItemStatus,
115442     priority:    _t.CalendarItemPriority,
115443     alarms:      [_t.CalendarAlarm],
115444     categories:  [_t.DOMString],
115445     attendees:   [_t.CalendarAttendee],
115446
115447     _dictionary: null
115448 };
115449
115450 _t.CalendarTaskInit = {
115451     dueDate:       _t.TZDate,
115452     completedDate: _t.TZDate,
115453     progress:      _t.short,
115454
115455     _dictionary: _t.CalendarItemInit
115456 };
115457
115458 _t.CalendarEventInit = {
115459     endDate:        _t.TZDate,
115460     availability:   _t.EventAvailability,
115461     recurrenceRule: _t.CalendarRecurrenceRule,
115462
115463     _dictionary: _t.CalendarItemInit
115464 };
115465
115466 _t.CalendarAttendeeInit = {
115467     name:         _t.DOMString,
115468     role:         _t.AttendeeRole,
115469     status:       _t.AttendeeStatus,
115470     RSVP:         _t.boolean,
115471     type:         _t.AttendeeType,
115472     group:        _t.DOMString,
115473     delegatorURI: _t.DOMString,
115474     delegateURI:  _t.DOMString,
115475     contactRef:   _t.ContactRef,
115476
115477     _dictionary: null
115478 };
115479
115480 _t.CalendarRecurrenceRuleInit = {
115481     interval:        _t.short,
115482     untilDate:       _t.TZDate,
115483     occurrenceCount: _t.long,
115484     daysOfTheWeek:   [_t.ByDayValue],
115485     setPositions:    [_t.short],
115486     exceptions:      [_t.TZDate],
115487
115488     _dictionary: null
115489 };
115490
115491 _t.CalendarChangeCallback = {
115492     onitemsadded:   _t.Callback,
115493     onitemsupdated: _t.Callback,
115494     onitemsremoved: _t.Callback
115495 };
115496
115497 /*
115498  * CallHistory
115499  */
115500
115501 _t.CallHistoryEntryArraySuccessCallback = _t.Function;
115502
115503 _t.RemoteParty = {
115504     remoteParty: _t.DOMString,
115505     personId:    _t.PersonId,
115506
115507     _optional: {
115508         // nullable
115509         remoteParty: true,
115510         personId:    true
115511     }
115512 };
115513
115514 _t.CallHistoryEntry = {
115515     uid:           _t.DOMString,
115516     type:          _t.DOMString,
115517     features:      [_t.DOMString],
115518     remoteParties: [_t.RemoteParty],
115519     startTime:     _t.Date,
115520     duration:      _t.unsigned_long,
115521     direction:     _t.DOMString,
115522
115523     _optional: {
115524         // nullable
115525         features: true
115526     }
115527 };
115528
115529 _t.CallHistoryChangeCallback = {
115530     onadded:   _t.Callback,
115531     onchanged: _t.Callback,
115532     onremoved: _t.Callback
115533 };
115534
115535 /*
115536  * Content
115537  */
115538
115539 _t.ContentId                            = _t.DOMString;
115540 _t.ContentDirectoryId                   = _t.DOMString;
115541 _t.ContentArraySuccessCallback          = _t.Function;
115542 _t.ContentDirectoryArraySuccessCallback = _t.Function;
115543 _t.ContentScanSuccessCallback           = _t.Function;
115544
115545 _t.ContentChangeCallback = {
115546     oncontentadded:   _t.Callback,
115547     oncontentupdated: _t.Callback,
115548     oncontentremoved: _t.Callback
115549 };
115550
115551 _t.VideoContent = {
115552     geolocation: _t.SimpleCoordinates,
115553     album:       _t.DOMString,
115554     artists:     [_t.DOMString],
115555     duration:    _t.unsigned_long,
115556     width:       _t.unsigned_long,
115557     height:      _t.unsigned_long,
115558
115559     _optional: {
115560         // nullable
115561         geolocation: true,
115562         album:       true,
115563         artists:     true
115564     }
115565 };
115566
115567 _t.AudioContentLyrics = {
115568     type:       _t.AudioContentLyricsType,
115569     timestamps: [_t.unsigned_long],
115570     texts:      [_t.DOMString]
115571 };
115572
115573 _t.AudioContent = {
115574     album:       _t.DOMString,
115575     genres:      [_t.DOMString],
115576     artists:     [_t.DOMString],
115577     composers:   [_t.DOMString],
115578     lyrics:      _t.AudioContentLyrics,
115579     copyright:   _t.DOMString,
115580     bitrate:     _t.unsigned_long,
115581     trackNumber: _t.unsigned_short,
115582     duration:    _t.unsigned_long,
115583
115584     _optional: {
115585         // nullable
115586         album:       true,
115587         genres:      true,
115588         artists:     true,
115589         composers:   true,
115590         lyrics:      true,
115591         copyright:   true,
115592         trackNumber: true
115593     }
115594 };
115595
115596 _t.ImageContent = {
115597     geolocation: _t.SimpleCoordinates,
115598     width:       _t.unsigned_long,
115599     height:      _t.unsigned_long,
115600     orientation: _t.ImageContentOrientation,
115601
115602     _optional: {
115603         // nullable
115604         geolocation: true
115605     }
115606 };
115607
115608 _t.Content = {
115609     editableAttributes: [_t.DOMString],
115610     id:                 _t.ContentId,
115611     name:               _t.DOMString,
115612     type:               _t.ContentType,
115613     mimeType:           _t.DOMString,
115614     title:              _t.DOMString,
115615     contentURI:         _t.DOMString,
115616     thumbnailURIs:      [_t.DOMString],
115617     releaseDate:        _t.Date,
115618     modifiedDate:       _t.Date,
115619     size:               _t.unsigned_long,
115620     description:        _t.DOMString,
115621     rating:             _t.float,
115622
115623     _optional: {
115624         // nullable
115625         thumbnailURIs: true,
115626         releaseDate:   true,
115627         modifiedDate:  true,
115628         description:   true
115629     },
115630
115631     _derived: [_t.VideoContent, _t.AudioContent, _t.ImageContent]
115632 };
115633
115634 /*
115635  * Data Control
115636  */
115637
115638 _t.DataControlSuccessCallback         = _t.Function;
115639 _t.DataControlErrorCallback           = _t.Function;
115640 _t.DataControlInsertSuccessCallback   = _t.Function;
115641 _t.DataControlSelectSuccessCallback   = _t.Function;
115642 _t.DataControlGetValueSuccessCallback = _t.Function;
115643
115644 _t.RowData = {
115645     columns: [_t.DOMString],
115646     values:  [_t.DOMString]
115647 };
115648
115649 /*
115650  * Data Synchronization
115651  */
115652
115653 _t.SyncProfileId = _t.DOMString;
115654
115655 _t.SyncInfo = {
115656     url:      _t.DOMString,
115657     id:       _t.DOMString,
115658     password: _t.DOMString,
115659     mode:     _t.SyncMode,
115660     type:     _t.SyncType,
115661     interval: _t.SyncInterval,
115662
115663     _optional: {
115664         // nullable
115665         id:       true,
115666         password: true,
115667         type:     true,
115668         interval: true
115669     }
115670 };
115671
115672 _t.SyncServiceInfo = {
115673     enable:            _t.boolean,
115674     serviceType:       _t.SyncServiceType,
115675     serverDatabaseUri: _t.DOMString,
115676     id:                _t.DOMString,
115677     password:          _t.DOMString,
115678
115679     _optional: {
115680         // nullable
115681         id:       true,
115682         password: true
115683     }
115684 };
115685
115686 _t.SyncProfileInfo = {
115687     profileId:   _t.SyncProfileId,
115688     profileName: _t.DOMString,
115689     syncInfo:    _t.SyncInfo,
115690     serviceInfo: [_t.SyncServiceInfo],
115691
115692     _optional: {
115693         // nullable
115694         profileId:   true,
115695         serviceInfo: true
115696     }
115697 };
115698
115699 _t.SyncProgressCallback = {
115700     onprogress:  _t.Callback,
115701     oncompleted: _t.Callback,
115702     onstopped:   _t.Callback,
115703     onfailed:    _t.Callback
115704 };
115705
115706 /*
115707  * Download
115708  */
115709
115710 _t.DownloadHTTPHeaderFields = {};
115711
115712 _t.DownloadRequest = {
115713     url:         _t.DOMString,
115714     destination: _t.DOMString,
115715     fileName:    _t.DOMString,
115716     networkType: _t.DownloadNetworkType,
115717     httpHeader:  _t.DownloadHTTPHeaderFields,
115718
115719     _optional: {
115720         destination: true,
115721         fileName:    true,
115722         networkType: true,
115723         httpHeader:  true
115724     }
115725 };
115726
115727 _t.DownloadCallback = {
115728     onprogress:  _t.Callback,
115729     onpaused:    _t.Callback,
115730     oncanceled:  _t.Callback,
115731     oncompleted: _t.Callback,
115732     onfailed:    _t.Callback
115733 };
115734
115735 /*
115736  * Messaging
115737  */
115738
115739 _t.MessageId                               = _t.DOMString;
115740 _t.MessageAttachmentId                     = _t.DOMString;
115741 _t.MessageConvId                           = _t.DOMString;
115742 _t.MessageFolderId                         = _t.DOMString;
115743 _t.MessageServiceArraySuccessCallback      = _t.Function;
115744 _t.MessageRecipientsCallback               = _t.Function;
115745 _t.MessageBodySuccessCallback              = _t.Function;
115746 _t.MessageAttachmentSuccessCallback        = _t.Function;
115747 _t.MessageArraySuccessCallback             = _t.Function;
115748 _t.MessageConversationArraySuccessCallback = _t.Function;
115749 _t.MessageFolderArraySuccessCallback       = _t.Function;
115750
115751 _t.MessageFolder = {
115752     id:             _t.MessageFolderId,
115753     parentId:       _t.MessageFolderId,
115754     serviceId:      _t.DOMString,
115755     contentType:    _t.MessageServiceTag,
115756     name:           _t.DOMString,
115757     path:           _t.DOMString,
115758     type:           _t.DOMString,
115759     synchronizable: _t.boolean,
115760
115761     _optional: {
115762         // nullable
115763         parentId: true
115764     }
115765 };
115766
115767 _t.MessagesChangeCallback = {
115768     messagesadded:   _t.Callback,
115769     messagesupdated: _t.Callback,
115770     messagesremoved: _t.Callback
115771 };
115772
115773 _t.MessageConversationsChangeCallback = {
115774     conversationsadded:   _t.Callback,
115775     conversationsupdated: _t.Callback,
115776     conversationsremoved: _t.Callback
115777 };
115778
115779 _t.MessageFoldersChangeCallback = {
115780     foldersadded:   _t.Callback,
115781     foldersupdated: _t.Callback,
115782     foldersremoved: _t.Callback
115783 };
115784
115785 /*
115786  * Network Bearer Selection
115787  */
115788
115789 _t.NetworkSuccessCallback = {
115790     onsuccess:      _t.Callback,
115791     ondisconnected: _t.Callback
115792 };
115793
115794 /*
115795  * NFC
115796  */
115797
115798 _t.NDEFMessageReadCallback  = _t.Function;
115799 _t.ByteArraySuccessCallback = _t.Function;
115800
115801 _t.NFCTagDetectCallback = {
115802     onattach: _t.Callback,
115803     ondetach: _t.Callback
115804 };
115805
115806 _t.NFCPeerDetectCallback = {
115807     onattach: _t.Callback,
115808     ondetach: _t.Callback
115809 };
115810
115811 _t.NDEFRecordText = {
115812     text:         _t.DOMString,
115813     languageCode: _t.DOMString,
115814     encoding:     _t.NDEFRecordTextEncoding
115815 };
115816
115817 _t.NDEFRecordURI = {
115818     uri: _t.DOMString
115819 };
115820
115821 _t.NDEFRecordMedia = {
115822     mimeType: _t.DOMString
115823 };
115824
115825 _t.NDEFRecord = {
115826     tnf:     _t.short,
115827     type:    [_t.byte],
115828     id:      [_t.byte],
115829     payload: [_t.byte],
115830
115831     _derived: [_t.NDEFRecordText, _t.NDEFRecordURI, _t.NDEFRecordMedia]
115832 };
115833
115834 _t.NDEFMessage = {
115835     recordCount: _t.long,
115836     records:     [_t.NDEFRecord],
115837     toByte:      _t.Function
115838 };
115839
115840 /*
115841  * Notification
115842  */
115843
115844 _t.NotificationId = _t.DOMString;
115845
115846 _t.NotificationDetailInfo = {
115847     mainText: _t.DOMString,
115848     subText:  _t.DOMString,
115849
115850     _optional: {
115851         // nullable
115852         subText: true
115853     }
115854 };
115855
115856 _t.StatusNotificationInit = {
115857     content:             _t.DOMString,
115858     iconPath:            _t.DOMString,
115859     soundPath:           _t.DOMString,
115860     vibration:           _t.boolean,
115861     appControl:          _t.ApplicationControl,
115862     appId:               _t.ApplicationId,
115863     progressType:        _t.NotificationProgressType,
115864     progressValue:       _t.unsigned_long,
115865     number:              _t.long,
115866     subIconPath:         _t.DOMString,
115867     detailInfo:          [_t.NotificationDetailInfo],
115868     ledColor:            _t.DOMString,
115869     ledOnPeriod:         _t.unsigned_long,
115870     ledOffPeriod:        _t.unsigned_long,
115871     backgroundImagePath: _t.DOMString,
115872     thumbnails:          [_t.DOMString],
115873
115874     _dictionary: null
115875 };
115876
115877 _t.StatusNotification = {
115878     statusType:          _t.StatusNotificationType,
115879     iconPath:            _t.DOMString,
115880     subIconPath:         _t.DOMString,
115881     number:              _t.long,
115882     detailInfo:          [_t.NotificationDetailInfo],
115883     ledColor:            _t.DOMString,
115884     ledOnPeriod:         _t.unsigned_long,
115885     ledOffPeriod:        _t.unsigned_long,
115886     backgroundImagePath: _t.DOMString,
115887     thumbnails:          [_t.DOMString],
115888     soundPath:           _t.DOMString,
115889     vibration:           _t.boolean,
115890     appControl:          _t.ApplicationControl,
115891     appId:               _t.ApplicationId,
115892     progressType:        _t.NotificationProgressType,
115893     progressValue:       _t.unsigned_long,
115894
115895     _optional: {
115896         // nullable
115897         iconPath:            true,
115898         subIconPath:         true,
115899         number:              true,
115900         detailInfo:          true,
115901         ledColor:            true,
115902         backgroundImagePath: true,
115903         thumbnails:          true,
115904         soundPath:           true,
115905         appControl:          true,
115906         appId:               true,
115907         progressValue:       true
115908     }
115909 };
115910
115911 _t.Notification = {
115912     id:         _t.NotificationId,
115913     type:       _t.NotificationType,
115914     postedTime: _t.Date,
115915     title:      _t.DOMString,
115916     content:    _t.DOMString,
115917
115918     _optional: {
115919         // nullable
115920         id:         true,
115921         postedTime: true,
115922         content:    true
115923     },
115924
115925     _derived: [_t.StatusNotification]
115926 };
115927
115928 /*
115929  * Push
115930  */
115931
115932 _t.PushRegistrationId          = _t.DOMString;
115933 _t.PushRegisterSuccessCallback = _t.Function;
115934 _t.PushNotificationCallback    = _t.Function;
115935
115936 /*
115937  * Package
115938  */
115939
115940 _t.PackageId = _t.DOMString;
115941 _t.PackageInformationArraySuccessCallback = _t.Function;
115942
115943 _t.PackageProgressCallback = {
115944     onprogress: _t.Callback,
115945     oncomplete: _t.Callback
115946 };
115947
115948 _t.PackageInfomationEventCallback = {
115949     oninstalled:   _t.Callback,
115950     onupdated:     _t.Callback,
115951     onuninstalled: _t.Callback
115952 };
115953
115954 /*
115955  * System Info
115956  */
115957
115958 _t.SystemInfoPropertySuccessCallback = _t.Callback;
115959
115960 _t.SystemInfoOptions = {
115961     timeout:       _t.unsigned_long,
115962     highThreshold: _t.double,
115963     lowThreshold:  _t.double,
115964
115965     _dictionary: null
115966 };
115967
115968 /*
115969  * System Setting
115970  */
115971
115972 _t.SystemSettingSuccessCallback = _t.Function;
115973
115974 /*
115975  * Vehicle
115976  */
115977 _t.SupportedPropertiesSuccessCallback = _t.Function;
115978
115979 _t.VehiclePropertyErrorCallback = _t.Function;
115980
115981 /*
115982  * Constructor list definition
115983  */
115984
115985 /*
115986  * Generic constructor
115987  *     Construct a prototype of constructor. A fake array of arguments type is
115988  *     specified for constructor.
115989  *
115990  * Overloaded constructors
115991  *     Construct an array of prototype of constructor. Each array element is
115992  *     specified for one of constructors. The constructor with extra arguments
115993  *     are recommended to be defined ahead of the one with fewer same arguments
115994  *     for exact match.
115995  */
115996
115997 _c = {
115998     // Alarm
115999     AlarmAbsolute: [],
116000
116001     // Calendar
116002     CalendarTask:  [],
116003     CalendarEvent: [],
116004     CalendarAlarm: [],
116005
116006     // Contact
116007     Contact:       [],
116008
116009     // NFC
116010     NDEFMessage:   [],
116011     NDEFRecord:    [],
116012
116013     // Data Synchronization
116014     SyncInfo:      [],
116015
116016     // Time
116017     TZDate:        []
116018 };
116019
116020 /*
116021  * Common
116022  */
116023
116024 // AttributeFilter
116025 _c.AttributeFilter = {
116026     0: _t.DOMString,
116027     1: _t.FilterMatchFlag,
116028     2: _t.any,
116029
116030     _optional: {
116031         1: true,
116032         2: true
116033     }
116034 };
116035
116036 // AttributeRangeFilter
116037 _c.AttributeRangeFilter = {
116038     0: _t.DOMString,
116039     1: _t.any,
116040     2: _t.any,
116041
116042     _optional: {
116043         1: true,
116044         2: true
116045     }
116046 };
116047
116048 // CompositeFilter
116049 _c.CompositeFilter = {
116050     0: _t.CompositeFilterType,
116051     1: [_t.AbstractFilter],
116052
116053     _optional: {
116054         1: true
116055     }
116056 };
116057
116058 // SortMode
116059 _c.SortMode = {
116060     0: _t.DOMString,
116061     1: _t.SortModeOrder,
116062
116063     _optional: {
116064         1: true
116065     }
116066 };
116067
116068 // SimpleCoordinates
116069 _c.SimpleCoordinates = {
116070     0: _t.double,
116071     1: _t.double
116072 };
116073
116074 /*
116075  * Alarm
116076  */
116077
116078 // AlarmRelative
116079 _c.AlarmRelative = {
116080     0: _t.long,
116081     1: _t.long,
116082
116083     _optional: {
116084         1: true
116085     }
116086 };
116087
116088 // AlarmAbsolute
116089 _c.AlarmAbsolute[0] = {
116090     0: _t.Date,
116091     1: [_t.ByDayValue]
116092 };
116093
116094 _c.AlarmAbsolute[1] = {
116095     0: _t.Date,
116096     1: _t.long
116097 };
116098
116099 _c.AlarmAbsolute[2] = {
116100     0: _t.Date
116101 };
116102
116103 /*
116104  * Application
116105  */
116106
116107 // ApplicationControlData
116108 _c.ApplicationControlData = {
116109     0: _t.DOMString,
116110     1: [_t.DOMString]
116111 };
116112
116113 // ApplicationControl
116114 _c.ApplicationControl = {
116115     0: _t.DOMString,
116116     1: _t.DOMString,
116117     2: _t.DOMString,
116118     3: _t.DOMString,
116119     4: [_t.ApplicationControlData],
116120
116121     _optional: {
116122         1: true,
116123         2: true,
116124         3: true,
116125         4: true
116126     }
116127 };
116128
116129 /*
116130  * Bookmark
116131  */
116132
116133 // BookmarkItem
116134 _c.BookmarkItem = {
116135     0: _t.DOMString,
116136     1: _t.DOMString
116137 };
116138
116139 // BookmarkFolder
116140 _c.BookmarkFolder = {
116141     0: _t.DOMString
116142 };
116143
116144 /*
116145  * Calendar
116146  */
116147
116148 // CalendarTask
116149 _c.CalendarTask[0] = {
116150     0: _t.CalendarTaskInit,
116151
116152     _optional: {
116153         // nullable
116154         0: true
116155     }
116156 };
116157
116158 _c.CalendarTask[1] = {
116159     0: _t.DOMString,
116160     1: _t.CalendarTextFormat
116161 };
116162
116163 // CalendarEvent
116164 _c.CalendarEvent[0] = {
116165     0: _t.CalendarEventInit,
116166
116167     _optional: {
116168         // nullable
116169         0: true
116170     }
116171 };
116172
116173 _c.CalendarEvent[1] = {
116174     0: _t.DOMString,
116175     1: _t.CalendarTextFormat
116176 };
116177
116178 // CalendarAttendee
116179 _c.CalendarAttendee = {
116180     0: _t.DOMString,
116181     1: _t.CalendarAttendeeInit,
116182
116183     _optional: {
116184         1: true
116185     }
116186 };
116187
116188 // CalendarRecurrenceRule
116189 _c.CalendarRecurrenceRule = {
116190     0: _t.RecurrenceRuleFrequency,
116191     1: _t.CalendarRecurrenceRuleInit,
116192
116193     _optional: {
116194         1: true
116195     }
116196 };
116197
116198 // CalendarEventId
116199 _c.CalendarEventId = {
116200     0: _t.DOMString,
116201     1: _t.DOMString,
116202
116203     _optional: {
116204         1: true
116205     }
116206 };
116207
116208 // CalendarAlarm
116209 _c.CalendarAlarm[0] = {
116210     0: _t.TZDate,
116211     1: _t.AlarmMethod,
116212     2: _t.DOMString,
116213
116214     _optional: {
116215         2: true
116216     }
116217 };
116218
116219 _c.CalendarAlarm[1] = {
116220     0: _t.TimeDuration,
116221     1: _t.AlarmMethod,
116222     2: _t.DOMString,
116223
116224     _optional: {
116225         2: true
116226     }
116227 };
116228
116229 /*
116230  * Contact
116231  */
116232
116233 // Contact
116234 _c.Contact[0] = {
116235     0: _t.ContactInit,
116236
116237     _optional: {
116238         0: true
116239     }
116240 };
116241
116242 _c.Contact[1] = {
116243     0: _t.DOMString
116244 };
116245
116246 // ContactRef
116247 _c.ContactRef = {
116248     0: _t.AddressBookId,
116249     1: _t.ContactId
116250 };
116251
116252 // ContactName
116253 _c.ContactName = {
116254     0: _t.ContactNameInit,
116255
116256     _optional: {
116257         0: true
116258     }
116259 };
116260
116261 // ContactOrganization
116262 _c.ContactOrganization = {
116263     0: _t.ContactOrganizationInit,
116264
116265     _optional: {
116266         0: true
116267     }
116268 };
116269
116270 // ContactWebSite
116271 _c.ContactWebSite = {
116272     0: _t.DOMString,
116273     1: _t.DOMString,
116274
116275     _optional: {
116276         1: true
116277     }
116278 };
116279
116280 // ContactAnniversary
116281 _c.ContactAnniversary = {
116282     0: _t.Date,
116283     1: _t.DOMString,
116284
116285     _optional: {
116286         1: true
116287     }
116288 };
116289
116290 // ContactAddress
116291 _c.ContactAddress = {
116292     0: _t.ContactAddressInit,
116293
116294     _optional: {
116295         0: true
116296     }
116297 };
116298
116299 // ContactPhoneNumber
116300 _c.ContactPhoneNumber = {
116301     0: _t.DOMString,
116302     1: [_t.DOMString],
116303     2: _t.boolean,
116304
116305     _optional: {
116306         1: true,
116307         2: true
116308     }
116309 };
116310
116311 // ContactEmailAddress
116312 _c.ContactEmailAddress = {
116313     0: _t.DOMString,
116314     1: [_t.DOMString],
116315     2: _t.boolean,
116316
116317     _optional: {
116318         1: true,
116319         2: true
116320     }
116321 };
116322
116323 // ContactGroup
116324 _c.ContactGroup = {
116325     0: _t.DOMString,
116326     1: _t.DOMString,
116327     2: _t.DOMString,
116328
116329     _optional: {
116330         1: true,
116331         2: true
116332     }
116333 };
116334
116335 /*
116336  * Data Synchronization
116337  */
116338
116339 // SyncInfo
116340 _c.SyncInfo[0] = {
116341     0: _t.DOMString,
116342     1: _t.DOMString,
116343     2: _t.DOMString,
116344     3: _t.SyncMode,
116345     4: _t.SyncType
116346 };
116347
116348 _c.SyncInfo[1] = {
116349     0: _t.DOMString,
116350     1: _t.DOMString,
116351     2: _t.DOMString,
116352     3: _t.SyncMode,
116353     4: _t.SyncInterval
116354 };
116355
116356 _c.SyncInfo[2] = {
116357     0: _t.DOMString,
116358     1: _t.DOMString,
116359     2: _t.DOMString,
116360     3: _t.SyncMode
116361 };
116362
116363 // SyncServiceInfo
116364 _c.SyncServiceInfo = {
116365     0: _t.boolean,
116366     1: _t.SyncServiceType,
116367     2: _t.DOMString,
116368     3: _t.DOMString,
116369     4: _t.DOMString,
116370
116371     _optional: {
116372         3: true,
116373         4: true
116374     }
116375 };
116376
116377 // SyncProfileInfo
116378 _c.SyncProfileInfo = {
116379     0: _t.DOMString,
116380     1: _t.SyncInfo,
116381     2: [_t.SyncServiceInfo],
116382
116383     _optional: {
116384         2: true
116385     }
116386 };
116387
116388 /*
116389  * Download
116390  */
116391
116392 // DownloadRequest
116393 _c.DownloadRequest = {
116394     0: _t.DOMString,
116395     1: _t.DOMString,
116396     2: _t.DOMString,
116397     3: _t.DownloadNetworkType,
116398     4: _t.DownloadHTTPHeaderFields,
116399
116400     _optional: {
116401         1: true,
116402         2: true,
116403         3: true,
116404         4: true
116405     }
116406 };
116407
116408 /*
116409  * NFC
116410  */
116411
116412 // NDEFMessage
116413 _c.NDEFMessage[0] = {
116414     0: [_t.NDEFRecord]
116415 };
116416
116417 _c.NDEFMessage[1] = {
116418     0: [_t.byte]
116419 };
116420
116421 _c.NDEFMessage[2] = null;
116422
116423 // NDEFRecord
116424 _c.NDEFRecord[0] = {
116425     0: _t.short,
116426     1: [_t.byte],
116427     2: [_t.byte],
116428     3: [_t.byte],
116429
116430     _optional: {
116431         3: true
116432     }
116433 };
116434
116435 _c.NDEFRecord[1] = {
116436     0: [_t.byte]
116437 };
116438
116439 // NDEFRecordText
116440 _c.NDEFRecordText = {
116441     0: _t.DOMString,
116442     1: _t.DOMString,
116443     2: _t.DOMString,
116444
116445     _optional: {
116446         2: true
116447     }
116448 };
116449
116450 // NDEFRecordURI
116451 _c.NDEFRecordURI = {
116452     0: _t.DOMString
116453 };
116454
116455 // NDEFRecordMedia
116456 _c.NDEFRecordMedia = {
116457     0: _t.DOMString,
116458     1: [_t.byte]
116459 };
116460
116461 /*
116462  * Notification
116463  */
116464
116465 // StatusNotification
116466 _c.StatusNotification = {
116467     0: _t.StatusNotificationType,
116468     1: _t.DOMString,
116469     2: _t.StatusNotificationInit,
116470
116471     _optional: {
116472         2: true
116473     }
116474 };
116475
116476 // NotificationDetailInfo
116477 _c.NotificationDetailInfo = {
116478     0: _t.DOMString,
116479     1: _t.DOMString,
116480
116481     _optional: {
116482         1: true
116483     }
116484 };
116485
116486 /*
116487  * Time
116488  */
116489
116490 // TZDate
116491 _c.TZDate[0] = {
116492     0: _t.Date,
116493     1: _t.DOMString,
116494
116495     _optional: {
116496         // nullable
116497         0: true,
116498         1: true
116499     }
116500 };
116501
116502 _c.TZDate[1] = {
116503     0: _t.long,
116504     1: _t.long,
116505     2: _t.long,
116506     3: _t.long,
116507     4: _t.long,
116508     5: _t.long,
116509     6: _t.long,
116510     7: _t.DOMString,
116511
116512     _optional: {
116513         // nullable
116514         3: true,
116515         4: true,
116516         5: true,
116517         6: true,
116518         7: true
116519     }
116520 };
116521
116522 // TimeDuration
116523 _c.TimeDuration = {
116524     0: _t.long_long,
116525     1: _t.TimeDurationUnit,
116526
116527     _optional: {
116528         // nullable
116529         1: true
116530     }
116531 };
116532
116533 /*
116534  * Interface prototype definition
116535  */
116536
116537 _i = {
116538     // Alarm
116539     AlarmManager:                  {},
116540
116541     // Application
116542     ApplicationManager:            {},
116543     Application:                   {},
116544     RequestedApplicationControl:   {},
116545
116546     // Bluetooth
116547     BluetoothManager:              {},
116548     BluetoothAdapter:              {},
116549     BluetoothDevice:               {},
116550     BluetoothSocket:               {},
116551     BluetoothClass:                {},
116552     BluetoothServiceHandler:       {},
116553     BluetoothHealthProfileHandler: {},
116554     BluetoothHealthApplication:    {},
116555     BluetoothHealthChannel:        {},
116556
116557     // Bookmark
116558     BookmarkManager:               {},
116559
116560     // Calendar
116561     CalendarManager:               {},
116562     Calendar:                      {},
116563     CalendarItem:                  {},
116564     CalendarEvent:                 {},
116565
116566     // Call History
116567     CallHistory:                   {},
116568
116569     // Contact
116570     ContactManager:                {},
116571     AddressBook:                   {},
116572     Person:                        {},
116573     Contact:                       {},
116574
116575     // Content
116576     ContentManager:                {},
116577
116578     // Data Control
116579     DataControlManager:            {},
116580     SQLDataControlConsumer:        {},
116581     MappedDataControlConsumer:     {},
116582
116583     // Data Synchronization
116584     DataSynchronizationManager:    {},
116585
116586     // Download
116587     DownloadManager:               {},
116588
116589     // Network Bearer Selection
116590     NetworkBearerSelection:        {},
116591
116592     // NFC
116593     NFCManager:                    {},
116594     NFCAdapter:                    {},
116595     NFCTag:                        {},
116596     NFCPeer:                       {},
116597     NDEFMessage:                   {},
116598
116599     // Notification
116600     NotificationManager:           {},
116601
116602     // Message
116603     Messaging:                     {},
116604     MessageService:                {},
116605     MessageStorage:                {},
116606
116607     // Package
116608     PackageManager:                {},
116609
116610     // Push
116611     PushManager:                   {},
116612
116613     // System Info
116614     SystemInfo:                    {},
116615
116616     // System Setting
116617     SystemSettingManager:          {},
116618
116619     // Time
116620     TimeUtil:                      {},
116621     TZDate:                        {},
116622     TimeDuration:                  {},
116623
116624     // Vehicle
116625     Vehicle:                       {}
116626 };
116627
116628 /*
116629  * Alarm
116630  */
116631
116632 // AlarmManager
116633 _i.AlarmManager.add = {
116634     0: _t.Alarm,
116635     1: _t.ApplicationId,
116636     2: _t.ApplicationControl,
116637
116638     _optional: {
116639         2: true
116640     }
116641 };
116642
116643 _i.AlarmManager.remove = {
116644     0: _t.AlarmId
116645 };
116646
116647 _i.AlarmManager.removeAll = null;
116648
116649 _i.AlarmManager.get = {
116650     0: _t.AlarmId
116651 };
116652
116653 _i.AlarmManager.getAll = null;
116654
116655 /*
116656  * Application
116657  */
116658
116659 // ApplicationManager
116660 _i.ApplicationManager.getCurrentApplication = null;
116661
116662 _i.ApplicationManager.kill = {
116663     0: _t.ApplicationContextId,
116664     1: _t.SuccessCallback,
116665     2: _t.ErrorCallback,
116666
116667     _optional: {
116668         1: true,
116669         2: true
116670     }
116671 };
116672
116673 _i.ApplicationManager.launch = {
116674     0: _t.ApplicationId,
116675     1: _t.SuccessCallback,
116676     2: _t.ErrorCallback,
116677
116678     _optional: {
116679         1: true,
116680         2: true
116681     }
116682 };
116683
116684 _i.ApplicationManager.launchAppControl = {
116685     0: _t.ApplicationControl,
116686     1: _t.ApplicationId,
116687     2: _t.SuccessCallback,
116688     3: _t.ErrorCallback,
116689     4: _t.ApplicationControlDataArrayReplyCallback,
116690
116691     _optional: {
116692         1: true,
116693         2: true,
116694         3: true,
116695         4: true
116696     }
116697 };
116698
116699 _i.ApplicationManager.findAppControl = {
116700     0: _t.ApplicationControl,
116701     1: _t.FindAppControlSuccessCallback,
116702     2: _t.ErrorCallback,
116703
116704     _optional: {
116705         2: true
116706     }
116707 };
116708
116709 _i.ApplicationManager.getAppsContext = {
116710     0: _t.ApplicationContextArraySuccessCallback,
116711     1: _t.ErrorCallback,
116712
116713     _optional: {
116714         1: true
116715     }
116716 };
116717
116718 _i.ApplicationManager.getAppContext = {
116719     0: _t.ApplicationContextId,
116720
116721     _optional: {
116722         0: true
116723     }
116724 };
116725
116726 _i.ApplicationManager.getAppsInfo = {
116727     0: _t.ApplicationInformationArraySuccessCallback,
116728     1: _t.ErrorCallback,
116729
116730     _optional: {
116731         1: true
116732     }
116733 };
116734
116735 _i.ApplicationManager.getAppInfo = {
116736     0: _t.ApplicationId,
116737
116738     _optional: {
116739         0: true
116740     }
116741 };
116742
116743 _i.ApplicationManager.getAppCerts = {
116744     0: _t.ApplicationId,
116745
116746     _optional: {
116747         0: true
116748     }
116749 };
116750
116751 _i.ApplicationManager.getAppSharedURI = {
116752     0: _t.ApplicationId,
116753
116754     _optional: {
116755         0: true
116756     }
116757 };
116758
116759 _i.ApplicationManager.getAppMetaData = {
116760     0: _t.ApplicationId,
116761
116762     _optional: {
116763         0: true
116764     }
116765 };
116766
116767 _i.ApplicationManager.addAppInfoEventListener = {
116768     0: _t.ApplicationInformationEventCallback
116769 };
116770
116771 _i.ApplicationManager.removeAppInfoEventListener = {
116772     0: _t.long
116773 };
116774
116775 // Application
116776 _i.Application.exit = null;
116777 _i.Application.hide = null;
116778 _i.Application.getRequestedAppControl = null;
116779
116780 // RequestedApplicationControl
116781 _i.RequestedApplicationControl.replyResult = {
116782     0: [_t.ApplicationControlData],
116783
116784     _optional: {
116785         0: true
116786     }
116787 };
116788
116789 _i.RequestedApplicationControl.replyFailure = null;
116790
116791 /*
116792  * Bluetooth
116793  */
116794
116795 // BluetoothManager
116796 _i.BluetoothManager.getDefaultAdapter = null;
116797
116798 // BluetoothAdapter
116799 _i.BluetoothAdapter.setName = {
116800     0: _t.DOMString,
116801     1: _t.SuccessCallback,
116802     2: _t.ErrorCallback,
116803
116804     _optional: {
116805         1: true,
116806         2: true
116807     }
116808 };
116809
116810 _i.BluetoothAdapter.setPowered = {
116811     0: _t.boolean,
116812     1: _t.SuccessCallback,
116813     2: _t.ErrorCallback,
116814
116815     _optional: {
116816         1: true,
116817         2: true
116818     }
116819 };
116820
116821 _i.BluetoothAdapter.setVisible = {
116822     0: _t.boolean,
116823     1: _t.SuccessCallback,
116824     2: _t.ErrorCallback,
116825     3: _t.unsigned_short,
116826
116827     _optional: {
116828         1: true,
116829         2: true,
116830         3: true
116831     }
116832 };
116833
116834 _i.BluetoothAdapter.setChangeListener = {
116835     0: _t.BluetoothAdapterChangeCallback
116836 };
116837
116838 _i.BluetoothAdapter.unsetChangeListener = null;
116839
116840 _i.BluetoothAdapter.discoverDevices = {
116841     0: _t.BluetoothDiscoverDevicesSuccessCallback,
116842     1: _t.ErrorCallback,
116843
116844     _optional: {
116845         1: true
116846     }
116847 };
116848
116849 _i.BluetoothAdapter.stopDiscovery = {
116850     0: _t.SuccessCallback,
116851     1: _t.ErrorCallback,
116852
116853     _optional: {
116854         0: true,
116855         1: true
116856     }
116857 };
116858
116859 _i.BluetoothAdapter.getKnownDevices = {
116860     0: _t.BluetoothDeviceArraySuccessCallback,
116861     1: _t.ErrorCallback,
116862
116863     _optional: {
116864         1: true
116865     }
116866 };
116867
116868 _i.BluetoothAdapter.getDevice = {
116869     0: _t.BluetoothAddress,
116870     1: _t.BluetoothDeviceSuccessCallback,
116871     2: _t.ErrorCallback,
116872
116873     _optional: {
116874         2: true
116875     }
116876 };
116877
116878 _i.BluetoothAdapter.createBonding = {
116879     0: _t.BluetoothAddress,
116880     1: _t.BluetoothDeviceSuccessCallback,
116881     2: _t.ErrorCallback,
116882
116883     _optional: {
116884         2: true
116885     }
116886 };
116887
116888 _i.BluetoothAdapter.destroyBonding = {
116889     0: _t.BluetoothAddress,
116890     1: _t.SuccessCallback,
116891     2: _t.ErrorCallback,
116892
116893     _optional: {
116894         1: true,
116895         2: true
116896     }
116897 };
116898
116899 _i.BluetoothAdapter.registerRFCOMMServiceByUUID = {
116900     0: _t.BluetoothUUID,
116901     1: _t.DOMString,
116902     2: _t.BluetoothServiceSuccessCallback,
116903     3: _t.ErrorCallback,
116904
116905     _optional: {
116906         3: true
116907     }
116908 };
116909
116910 _i.BluetoothAdapter.getBluetoothProfileHandler = {
116911     0: _t.BluetoothProfileType
116912 };
116913
116914 // BluetoothDevice
116915 _i.BluetoothDevice.connectToServiceByUUID = {
116916     0: _t.BluetoothUUID,
116917     1: _t.BluetoothSocketSuccessCallback,
116918     2: _t.ErrorCallback,
116919
116920     _optional: {
116921         2: true
116922     }
116923 };
116924
116925 // BluetoothSocket
116926 _i.BluetoothSocket.readData = null;
116927 _i.BluetoothSocket.close = null;
116928
116929 _i.BluetoothSocket.writeData = {
116930     0: [_t.byte]
116931 };
116932
116933 // BluetoothClass
116934 _i.BluetoothClass.hasService = {
116935     0: _t.unsigned_short
116936 };
116937
116938 // BluetoothServiceHandler
116939 _i.BluetoothServiceHandler.unregister = {
116940     0: _t.SuccessCallback,
116941     1: _t.ErrorCallback,
116942
116943     _optional: {
116944         0: true,
116945         1: true
116946     }
116947 };
116948
116949 // BluetoothHealthProfileHandler
116950 _i.BluetoothHealthProfileHandler.registerSinkApplication = {
116951     0: _t.unsigned_short,
116952     1: _t.DOMString,
116953     2: _t.BluetoothHealthApplicationSuccessCallback,
116954     3: _t.ErrorCallback,
116955
116956     _optional: {
116957         3: true
116958     }
116959 };
116960
116961 _i.BluetoothHealthProfileHandler.connectToSource = {
116962     0: _t.BluetoothDevice,
116963     1: _t.BluetoothHealthApplication,
116964     2: _t.BluetoothHealthChannelSuccessCallback,
116965     3: _t.ErrorCallback,
116966
116967     _optional: {
116968         3: true
116969     }
116970 };
116971
116972 // BluetoothHealthApplication
116973 _i.BluetoothHealthApplication.unregister = {
116974     0: _t.SuccessCallback,
116975     1: _t.ErrorCallback,
116976
116977     _optional: {
116978         0: true,
116979         1: true
116980     }
116981 };
116982
116983 // BluetoothHealthChannel
116984 _i.BluetoothHealthChannel.close = null;
116985 _i.BluetoothHealthChannel.unsetListener = null;
116986
116987 _i.BluetoothHealthChannel.sendData = {
116988     0: [_t.byte]
116989 };
116990
116991 _i.BluetoothHealthChannel.setListener = {
116992     0: _t.BluetoothHealthChannelChangeCallback
116993 };
116994
116995 /*
116996  * Bookmark
116997  */
116998
116999 // BookmarkManager
117000 _i.BookmarkManager.get = {
117001     0: _t.BookmarkFolder,
117002     1: _t.boolean,
117003
117004     _optional: {
117005         0: true,
117006         1: true
117007     }
117008 };
117009
117010 _i.BookmarkManager.add = {
117011     0: _t.Bookmark,
117012     1: _t.BookmarkFolder,
117013
117014     _optional: {
117015         1: true
117016     }
117017 };
117018
117019 _i.BookmarkManager.remove = {
117020     0: _t.Bookmark,
117021
117022     _optional: {
117023         0: true
117024     }
117025 };
117026
117027 /*
117028  * Calendar
117029  */
117030
117031 // CalendarManager
117032 _i.CalendarManager.getCalendars = {
117033     0: _t.CalendarType,
117034     1: _t.CalendarArraySuccessCallback,
117035     2: _t.ErrorCallback,
117036
117037     _optional: {
117038         2: true
117039     }
117040 };
117041
117042 _i.CalendarManager.getUnifiedCalendar = {
117043     0: _t.CalendarType
117044 };
117045
117046 _i.CalendarManager.getDefaultCalendar = {
117047     0: _t.CalendarType
117048 };
117049
117050 _i.CalendarManager.getCalendar = {
117051     0: _t.CalendarType,
117052     1: _t.CalendarId
117053 };
117054
117055 // Calendar
117056 _i.Calendar.get = {
117057     0: _t.CalendarItemId
117058 };
117059
117060 _i.Calendar.add = {
117061     0: _t.CalendarItem
117062 };
117063
117064 _i.Calendar.addBatch = {
117065     0: [_t.CalendarItem],
117066     1: _t.CalendarItemArraySuccessCallback,
117067     2: _t.ErrorCallback,
117068
117069     _optional: {
117070         1: true,
117071         2: true
117072     }
117073 };
117074
117075 _i.Calendar.update = {
117076     0: _t.CalendarItem,
117077     1: _t.boolean,
117078
117079     _optional: {
117080         1: true
117081     }
117082 };
117083
117084 _i.Calendar.updateBatch = {
117085     0: [_t.CalendarItem],
117086     1: _t.SuccessCallback,
117087     2: _t.ErrorCallback,
117088     3: _t.boolean,
117089
117090     _optional: {
117091         1: true,
117092         2: true,
117093         3: true
117094     }
117095 };
117096
117097 _i.Calendar.remove = {
117098     0: _t.CalendarItemId
117099 };
117100
117101 _i.Calendar.removeBatch = {
117102     0: [_t.CalendarItemId],
117103     1: _t.SuccessCallback,
117104     2: _t.ErrorCallback,
117105
117106     _optional: {
117107         1: true,
117108         2: true
117109     }
117110 };
117111
117112 _i.Calendar.find = {
117113     0: _t.CalendarItemArraySuccessCallback,
117114     1: _t.ErrorCallback,
117115     2: _t.AbstractFilter,
117116     3: _t.SortMode,
117117
117118     _optional: {
117119         1: true,
117120         2: true,
117121         3: true
117122     }
117123 };
117124
117125 _i.Calendar.addChangeListener = {
117126     0: _t.CalendarChangeCallback
117127 };
117128
117129 _i.Calendar.removeChangeListener = {
117130     0: _t.long
117131 };
117132
117133 // CalendarItem
117134 _i.CalendarItem.convertToString = {
117135     0: _t.CalendarTextFormat
117136 };
117137
117138 _i.CalendarItem.clone = null;
117139
117140 // CalendarEvent
117141 _i.CalendarEvent.expandRecurrence = {
117142     0: _t.TZDate,
117143     1: _t.TZDate,
117144     2: _t.CalendarEventArraySuccessCallback,
117145     3: _t.ErrorCallback,
117146
117147     _optional: {
117148         3: true
117149     }
117150 };
117151
117152 /*
117153  * Call History
117154  */
117155
117156 // CallHistory
117157 _i.CallHistory.find = {
117158     0: _t.CallHistoryEntryArraySuccessCallback,
117159     1: _t.ErrorCallback,
117160     2: _t.AbstractFilter,
117161     3: _t.SortMode,
117162     4: _t.unsigned_long,
117163     5: _t.unsigned_long,
117164
117165     _optional: {
117166         // nullable
117167         1: true,
117168         2: true,
117169         3: true,
117170         4: true,
117171         5: true
117172     }
117173 };
117174
117175 _i.CallHistory.remove = {
117176     0: _t.CallHistoryEntry
117177 };
117178
117179 _i.CallHistory.removeBatch = {
117180     0: [_t.CallHistoryEntry],
117181     1: _t.SuccessCallback,
117182     2: _t.ErrorCallback,
117183
117184     _optional: {
117185         // nullable
117186         1: true,
117187         2: true
117188     }
117189 };
117190
117191 _i.CallHistory.removeAll = {
117192     0: _t.SuccessCallback,
117193     1: _t.ErrorCallback,
117194
117195     _optional: {
117196         // nullable
117197         0: true,
117198         1: true
117199     }
117200 };
117201
117202 _i.CallHistory.addChangeListener = {
117203     0: _t.CallHistoryChangeCallback
117204 };
117205
117206 _i.CallHistory.removeChangeListener = {
117207     0: _t.long
117208 };
117209
117210 /*
117211  * Contact
117212  */
117213
117214 // ContactManager
117215 _i.ContactManager.getAddressBooks = {
117216     0: _t.AddressBookArraySuccessCallback,
117217     1: _t.ErrorCallback,
117218
117219     _optional: {
117220         1: true
117221     }
117222 };
117223
117224 _i.ContactManager.getUnifiedAddressBook = null;
117225 _i.ContactManager.getDefaultAddressBook = null;
117226
117227 _i.ContactManager.getAddressBook = {
117228     0: _t.AddressBookId
117229 };
117230
117231 _i.ContactManager.get = {
117232     0: _t.PersonId
117233 };
117234
117235 _i.ContactManager.update = {
117236     0: _t.Person
117237 };
117238
117239 _i.ContactManager.updateBatch = {
117240     0: [_t.Person],
117241     1: _t.SuccessCallback,
117242     2: _t.ErrorCallback,
117243
117244     _optional: {
117245         1: true,
117246         2: true
117247     }
117248 };
117249
117250 _i.ContactManager.remove = {
117251     0: _t.PersonId
117252 };
117253
117254 _i.ContactManager.removeBatch = {
117255     0: [_t.PersonId],
117256     1: _t.SuccessCallback,
117257     2: _t.ErrorCallback,
117258
117259     _optional: {
117260         1: true,
117261         2: true
117262     }
117263 };
117264
117265 _i.ContactManager.find = {
117266     0: _t.PersonArraySuccessCallback,
117267     1: _t.ErrorCallback,
117268     2: _t.AbstractFilter,
117269     3: _t.SortMode,
117270
117271     _optional: {
117272         1: true,
117273         2: true,
117274         3: true
117275     }
117276 };
117277
117278 _i.ContactManager.addChangeListener = {
117279     0: _t.PersonsChangeCallback
117280 };
117281
117282 _i.ContactManager.removeChangeListener = {
117283     0: _t.long
117284 };
117285
117286 // AddressBook
117287 _i.AddressBook.get = {
117288     0: _t.ContactId
117289 };
117290
117291 _i.AddressBook.add = {
117292     0: _t.Contact
117293 };
117294
117295 _i.AddressBook.addBatch = {
117296     0: [_t.Contact],
117297     1: _t.ContactArraySuccessCallback,
117298     2: _t.ErrorCallback,
117299
117300     _optional: {
117301         1: true,
117302         2: true
117303     }
117304 };
117305
117306 _i.AddressBook.update = {
117307     0: _t.Contact
117308 };
117309
117310 _i.AddressBook.updateBatch = {
117311     0: [_t.Contact],
117312     1: _t.SuccessCallback,
117313     2: _t.ErrorCallback,
117314
117315     _optional: {
117316         1: true,
117317         2: true
117318     }
117319 };
117320
117321 _i.AddressBook.remove = {
117322     0: _t.ContactId
117323 };
117324
117325 _i.AddressBook.removeBatch = {
117326     0: [_t.ContactId],
117327     1: _t.SuccessCallback,
117328     2: _t.ErrorCallback,
117329
117330     _optional: {
117331         1: true,
117332         2: true
117333     }
117334 };
117335
117336 _i.AddressBook.find = {
117337     0: _t.ContactArraySuccessCallback,
117338     1: _t.ErrorCallback,
117339     2: _t.AbstractFilter,
117340     3: _t.SortMode,
117341
117342     _optional:{
117343         1: true,
117344         2: true,
117345         3: true
117346     }
117347 };
117348
117349 _i.AddressBook.addChangeListener = {
117350     0: _t.AddressBookChangeCallback,
117351     1: _t.ErrorCallback,
117352
117353     _optional: {
117354         1: true
117355     }
117356 };
117357
117358 _i.AddressBook.removeChangeListener = {
117359     0: _t.long
117360 };
117361
117362 _i.AddressBook.getGroup = {
117363     0: _t.ContactGroupId
117364 };
117365
117366 _i.AddressBook.addGroup = {
117367     0: _t.ContactGroup
117368 };
117369
117370 _i.AddressBook.updateGroup = {
117371     0: _t.ContactGroup
117372 };
117373
117374 _i.AddressBook.removeGroup = {
117375     0: _t.ContactGroupId
117376 };
117377
117378 _i.AddressBook.getGroups = null;
117379
117380 // Person
117381 _i.Person.link = {
117382     0: _t.PersonId
117383 };
117384
117385 _i.Person.unlink = {
117386     0: _t.ContactId
117387 };
117388
117389 // Contact
117390 _i.Contact.convertToString = {
117391     0: _t.ContactTextFormat,
117392
117393     _optional: {
117394         0: true
117395     }
117396 };
117397
117398 _i.Contact.clone = null;
117399
117400 /*
117401  * Content
117402  */
117403
117404 // ContentManager
117405 _i.ContentManager.update = {
117406     0: _t.Content
117407 };
117408
117409 _i.ContentManager.updateBatch = {
117410     0: [_t.Content],
117411     1: _t.SuccessCallback,
117412     2: _t.ErrorCallback,
117413
117414     _optional: {
117415         1: true,
117416         2: true
117417     }
117418 };
117419
117420 _i.ContentManager.getDirectories = {
117421     0: _t.ContentDirectoryArraySuccessCallback,
117422     1: _t.ErrorCallback,
117423
117424     _optional: {
117425         1: true
117426     }
117427 };
117428
117429 _i.ContentManager.find = {
117430     0: _t.ContentArraySuccessCallback,
117431     1: _t.ErrorCallback,
117432     2: _t.ContentDirectoryId,
117433     3: _t.AbstractFilter,
117434     4: _t.SortMode,
117435     5: _t.unsigned_long,
117436     6: _t.unsigned_long,
117437
117438     _optional: {
117439         1: true,
117440         2: true,
117441         3: true,
117442         4: true,
117443         5: true,
117444         6: true
117445     }
117446 };
117447
117448 _i.ContentManager.scanFile = {
117449     0: _t.DOMString,
117450     1: _t.ContentScanSuccessCallback,
117451     2: _t.ErrorCallback,
117452
117453     _optional: {
117454         1: true,
117455         2: true
117456     }
117457 };
117458
117459 _i.ContentManager.setChangeListener = {
117460     0: _t.ContentChangeCallback
117461 };
117462
117463 _i.ContentManager.unsetChangeListener = null;
117464
117465 /*
117466  * Data Control
117467  */
117468
117469 // DataControlManager
117470 _i.DataControlManager.getDataControlConsumer = {
117471     0: _t.DOMString,
117472     1: _t.DOMString,
117473     2: _t.DataType
117474 };
117475
117476 // SQLDataControlConsumer
117477 _i.SQLDataControlConsumer.insert = {
117478     0: _t.unsigned_long,
117479     1: _t.RowData,
117480     2: _t.DataControlInsertSuccessCallback,
117481     3: _t.DataControlErrorCallback,
117482
117483     _optional: {
117484         2: true,
117485         3: true
117486     }
117487 };
117488
117489 _i.SQLDataControlConsumer.update = {
117490     0: _t.unsigned_long,
117491     1: _t.RowData,
117492     2: _t.DOMString,
117493     3: _t.DataControlSuccessCallback,
117494     4: _t.DataControlErrorCallback,
117495
117496     _optional: {
117497         3: true,
117498         4: true
117499     }
117500 };
117501
117502 _i.SQLDataControlConsumer.remove = {
117503     0: _t.unsigned_long,
117504     1: _t.DOMString,
117505     2: _t.DataControlSuccessCallback,
117506     3: _t.DataControlErrorCallback,
117507
117508     _optional: {
117509         2: true,
117510         3: true
117511     }
117512 };
117513
117514 _i.SQLDataControlConsumer.select = {
117515     0: _t.unsigned_long,
117516     1: [_t.DOMString],
117517     2: _t.DOMString,
117518     3: _t.DataControlSelectSuccessCallback,
117519     4: _t.DataControlErrorCallback,
117520     5: _t.unsigned_long,
117521     6: _t.unsigned_long,
117522
117523     _optional: {
117524         4: true,
117525         5: true,
117526         6: true
117527     }
117528 };
117529
117530 // MappedDataControlConsumer
117531 _i.MappedDataControlConsumer.addValue = {
117532     0: _t.unsigned_long,
117533     1: _t.DOMString,
117534     2: _t.DOMString,
117535     3: _t.DataControlSuccessCallback,
117536     4: _t.DataControlErrorCallback,
117537
117538     _optional: {
117539         3: true,
117540         4: true
117541     }
117542 };
117543
117544 _i.MappedDataControlConsumer.removeValue = {
117545     0: _t.unsigned_long,
117546     1: _t.DOMString,
117547     2: _t.DOMString,
117548     3: _t.DataControlSuccessCallback,
117549     4: _t.DataControlErrorCallback,
117550
117551     _optional: {
117552         4: true
117553     }
117554 };
117555
117556 _i.MappedDataControlConsumer.getValue = {
117557     0: _t.unsigned_long,
117558     1: _t.DOMString,
117559     2: _t.DataControlGetValueSuccessCallback,
117560     3: _t.DataControlErrorCallback,
117561
117562     _optional: {
117563         3: true
117564     }
117565 };
117566
117567 _i.MappedDataControlConsumer.updateValue = {
117568     0: _t.unsigned_long,
117569     1: _t.DOMString,
117570     2: _t.DOMString,
117571     3: _t.DOMString,
117572     4: _t.DataControlSuccessCallback,
117573     5: _t.DataControlErrorCallback,
117574
117575     _optional: {
117576         5: true
117577     }
117578 };
117579
117580 /*
117581  * Data Synchronization
117582  */
117583
117584 // DataSynchronizationManager
117585 _i.DataSynchronizationManager.getMaxProfilesNum = null;
117586 _i.DataSynchronizationManager.getProfilesNum    = null;
117587 _i.DataSynchronizationManager.getAll            = null;
117588
117589 _i.DataSynchronizationManager.add = {
117590     0: _t.SyncProfileInfo
117591 };
117592
117593 _i.DataSynchronizationManager.update = {
117594     0: _t.SyncProfileInfo
117595 };
117596
117597 _i.DataSynchronizationManager.remove = {
117598     0: _t.SyncProfileId
117599 };
117600
117601 _i.DataSynchronizationManager.get = {
117602     0: _t.SyncProfileId
117603 };
117604
117605 _i.DataSynchronizationManager.startSync = {
117606     0: _t.SyncProfileId,
117607     1: _t.SyncProgressCallback,
117608
117609     _optional: {
117610         1: true
117611     }
117612 };
117613
117614 _i.DataSynchronizationManager.stopSync = {
117615     0: _t.SyncProfileId
117616 };
117617
117618 _i.DataSynchronizationManager.getLastSyncStatistics = {
117619     0: _t.SyncProfileId
117620 };
117621
117622 /*
117623  * Download
117624  */
117625
117626 // DownloadManager
117627 _i.DownloadManager.start = {
117628     0: _t.DownloadRequest,
117629     1: _t.DownloadCallback,
117630
117631     _optional: {
117632         1: true
117633     }
117634 };
117635
117636 _i.DownloadManager.cancel = {
117637     0: _t.long
117638 };
117639
117640 _i.DownloadManager.pause = {
117641     0: _t.long
117642 };
117643
117644 _i.DownloadManager.resume = {
117645     0: _t.long
117646 };
117647
117648 _i.DownloadManager.getState = {
117649     0: _t.long
117650 };
117651
117652 _i.DownloadManager.getDownloadRequest = {
117653     0: _t.long
117654 };
117655
117656 _i.DownloadManager.getMIMEType = {
117657     0: _t.long
117658 };
117659
117660 _i.DownloadManager.setListener = {
117661     0: _t.long,
117662     1: _t.DownloadCallback
117663 };
117664
117665 /*
117666  * Network Bearer Selection
117667  */
117668
117669 // NetworkBearerSelection
117670 _i.NetworkBearerSelection.requestRouteToHost = {
117671     0: _t.NetworkType,
117672     1: _t.DOMString,
117673     2: _t.NetworkSuccessCallback,
117674     3: _t.ErrorCallback,
117675
117676     _optional: {
117677         3: true
117678     }
117679 };
117680
117681 _i.NetworkBearerSelection.releaseRouteToHost = {
117682     0: _t.NetworkType,
117683     1: _t.DOMString,
117684     2: _t.SuccessCallback,
117685     3: _t.ErrorCallback,
117686
117687     _optional: {
117688         3: true
117689     }
117690 };
117691
117692 /*
117693  * NFC
117694  */
117695
117696 // NFCManager
117697 _i.NFCManager.getDefaultAdapter = null;
117698 _i.NFCManager.setExclusiveMode = {
117699     0: _t.boolean
117700 };
117701
117702 // NFCAdapter
117703 _i.NFCAdapter.setPowered = {
117704     0: _t.boolean,
117705     1: _t.SuccessCallback,
117706     2: _t.ErrorCallback,
117707
117708     _optional: {
117709         1: true,
117710         2: true
117711     }
117712 };
117713
117714 _i.NFCAdapter.setTagListener = {
117715     0: _t.NFCTagDetectCallback,
117716     1: [_t.NFCTagType],
117717
117718     _optional: {
117719         1: true
117720     }
117721 };
117722
117723 _i.NFCAdapter.setPeerListener = {
117724     0: _t.NFCPeerDetectCallback
117725 };
117726
117727 _i.NFCAdapter.unsetTagListener  = null;
117728 _i.NFCAdapter.unsetPeerListener = null;
117729 _i.NFCAdapter.getCachedMessage  = null;
117730
117731 // NFCTag
117732 _i.NFCTag.readNDEF = {
117733     0: _t.NDEFMessageReadCallback,
117734     1: _t.ErrorCallback,
117735
117736     _optional: {
117737         1: true
117738     }
117739 };
117740
117741 _i.NFCTag.writeNDEF = {
117742     0: _t.NDEFMessage,
117743     1: _t.SuccessCallback,
117744     2: _t.ErrorCallback,
117745
117746     _optional: {
117747         1: true,
117748         2: true
117749     }
117750 };
117751
117752 _i.NFCTag.transceive = {
117753     0: [_t.byte],
117754     1: _t.ByteArraySuccessCallback,
117755     2: _t.ErrorCallback,
117756
117757     _optional: {
117758         2: true
117759     }
117760 };
117761
117762 // NFCPeer
117763 _i.NFCPeer.setReceiveNDEFListener = {
117764     0: _t.NDEFMessageReadCallback
117765 };
117766
117767 _i.NFCPeer.unsetReceiveNDEFListener = null;
117768
117769 _i.NFCPeer.sendNDEF = {
117770     0: _t.NDEFMessage,
117771     1: _t.SuccessCallback,
117772     2: _t.ErrorCallback,
117773
117774     _optional: {
117775         1: true,
117776         2: true
117777     }
117778 };
117779
117780 // NDEFMessage
117781 _i.NDEFMessage.toByte = null;
117782
117783 /*
117784  * Notification
117785  */
117786
117787 // NotificationManager
117788 _i.NotificationManager.post = {
117789     0: _t.Notification
117790 };
117791
117792 _i.NotificationManager.update = {
117793     0: _t.Notification
117794 };
117795
117796 _i.NotificationManager.remove = {
117797     0: _t.NotificationId
117798 };
117799
117800 _i.NotificationManager.get = {
117801     0: _t.NotificationId
117802 };
117803
117804 _i.NotificationManager.removeAll = null;
117805 _i.NotificationManager.getAll = null;
117806
117807 /*
117808  * Package
117809  */
117810
117811 // PackageManager
117812 _i.PackageManager.install = {
117813     0: _t.DOMString,
117814     1: _t.PackageProgressCallback,
117815     2: _t.ErrorCallback,
117816
117817     _optional: {
117818         2: true
117819     }
117820 };
117821
117822 _i.PackageManager.uninstall = {
117823     0: _t.PackageId,
117824     1: _t.PackageProgressCallback,
117825     2: _t.ErrorCallback,
117826
117827     _optional: {
117828         2: true
117829     }
117830 };
117831
117832 _i.PackageManager.getPackagesInfo = {
117833     0: _t.PackageInformationArraySuccessCallback,
117834     1: _t.ErrorCallback,
117835
117836     _optional: {
117837         1: true
117838     }
117839 };
117840
117841 _i.PackageManager.getPackageInfo = {
117842     0: _t.PackageId,
117843
117844     _optional: {
117845         0: true
117846     }
117847 };
117848
117849 _i.PackageManager.setPackageInfoEventListener = {
117850     0: _t.PackageInfomationEventCallback
117851 };
117852
117853 _i.PackageManager.unsetPackageInfoEventListener = null;
117854
117855 /*
117856  * Push
117857  */
117858
117859 // PushManager
117860 _i.PushManager.registerService = {
117861     0: _t.ApplicationControl,
117862     1: _t.PushRegisterSuccessCallback,
117863     2: _t.ErrorCallback,
117864
117865     _optional: {
117866         2: true
117867     }
117868 };
117869
117870 _i.PushManager.unregisterService = {
117871     0: _t.SuccessCallback,
117872     1: _t.ErrorCallback,
117873
117874     _optional: {
117875         0: true,
117876         1: true
117877     }
117878 };
117879
117880 _i.PushManager.connectService = {
117881     0: _t.PushNotificationCallback
117882 };
117883
117884 _i.PushManager.disconnectService = null;
117885 _i.PushManager.getRegistrationId = null;
117886
117887 /*
117888  * System Info
117889  */
117890
117891 // SystemInfo
117892 _i.SystemInfo.getCapabilities = null;
117893
117894 _i.SystemInfo.getPropertyValue = {
117895     0: _t.SystemInfoPropertyId,
117896     1: _t.SystemInfoPropertySuccessCallback,
117897     2: _t.ErrorCallback,
117898
117899     _optional: {
117900         2: true
117901     }
117902 };
117903
117904 _i.SystemInfo.addPropertyValueChangeListener = {
117905     0: _t.SystemInfoPropertyId,
117906     1: _t.SystemInfoPropertySuccessCallback,
117907     2: _t.SystemInfoOptions,
117908
117909     _optional: {
117910         2: true
117911     }
117912 };
117913
117914 _i.SystemInfo.removePropertyValueChangeListener = {
117915     0: _t.unsigned_long
117916 };
117917
117918 /*
117919  * System Setting
117920  */
117921
117922 // SystemSettingManager
117923 _i.SystemSettingManager.setProperty = {
117924     0: _t.SystemSettingType,
117925     1: _t.DOMString,
117926     2: _t.SuccessCallback,
117927     3: _t.ErrorCallback,
117928
117929     _optional: {
117930         3: true
117931     }
117932 };
117933
117934 _i.SystemSettingManager.getProperty = {
117935     0: _t.SystemSettingType,
117936     1: _t.SystemSettingSuccessCallback,
117937     2: _t.ErrorCallback,
117938
117939     _optional: {
117940         2: true
117941     }
117942 };
117943
117944 /*
117945  * Time
117946  */
117947
117948 // TimeUtil
117949 _i.TimeUtil.getCurrentDateTime    = null;
117950 _i.TimeUtil.getLocalTimezone      = null;
117951 _i.TimeUtil.getAvailableTimezones = null;
117952 _i.TimeUtil.getTimeFormat         = null;
117953
117954 _i.TimeUtil.getDateFormat = {
117955     0: _t.boolean,
117956
117957     _optional: {
117958         0: true
117959     }
117960 };
117961
117962 _i.TimeUtil.isLeapYear = {
117963     0: _t.long
117964 };
117965
117966 // TimeDuration
117967 _i.TimeDuration.difference = {
117968     0: _t.TimeDuration
117969 };
117970
117971 _i.TimeDuration.equalsTo = {
117972     0: _t.TimeDuration
117973 };
117974
117975 _i.TimeDuration.lessThan = {
117976     0: _t.TimeDuration
117977 };
117978
117979 _i.TimeDuration.greaterThan = {
117980     0: _t.TimeDuration
117981 };
117982
117983 _i.Vehicle.getSupported = {
117984     0: _t.SupportedPropertiesSuccessCallback,
117985     1: _t.VehiclePropertyErrorCallback
117986 }
117987
117988 // Exports
117989 _t.constructor = _c;
117990 _t.interface   = _i;
117991
117992 module.exports = _t;
117993
117994 });
117995 define('ripple/platform/tizen/2.0/vibration', function (require, exports, module) {
117996 /*
117997  *  Copyright 2012 Intel Corporation.
117998  *
117999  * Licensed under the Apache License, Version 2.0 (the "License");
118000  * you may not use this file except in compliance with the License.
118001  * You may obtain a copy of the License at
118002  *
118003  * http://www.apache.org/licenses/LICENSE-2.0
118004  *
118005  * Unless required by applicable law or agreed to in writing, software
118006  * distributed under the License is distributed on an "AS IS" BASIS,
118007  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118008  * See the License for the specific language governing permissions and
118009  * limitations under the License.
118010  */
118011
118012 var event = require('ripple/event'),
118013     deviceSettings = require('ripple/deviceSettings'),
118014     constants = require('ripple/constants'),
118015     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
118016     emulatorBridge = require('ripple/emulatorBridge'),
118017     curPost,
118018     _self;
118019
118020 function isVibratorOn() {
118021     return deviceSettings.retrieve("Config.vibratingMode");
118022 }
118023
118024 var vibrator = (function () {
118025     var vibratorPattern,
118026         isVibrating = false,
118027         runTime = 0,
118028         vibrateTimeout = null,
118029         MILLILSECONDS_OF_ONE_VIBRATION = 100,
118030         node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
118031         movementIndex = 0,
118032         movement = [{ left: -10 }, { left: 0 }, { left: 10 }, { left: 0 },
118033                     {top: -10 }, { top: 0 }, {top: 10 }, { top: 0 }];
118034
118035     function _clearTimeout() {
118036         if (vibrateTimeout) {
118037             clearInterval(vibrateTimeout);
118038             vibrateTimeout = null;
118039         }
118040     }
118041
118042     function stopVibrate() {
118043         isVibrating = false;
118044         _clearTimeout();
118045         node.css({left: 0, top: 0}, MILLILSECONDS_OF_ONE_VIBRATION);
118046     }
118047
118048     function vibrate() {
118049         node.css(movement[movementIndex]);
118050         movementIndex = (movementIndex + 1) % 8;
118051     }
118052
118053     function changePulse() {
118054         if (emulatorBridge.document().hidden) {
118055             return;
118056         }
118057
118058         //run time
118059         runTime = runTime + MILLILSECONDS_OF_ONE_VIBRATION;
118060         if (curPost >= vibratorPattern.length) {
118061             setTimeout(stopVibrate, 1);
118062         }
118063         if (runTime > vibratorPattern[curPost]) {
118064             curPost = curPost + 1;
118065             runTime = 0;
118066         } else {
118067             if ((curPost % 2) === 0) {
118068                 vibrate();
118069             }
118070         }
118071     }
118072
118073     function startVibrate(_pattern) {
118074         if (!isVibratorOn())
118075             return;
118076
118077         vibratorPattern = _pattern;
118078         _clearTimeout();
118079         movementIndex = 0;
118080         if (_pattern) {
118081             runTime = 0;
118082             vibrateTimeout = setInterval(changePulse, MILLILSECONDS_OF_ONE_VIBRATION);
118083         }
118084         isVibrating = true;
118085     }
118086
118087     return {
118088         isVibrating: isVibrating,
118089         startVibrate: startVibrate,
118090         stopVibrate: stopVibrate
118091     };
118092 }());
118093
118094 _self = {
118095     vibrate: function () {
118096         var pattern = arguments[0],
118097             i;
118098
118099         // If vibrator is off, stop the vibration
118100         event.on("VibratingModeChanged", function (value) {
118101             if (value === false) {
118102                 vibrator.stopVibrate();
118103             }
118104         });
118105
118106         //1. If the hidden attribute [PAGE-VISIBILITY] is set to true, abort these steps.
118107         if (emulatorBridge.document().hidden) {
118108             return;
118109         }
118110
118111         //2. Let pattern be the value of the first argument.
118112         if (!tizen1_utils.isValidArray(pattern)) {
118113             pattern |= 0;
118114         } else {
118115             for (i = 0; i < pattern.length; i++) {
118116                 pattern[i] |= 0;
118117             }
118118         }
118119
118120         //3. If pattern is 0, or an empty list, cancel the pre-existing instance of the processing vibration patterns algorithm, if any, and abort these steps.
118121         if (pattern === 0 || (tizen1_utils.isValidArray(pattern) && pattern.length === 0)) {
118122             vibrator.stopVibrate();
118123             return;
118124         }
118125
118126         //4. If pattern is a list, proceed to the next step. Otherwise run the following substeps:
118127         //a. Let list be an initially empty list, and add pattern to list.
118128         //b. Let pattern be list.
118129         if (!tizen1_utils.isValidArray(pattern)) {
118130             pattern = [pattern];
118131         }
118132
118133         //5. If any entry of pattern exceeds an implementation-dependent limit, then the user agent may throw a NotSupportedError exception and abort these steps.
118134
118135         //6. If the length of pattern is even, then remove the last entry in pattern.
118136         if (pattern.length % 2 === 0) {
118137             pattern.pop();
118138         }
118139
118140         //7. Cancel the pre-existing instance of the processing vibration patterns algorithm, if any.
118141         if (vibrator.isVibrating) {
118142             vibrator.stopVibrate();
118143         }
118144
118145         curPost = 0;
118146         vibrator.startVibrate(pattern);
118147     }
118148 };
118149
118150 module.exports = _self;
118151
118152 });
118153 define('ripple/platform/w3c/1.0/Acceleration', function (require, exports, module) {
118154 module.exports = function (x, y, z) {
118155     return {
118156         x: x || 0,    //Acceleration in the 'x' expressed in m/s^2. (Number)
118157         y: y || 0,    //Acceleration in the 'y' expressed in m/s^2. (Number)
118158         z: z || 0     //Acceleration in the 'z' expressed in m/s^2. (Number)
118159     };
118160 };
118161
118162 });
118163 define('ripple/platform/w3c/1.0/Coordinates', function (require, exports, module) {
118164 /*
118165  *  Copyright 2011 Research In Motion Limited.
118166  *
118167  * Licensed under the Apache License, Version 2.0 (the "License");
118168  * you may not use this file except in compliance with the License.
118169  * You may obtain a copy of the License at
118170  *
118171  * http://www.apache.org/licenses/LICENSE-2.0
118172  *
118173  * Unless required by applicable law or agreed to in writing, software
118174  * distributed under the License is distributed on an "AS IS" BASIS,
118175  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118176  * See the License for the specific language governing permissions and
118177  * limitations under the License.
118178  */
118179 module.exports = function (latitude, longitude, altitude, accuracy, altitudeAccuracy, heading, speed) {
118180     return {
118181         latitude: latitude || 0,                    //Latitude in decimal degrees. (Number)
118182         longitude: longitude || 0,                  //Longitude in decimal degrees. (Number)
118183         altitude: altitude || 0,                    //Height of the position in meters above the ellipsoid. (Number)
118184         accuracy: accuracy || 0,                    //Accuracy level of the latitude and longitude coordinates in meters. (Number)
118185         altitudeAccuracy: altitudeAccuracy || 0,    //Accuracy level of the altitude coordinate in meters. (Number)
118186         heading: heading || 0,                      //Direction of travel, specified in degrees counting clockwise relative to the true north. (Number)
118187         speed: speed || 0                           //Current ground speed of the device, specified in meters per second. (Number)
118188     };
118189 };
118190
118191 });
118192 define('ripple/platform/w3c/1.0/Position', function (require, exports, module) {
118193 /*
118194  *  Copyright 2011 Research In Motion Limited.
118195  *
118196  * Licensed under the Apache License, Version 2.0 (the "License");
118197  * you may not use this file except in compliance with the License.
118198  * You may obtain a copy of the License at
118199  *
118200  * http://www.apache.org/licenses/LICENSE-2.0
118201  *
118202  * Unless required by applicable law or agreed to in writing, software
118203  * distributed under the License is distributed on an "AS IS" BASIS,
118204  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118205  * See the License for the specific language governing permissions and
118206  * limitations under the License.
118207  */
118208 var Coordinates = require('ripple/platform/w3c/1.0/Coordinates');
118209
118210 module.exports = function () {
118211     return {
118212         coords: new Coordinates(),
118213         timestamp: new Date().getTime()
118214     };
118215 };
118216
118217 });
118218 define('ripple/platform/w3c/1.0/PositionError', function (require, exports, module) {
118219 /*
118220  *  Copyright 2011 Research In Motion Limited.
118221  *
118222  * Licensed under the Apache License, Version 2.0 (the "License");
118223  * you may not use this file except in compliance with the License.
118224  * You may obtain a copy of the License at
118225  *
118226  * http://www.apache.org/licenses/LICENSE-2.0
118227  *
118228  * Unless required by applicable law or agreed to in writing, software
118229  * distributed under the License is distributed on an "AS IS" BASIS,
118230  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118231  * See the License for the specific language governing permissions and
118232  * limitations under the License.
118233  */
118234 var _self = function () {
118235     return {
118236         code: undefined,
118237         message: undefined
118238     };
118239 };
118240
118241 _self.PERMISSION_DENIED = "PERMISSION_DENIED";
118242 _self.POSITION_UNAVAILABLE = "POSITION_UNAVAILABLE";
118243 _self.TIMEOUT = "TIMEOUT";
118244
118245 module.exports = _self;
118246
118247 });
118248 define('ripple/platform/w3c/1.0/Rotation', function (require, exports, module) {
118249 module.exports = function (alpha, beta, gamma) {
118250     return {
118251         alpha: alpha || 0,    //Rotation about the 'z' axis expressed in degrees [0, 360].    (Number)
118252         beta: beta || 0,      //Rotation about the 'x' axis expressed in degrees [-180, 180]. (Number)
118253         gamma: gamma || 0     //Rotation about the 'y' axis expressed in degrees [-90, 90].   (Number)
118254     };
118255 };
118256
118257 });
118258 define('ripple/platform/w3c/1.0/SensorConnection', function (require, exports, module) {
118259 /*
118260  *  Copyright 2012 Intel Corporation.
118261  *
118262  * Licensed under the Apache License, Version 2.0 (the "License");
118263  * you may not use this file except in compliance with the License.
118264  * You may obtain a copy of the License at
118265  *
118266  * http://www.apache.org/licenses/LICENSE-2.0
118267  *
118268  * Unless required by applicable law or agreed to in writing, software
118269  * distributed under the License is distributed on an "AS IS" BASIS,
118270  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118271  * See the License for the specific language governing permissions and
118272  * limitations under the License.
118273  */
118274
118275 var utils = require('ripple/utils'),
118276     platform = require('ripple/platform'),
118277     event = require('ripple/event'),
118278     sensorSettings = require('ripple/sensorSettings'),
118279     accelerometer = require('ripple/accelerometer'),
118280     exception = require('ripple/exception'),
118281
118282     _permission = true,
118283     _self;
118284
118285 function ErrorMsg() {
118286     this.__defineGetter__("UNKNOWN_ERROR", function () {
118287         return "An unknown error has occurred.";
118288     });
118289
118290     this.__defineGetter__("TYPE_MISMATCH_ERROR", function () {
118291         return "The object type is incompatible with the expected type.";
118292     });
118293
118294     this.__defineGetter__("INVALID_VALUES_ERROR", function () {
118295         return "The content of an object does not contain valid values.";
118296     });
118297
118298     this.__defineGetter__("ILLEGAL_STATE", function () {
118299         return "The status of connection is illegal.";
118300     });
118301 }
118302
118303 // TODO: Should be replaced by a global object in tizen 1.0
118304 function ErrorCode() {
118305     this.__defineGetter__("UNKNOWN_ERR", function () {
118306         return 0;
118307     });
118308
118309     this.__defineGetter__("INVALID_VALUES_ERROR", function () {
118310         return 1;
118311     });
118312
118313     this.__defineGetter__("TYPE_MISMATCH_ERROR", function () {
118314         return 2;
118315     });
118316
118317     this.__defineGetter__("ILLEGAL_STATE", function () {
118318         return 3;
118319     });
118320 }
118321
118322 function SensorError(code, msg) {
118323     this.__defineGetter__("message", function () {
118324         return msg;
118325     });
118326     this.__defineGetter__("code", function () {
118327         return code;
118328     });
118329
118330     this.PERMISSION_DENIED = -100;
118331 }
118332
118333 function Event() {
118334     var _self = {
118335         CAPTURING_PHASE: 1,
118336         AT_TARGET:  2,
118337         BUBBLING_PHASE: 3,
118338
118339         type: '',
118340         target: null, //new EventTarget(),
118341         currentTarget: null, //new EventTarget(),
118342         eventPhase: 0,
118343         bubbles: false,
118344         cancelable: false,
118345         timeStamp: 0
118346     };
118347         
118348     this.__defineGetter__("type", function () {
118349         return _self.type;
118350     });
118351
118352     this.__defineGetter__("target", function () {
118353         return _self.target;
118354     });
118355
118356     this.__defineGetter__("currentTarget", function () {
118357         return _self.currentTarget;
118358     });
118359
118360     this.__defineGetter__("eventPhase", function () {
118361         return _self.eventPhase;
118362     });    
118363
118364     this.__defineGetter__("bubbles", function () {
118365         return _self.bubbles;
118366     });
118367
118368     this.__defineGetter__("cancelable", function () {
118369         return _self.cancelable;
118370     });
118371     
118372     this.__defineGetter__("timeStamp", function () {
118373         return _self.timeStamp;
118374     });
118375
118376     this.stopPropagation = function () {};
118377
118378     this.preventDefault = function () {};
118379
118380     this.initEvent = function (eventTypeArg, canBubbleArg, cancelableArg) {
118381         _self.type = eventTypeArg;
118382         _self.bubbles = canBubbleArg;
118383         _self.cancelable = cancelableArg;
118384     };
118385
118386     return _self;
118387 }
118388
118389 function SensorDataEvent() {
118390     var _self = {
118391         data: 0,
118392         accuracy: 0,
118393         timestamp: 0,
118394         reason: ''
118395     };
118396
118397     // This type of event inherit from Event
118398     Event.call(this);
118399
118400     this.__defineGetter__("data", function () {
118401         return _self.data;
118402     });
118403
118404     this.__defineGetter__("accuracy", function () {
118405         return _self.accuracy;
118406     });
118407
118408     this.__defineGetter__("timestamp", function () {
118409         return _self.timestamp;
118410     });
118411
118412     this.__defineGetter__("reason", function () {
118413         return _self.reason;
118414     });
118415
118416     this.initSensorDataEvent = function (type, bubbles, cancelable, reason, timestamp, accuracy, data) {
118417         this.initEvent(type, bubbles, cancelable);
118418
118419         _self.reason = reason;
118420         _self.timestamp = timestamp;
118421         _self.accuracy = accuracy;
118422         
118423         // If the data has only one part, just return the value, not the data object    
118424         if (utils.count(data) === 1) {
118425             utils.forEach(data, function (section, key) {
118426                 _self.data = data[key];
118427             });
118428         }
118429         else {
118430             _self.data = utils.copy(data);
118431         }
118432     };
118433 }
118434
118435 // As only one sensor will be used during the simulation with a SensorConnection object,
118436 // we can get that sensor object first and then the following read or write operations will be simplified
118437 function _getSensorObj(type, name) {
118438     var settings = platform.current().sensor, _sensor;
118439
118440     utils.forEach(settings, function (settingSection, settingType) {
118441         if (settingSection.type === type) {
118442
118443             if (settingSection.name && settingSection.name !== name) {
118444                 return;
118445             }
118446
118447             _sensor = utils.copy(settingSection);
118448         }
118449     });
118450
118451     return _sensor;
118452 }
118453
118454 function _getAccelerometerData(dataType) {
118455     var accelerometerData, data = {};
118456
118457     switch (dataType) {
118458     case "Accelerometer":
118459         accelerometerData = accelerometer.getInfo();
118460         data = {
118461             x: accelerometerData.acceleration.x,
118462             y: accelerometerData.acceleration.y,
118463             z: accelerometerData.acceleration.z
118464         };
118465         break;
118466     case "Rotation":
118467         accelerometerData = accelerometer.getInfo();
118468         data = {
118469             x: accelerometerData.orientation.alpha,
118470             y: accelerometerData.orientation.beta,
118471             z: accelerometerData.orientation.gamma
118472         };
118473         break;
118474     case "Orientation":
118475         accelerometerData = accelerometer.getInfo();
118476         data = {
118477             alpha: accelerometerData.orientation.alpha,
118478             beta: accelerometerData.orientation.beta,
118479             gamma: accelerometerData.orientation.gamma
118480         };
118481         break;
118482     default:
118483         break;
118484     }
118485
118486     return data;
118487 }
118488
118489 // The parameter of event callback is an object that contains the latest value, not the value itself,
118490 // so we need a function to create such object.
118491 function _getSensorData(sensorType, sensor, onerror) {
118492     var data = {}, value;
118493
118494     if (sensorType === "Accelerometer" || sensorType === "Rotation" || sensorType === "Orientation") {
118495         return _getAccelerometerData(sensorType);
118496     }
118497
118498     utils.forEach(sensor, function (sensorSection, key) {
118499         try {
118500             value = sensorSettings.retrieve(sensorType + "." + key);
118501         }
118502         catch (e) {
118503             if (onerror) {
118504                 onerror(e);
118505             }
118506         }
118507         
118508         if (value) {
118509             data[key] = value;
118510         }                    
118511     });
118512     
118513     return data;
118514 }
118515
118516 // As the event type in sensor.js file are named in this way, so we can get it with this function.
118517 function _getSensorEventTypes(type, sensor) {
118518     var types = [];
118519
118520     if (type === "Accelerometer" || type === "Rotation" || type === "Orientation") {
118521         return ["AccelerometerInfoChangedEvent"];
118522     }
118523
118524     utils.forEach(sensor, function (sensorSection, sensorType) {
118525         if (typeof sensorSection === "object") {
118526             types.push(type + "-" + sensorType + "Changed");
118527         }
118528     });
118529
118530     return types;
118531 }
118532
118533 function _onEventCallback(type, options, currentSensor, length, eventCallback, onerror) {
118534     return function (values) {
118535         var sensorEvent = new SensorDataEvent();
118536
118537         // Only the sensor that has one attribute could be compared with the threshold
118538         if (options && options.threshold && length === 1 && values[0] < options.threshold) {
118539             return;
118540         }
118541
118542         if (eventCallback) {
118543             sensorEvent.initSensorDataEvent(type, false, false, "read", (new Date()).getTime(), 
118544                                             currentSensor.resolution, _getSensorData(type, currentSensor, onerror));
118545
118546             eventCallback(sensorEvent);
118547         }
118548     };
118549 }
118550
118551 function _bind(name, obj) {
118552     var callback = null;
118553
118554     obj.__defineGetter__(name, function () {
118555         return callback;
118556     });
118557
118558     obj.__defineSetter__(name, function (cb) {
118559         callback = cb;
118560     });
118561
118562     return {
118563         get: function () {
118564             return callback;
118565         },
118566         set: function (value) {
118567             callback = value;
118568         },
118569         exec: function (arg) {
118570             return callback && callback(arg);
118571         },
118572         unbind: function (cb) {
118573             callback = cb === callback ? null : callback;
118574         }
118575     };
118576 }
118577
118578 function SensorConnection(type, name) {
118579     var _self,
118580         currentSensor = _getSensorObj(type, name),
118581         sensorEvent = new SensorDataEvent(),
118582         sensorEventTypes = _getSensorEventTypes(type, currentSensor),
118583         watches = [],
118584         _errorCode = new ErrorCode(),
118585         _errorMsg = new ErrorMsg(),
118586         sensorListener;
118587
118588     if (currentSensor) {
118589         _self = {
118590             sensor: {
118591                 resolution: currentSensor.resolution,
118592                 minDelay: currentSensor.minDelay,
118593                 range: currentSensor.range,
118594                 name: currentSensor.name,
118595                 type: currentSensor.type
118596             },
118597             status: "open",
118598             error: null,
118599             read: function () {
118600
118601                 if (_self.status !== "open" && _self.status !== "watching") {
118602                     exception.raise(exception.types.Argument, "illegal state", new SensorError(_errorCode.ILLEGAL_STATE, _errorMsg.ILLEGAL_STATE));
118603                     return;
118604                 }                
118605
118606                 setTimeout(function () {
118607                     if (sensorListener.get()) {
118608                         sensorEvent.initSensorDataEvent(type, false, false, "read", (new Date()).getTime(), 
118609                                                         currentSensor.resolution, _getSensorData(type, currentSensor, _self.onerror));
118610
118611                         sensorListener.exec(sensorEvent);
118612                     }
118613                 }, 1);  
118614
118615                 return;
118616             },
118617
118618             startWatch: function (options) {
118619                 var index, watchId, watchObj = {};
118620
118621                 if (_self.status !== "open") {
118622                     exception.raise(exception.types.Argument, "illegal state", new SensorError(_errorCode.ILLEGAL_STATE, _errorMsg.ILLEGAL_STATE));
118623                     return;
118624                 }
118625                     
118626                 if (typeof options !== "object") {
118627                     if (_self.onerror) {
118628                         _self.onerror(new SensorError(_errorCode.TYPE_MISMATCH_ERROR, _errorMsg.TYPE_MISMATCH_ERROR));
118629                     }
118630                 }
118631
118632                 setTimeout(function () {
118633                     watchId = (new Date()).getTime();   
118634
118635                     // As there will be many attributes for some sensor, each of them is needed to be watched.
118636                     for (index = 0; index < sensorEventTypes.length; index++) {
118637                         watchObj = {
118638                             eventType: sensorEventTypes[index],
118639                             onEvent: _onEventCallback(type, options, currentSensor, sensorEventTypes.length, sensorListener.get(), _self.onerror),
118640                         };
118641
118642                         watches.push(watchObj);
118643                         if (watchObj.eventType) {
118644                             event.on(watchObj.eventType, watchObj.onEvent);                                               
118645                         }
118646                     }
118647
118648                     
118649                     if (options && options.interval) {
118650                         watchObj.intervalId = setInterval(_onEventCallback(type, options, currentSensor, sensorEventTypes.length, sensorListener.get(), _self.onerror), 
118651                                                           options.interval);
118652                     }
118653
118654                     _self.status = "watching";
118655                     if (_self.onstatuschange) {
118656                         _self.onstatuschange();
118657                     }
118658                                                                                                         
118659                 }, 1);  
118660
118661                 return;
118662             },
118663
118664             endWatch: function () {
118665                 var index, watchObj;
118666
118667                 if (_self.status !== "watching") {
118668                     exception.raise(exception.types.Argument, "illegal state", new SensorError(_errorCode.ILLEGAL_STATE, _errorMsg.ILLEGAL_STATE));
118669                     return;
118670                 }
118671
118672                 for (index = 0; index < watches.length; index++) {
118673                     watchObj = watches[index];
118674
118675                     try {
118676                         event.deleteEventHandler(watchObj.eventType, watchObj.onEvent);  
118677                     }
118678                     catch (e) {
118679                         if (_self.onerror) {
118680                             _self.onerror(e);
118681                         }
118682                     }
118683
118684                     if (watchObj.intervalId) {
118685                         clearInterval(watchObj.intervalId);
118686                     }                
118687                 }
118688
118689                 watches = [];
118690
118691                 _self.status = "open";
118692                 if (_self.onstatuschange) {
118693                     _self.onstatuschange();
118694                 }
118695             },
118696
118697             // These functions are inherited from the EventTarget object
118698             addEventListener: function (eventType, callback, useCapture) {
118699                 var sensorEvent;
118700                 
118701                 if (eventType === "sensordata") {
118702                     sensorListener.set(callback);  
118703
118704                     event.on("sensordata", function (data) {
118705                         sensorEvent = new SensorDataEvent();        
118706                         sensorEvent.initSensorDataEvent("sensordata", false, false, "read", (new Date()).getTime(), 
118707                                                         currentSensor.resolution, _getSensorData(type, currentSensor, _self.onerror));           
118708
118709                         sensorListener.exec(sensorEvent);
118710                     });             
118711                 }               
118712             },
118713
118714             removeEventListener: function (eventType, callback) {
118715                 event.clear(eventType, callback);
118716                 sensorListener.unbind(callback);                                
118717             },
118718
118719             dispatchEvent: function (evt) {
118720                 event.trigger("sensordata", evt);
118721             }
118722         };
118723
118724         sensorListener = _bind("onsensordata", _self);
118725     }    
118726
118727     return _self;
118728 }
118729
118730 module.exports = function (option) {
118731  
118732     var connectionObj,
118733         _errorCode = new ErrorCode(),
118734         _errorMsg = new ErrorMsg();
118735
118736     if (option === null || option === undefined) {
118737         return null;
118738     }
118739
118740     // There are two ways to construct an object
118741     if (typeof option === "object") {
118742         if ((option.type === null || option.type === undefined) &&
118743             (option.name === null || option.name === undefined)) {
118744             // Spec: If none of the dictionary members are defined then raise an instantiation exception    
118745             exception.raise(exception.types.Argument, "type illegal", new SensorError(_errorCode.ILLEGAL_TYPE, _errorMsg.ILLEGAL_TYPE));             
118746         }
118747
118748         connectionObj = new SensorConnection(option.type, option.name);
118749     }
118750     else if (typeof option === "string") {
118751         connectionObj = new SensorConnection(option, option);
118752     }
118753
118754     return connectionObj;
118755 };
118756
118757 });
118758 define('ripple/platform/w3c/1.0/geolocation', function (require, exports, module) {
118759 /*
118760  *  Copyright 2011 Research In Motion Limited.
118761  *
118762  * Licensed under the Apache License, Version 2.0 (the "License");
118763  * you may not use this file except in compliance with the License.
118764  * You may obtain a copy of the License at
118765  *
118766  * http://www.apache.org/licenses/LICENSE-2.0
118767  *
118768  * Unless required by applicable law or agreed to in writing, software
118769  * distributed under the License is distributed on an "AS IS" BASIS,
118770  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118771  * See the License for the specific language governing permissions and
118772  * limitations under the License.
118773  */
118774 var geo = require('ripple/geo'),
118775     Position = require('ripple/platform/w3c/1.0/Position'),
118776     PositionError = require('ripple/platform/w3c/1.0/PositionError'),
118777     _watches = {},
118778     _self;
118779
118780 function createPosition() {
118781     var position = new Position(),
118782         positionInfo = geo.getPositionInfo();
118783
118784     position.coords.latitude = positionInfo.latitude;
118785     position.coords.longitude = positionInfo.longitude;
118786     position.coords.altitude = positionInfo.altitude;
118787     position.coords.altitudeAccuracy = positionInfo.altitudeAccuracy;
118788     position.coords.accuracy = positionInfo.accuracy;
118789     position.coords.heading = positionInfo.heading;
118790     position.coords.speed = positionInfo.speed;
118791     position.timestamp = positionInfo.timeStamp.getTime();
118792
118793     return position;
118794 }
118795
118796 _self = {
118797     getCurrentPosition: function (onSuccess, onError) {
118798         var delay = ((geo.delay || 0) * 1000) || 1,
118799             timeout = geo.timeout;
118800
118801         window.setTimeout(function () {
118802             if (timeout) {
118803                 var error = new PositionError();
118804                 error.code = PositionError.TIMEOUT;
118805                 error.message = "postion timed out";
118806
118807                 onError(error);
118808             }
118809             else {
118810                 // TODO: build facility to trigger onError() from emulator
118811                 // see pivotal item: https://www.pivotaltracker.com/story/show/7040343
118812                 _self.lastPosition = createPosition();
118813                 onSuccess(_self.lastPosition);
118814             }
118815         }, delay);
118816     },
118817
118818     watchPosition: function (geolocationSuccess, geolocationError, geolocationOptions) {
118819         var watchId = (new Date()).getTime().toString(),
118820             watchObj = {},
118821             timeout;
118822
118823         if (geolocationOptions) {
118824             timeout = geolocationOptions.timeout || 10000;
118825
118826             watchObj = {
118827                 onSuccess: geolocationSuccess,
118828                 onError: geolocationError,
118829                 interval: timeout
118830             };
118831
118832             _watches[watchId] = watchObj;
118833
118834             _watches[watchId].intervalId = window.setInterval(function () {
118835                 _self.getCurrentPosition(_watches[watchId].onSuccess, _watches[watchId].onError);
118836             }, timeout);
118837
118838         }
118839         else {
118840             if (typeof geolocationError === "function") {
118841                 window.setTimeout(function () {
118842                     geolocationError();
118843                 }, 1);
118844             }
118845         }
118846
118847         return watchId;
118848     },
118849
118850     lastPosition: null,
118851
118852     clearWatch: function (watchId) {
118853         window.clearInterval(_watches[watchId].intervalId);
118854         delete _watches[watchId];
118855     }
118856 };
118857
118858 module.exports = _self;
118859
118860 });
118861 define('ripple/platform/w3c/1.0/navigator', function (require, exports, module) {
118862 /*
118863  *  Copyright 2011 Research In Motion Limited.
118864  *
118865  * Licensed under the Apache License, Version 2.0 (the "License");
118866  * you may not use this file except in compliance with the License.
118867  * You may obtain a copy of the License at
118868  *
118869  * http://www.apache.org/licenses/LICENSE-2.0
118870  *
118871  * Unless required by applicable law or agreed to in writing, software
118872  * distributed under the License is distributed on an "AS IS" BASIS,
118873  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118874  * See the License for the specific language governing permissions and
118875  * limitations under the License.
118876  */
118877 var _original = window.navigator,
118878     utils = require('ripple/utils'),
118879     devices = require('ripple/devices'),
118880     constants = require('ripple/constants'),
118881     _self = {};
118882
118883 (function () {
118884     var key,
118885         nav = window.navigator;
118886
118887     function _handle(obj, key) {
118888         return typeof obj[key] !== "function" ? obj[key] : function () {
118889             return obj[key].apply(obj, Array.prototype.slice.call(arguments));
118890         };
118891     }
118892
118893     for (key in nav) {
118894         _self[key] = _handle(nav, key);
118895     }
118896 }());
118897
118898 _self.__defineGetter__('userAgent', function () {
118899     var currentUserAgent = devices.getCurrentDevice().userAgent;
118900
118901     return currentUserAgent === constants.COMMON.USER_AGENT_DEFAULT ?
118902         _original.userAgent : currentUserAgent;
118903 });
118904
118905 module.exports = _self;
118906
118907 });
118908 define('ripple/platform/wac/1.0/AccelerometerInfo', function (require, exports, module) {
118909 /*
118910  *  Copyright 2011 Research In Motion Limited.
118911  *
118912  * Licensed under the Apache License, Version 2.0 (the "License");
118913  * you may not use this file except in compliance with the License.
118914  * You may obtain a copy of the License at
118915  *
118916  * http://www.apache.org/licenses/LICENSE-2.0
118917  *
118918  * Unless required by applicable law or agreed to in writing, software
118919  * distributed under the License is distributed on an "AS IS" BASIS,
118920  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118921  * See the License for the specific language governing permissions and
118922  * limitations under the License.
118923  */
118924 var accelerometer = require('ripple/accelerometer'),
118925     _self = {};
118926
118927 _self.__defineGetter__("xAxis", function () {
118928     return accelerometer.getInfo().accelerationIncludingGravity.x;
118929 });
118930
118931 _self.__defineGetter__("yAxis", function () {
118932     return accelerometer.getInfo(true).accelerationIncludingGravity.y;
118933 });
118934
118935 _self.__defineGetter__("zAxis", function () {
118936     return accelerometer.getInfo(true).accelerationIncludingGravity.z;
118937 });
118938
118939 module.exports = _self;
118940
118941 });
118942 define('ripple/platform/wac/1.0/Account', function (require, exports, module) {
118943 /*
118944  *  Copyright 2011 Research In Motion Limited.
118945  *
118946  * Licensed under the Apache License, Version 2.0 (the "License");
118947  * you may not use this file except in compliance with the License.
118948  * You may obtain a copy of the License at
118949  *
118950  * http://www.apache.org/licenses/LICENSE-2.0
118951  *
118952  * Unless required by applicable law or agreed to in writing, software
118953  * distributed under the License is distributed on an "AS IS" BASIS,
118954  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118955  * See the License for the specific language governing permissions and
118956  * limitations under the License.
118957  */
118958 var deviceSettings = require('ripple/deviceSettings'),
118959     _self;
118960
118961 _self = {
118962     accountName: undefined,
118963     accountId: undefined
118964 };
118965
118966 _self.__defineGetter__("accountName", function () {
118967     return deviceSettings.retrieve("Account.accountName");
118968 });
118969
118970 _self.__defineGetter__("accountId", function () {
118971     return deviceSettings.retrieve("Account.accountId");
118972 });
118973
118974 module.exports = _self;
118975
118976 });
118977 define('ripple/platform/wac/1.0/AccountInfo', function (require, exports, module) {
118978 /*
118979  *  Copyright 2011 Research In Motion Limited.
118980  *
118981  * Licensed under the Apache License, Version 2.0 (the "License");
118982  * you may not use this file except in compliance with the License.
118983  * You may obtain a copy of the License at
118984  *
118985  * http://www.apache.org/licenses/LICENSE-2.0
118986  *
118987  * Unless required by applicable law or agreed to in writing, software
118988  * distributed under the License is distributed on an "AS IS" BASIS,
118989  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118990  * See the License for the specific language governing permissions and
118991  * limitations under the License.
118992  */
118993 var deviceSettings = require('ripple/deviceSettings'),
118994     _self = {
118995         phoneUserUniqueId: undefined,
118996         phoneMSISDN: undefined,
118997         phoneOperatorName: undefined,
118998         userAccountBalance: undefined,
118999         userSubscriptionType: undefined
119000     };
119001
119002 _self.__defineGetter__("phoneUserUniqueId", function () {
119003     return deviceSettings.retrieve("AccountInfo.phoneUserUniqueId");
119004 });
119005
119006 _self.__defineGetter__("phoneMSISDN", function () {
119007     return deviceSettings.retrieve("AccountInfo.phoneMSISDN");
119008 });
119009
119010 _self.__defineGetter__("phoneOperatorName", function () {
119011     return deviceSettings.retrieve("AccountInfo.phoneOperatorName");
119012 });
119013
119014 _self.__defineGetter__("userAccountBalance", function () {
119015     return deviceSettings.retrieve("AccountInfo.userAccountBalance");
119016 });
119017
119018 _self.__defineGetter__("userSubscriptionType", function () {
119019     return deviceSettings.retrieve("AccountInfo.userSubscriptionType");
119020 });
119021
119022 module.exports = _self;
119023
119024 });
119025 define('ripple/platform/wac/1.0/AddressBookItem', function (require, exports, module) {
119026 /*
119027  *  Copyright 2011 Research In Motion Limited.
119028  *
119029  * Licensed under the Apache License, Version 2.0 (the "License");
119030  * you may not use this file except in compliance with the License.
119031  * You may obtain a copy of the License at
119032  *
119033  * http://www.apache.org/licenses/LICENSE-2.0
119034  *
119035  * Unless required by applicable law or agreed to in writing, software
119036  * distributed under the License is distributed on an "AS IS" BASIS,
119037  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119038  * See the License for the specific language governing permissions and
119039  * limitations under the License.
119040  */
119041 var utils = require('ripple/utils'),
119042     exception = require('ripple/exception'),
119043     db = require('ripple/db'),
119044     constants = require('ripple/constants'),
119045     Exception = require('ripple/platform/wac/1.0/Exception'),
119046     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes');
119047
119048 function _validateArgs(min, max, len) {
119049     utils.validateNumberOfArguments(min, max, len,
119050         ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception());
119051 }
119052
119053 function _validateType(arg, argType) {
119054     utils.validateArgumentType(arg, argType,
119055         ExceptionTypes.INVALID_PARAMETER,  "argument of wrong type provided",
119056         new Exception());
119057 }
119058
119059 module.exports = function () {
119060     function _throwUnsupportedException(method) {
119061         exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
119062     }
119063
119064     this.addressBookItemId = undefined;
119065     this.fullName = undefined;
119066     this.mobilePhone = undefined;
119067     this.homePhone = undefined;
119068     this.workPhone = undefined;
119069     this.eMail = undefined;
119070     this.company = undefined;
119071     this.title = undefined;
119072     this.address = undefined;
119073
119074     this.setAttributeValue = function (attribute, value) {
119075         _validateArgs(2, 2, arguments.length);
119076         _validateType(attribute, "string");
119077         this[attribute] = value;
119078     };
119079     this.setAddressGroupNames = function (groups) {
119080         _throwUnsupportedException("PIM.AddressBookItem.setAddressGroupNames");
119081     };
119082     this.getAttributeValue = function (attribute) {
119083         _validateArgs(1, 1, arguments.length);
119084         _validateType(attribute, "string");
119085         return this[attribute];
119086     };
119087     this.getAddressGroupNames = function () {
119088         _throwUnsupportedException("PIM.AddressBookItem.getAddressGroupNames");
119089     };
119090     this.getAvailableAttributes = function () {
119091         return utils.reduce(this, function (attributes, value, key) {
119092             if (typeof(value) !== 'function') {
119093                 attributes.push(key);
119094             }
119095             return attributes;
119096         }, []).sort();
119097     };
119098     this.update = function () {
119099         var items = db.retrieveObject(constants.PIM.ADDRESS_LIST_KEY),
119100             that = this,
119101             itemIndex = items.reduce(function (current, value, i) {
119102                 return value.addressBookItemId === that.addressBookItemId ?
119103                     i : current;
119104             }, -1);
119105
119106         if (itemIndex >= 0) {
119107             items[itemIndex] = this;
119108             db.saveObject(constants.PIM.ADDRESS_LIST_KEY, items);
119109         }
119110         else {
119111             exception.raise(ExceptionTypes.INVALID_PARAMETER, "Address Book Item not found: " + (this.addressBookItemId || ""), new Exception());
119112         }
119113
119114     };
119115 };
119116
119117 });
119118 define('ripple/platform/wac/1.0/ApplicationTypes', function (require, exports, module) {
119119 /*
119120  *  Copyright 2011 Research In Motion Limited.
119121  *
119122  * Licensed under the Apache License, Version 2.0 (the "License");
119123  * you may not use this file except in compliance with the License.
119124  * You may obtain a copy of the License at
119125  *
119126  * http://www.apache.org/licenses/LICENSE-2.0
119127  *
119128  * Unless required by applicable law or agreed to in writing, software
119129  * distributed under the License is distributed on an "AS IS" BASIS,
119130  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119131  * See the License for the specific language governing permissions and
119132  * limitations under the License.
119133  */
119134 var utils = require('ripple/utils'),
119135     constants = require('ripple/constants'),
119136     _self = {};
119137
119138 utils.forEach(constants.PLATFORMS.WAC.APPLICATIONS, function (application) {
119139     _self.__defineGetter__(application, function () {
119140         return application;
119141     });
119142 });
119143
119144 module.exports = _self;
119145
119146 });
119147 define('ripple/platform/wac/1.0/Attachment', function (require, exports, module) {
119148 /*
119149  *  Copyright 2011 Research In Motion Limited.
119150  *
119151  * Licensed under the Apache License, Version 2.0 (the "License");
119152  * you may not use this file except in compliance with the License.
119153  * You may obtain a copy of the License at
119154  *
119155  * http://www.apache.org/licenses/LICENSE-2.0
119156  *
119157  * Unless required by applicable law or agreed to in writing, software
119158  * distributed under the License is distributed on an "AS IS" BASIS,
119159  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119160  * See the License for the specific language governing permissions and
119161  * limitations under the License.
119162  */
119163 module.exports = function () {
119164     this.fileName = "";
119165     this.MIMEType = "";
119166     this.size = 0;
119167 };
119168
119169 });
119170 define('ripple/platform/wac/1.0/AudioPlayer', function (require, exports, module) {
119171 /*
119172  *  Copyright 2011 Research In Motion Limited.
119173  *
119174  * Licensed under the Apache License, Version 2.0 (the "License");
119175  * you may not use this file except in compliance with the License.
119176  * You may obtain a copy of the License at
119177  *
119178  * http://www.apache.org/licenses/LICENSE-2.0
119179  *
119180  * Unless required by applicable law or agreed to in writing, software
119181  * distributed under the License is distributed on an "AS IS" BASIS,
119182  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119183  * See the License for the specific language governing permissions and
119184  * limitations under the License.
119185  */
119186 var constants = require('ripple/constants'),
119187     event = require('ripple/event'),
119188     exception = require('ripple/exception'),
119189     utils = require('ripple/utils'),
119190     fileSystem = require('ripple/fileSystem'),
119191     _console = require('ripple/console'),
119192     Exception = require('ripple/platform/wac/1.0/Exception'),
119193     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
119194     _self,
119195     _state = null,
119196     _STATES = constants.MULTIMEDIA.AUDIO_STATES,
119197     _currentAudioFile,
119198     _audio, _loopCount;
119199
119200 event.on("MultimediaAudioStateChanged", function updateAudioState(state) {
119201     _state = state;
119202     if (typeof _self.onStateChange === 'function') {
119203         _self.onStateChange.apply(_self, arguments);
119204     }
119205 });
119206
119207 _audio = utils.createElement("audio", {
119208     "id": "multimedia-audio"
119209 });
119210
119211 _audio.addEventListener('error', function () {
119212     _console.warn("AudioPlayer encountered an error: " + _audio.error.code);
119213     if (_audio.error.code === 4) {
119214         _console.warn("AudioPlayer error 4 could be caused by missing codecs");
119215     }
119216     _state = null;
119217     event.trigger("MultimediaAudioStateChanged", [null], true);
119218 });
119219
119220 _audio.addEventListener('ended', function handleAudioEnded() {
119221     event.trigger("MultimediaAudioStateChanged", [_STATES.COMPLETED], true);
119222     if (_loopCount > 1) {
119223         _self.open(_currentAudioFile);
119224         _self.play(_loopCount--);
119225     }
119226 });
119227
119228 document.getElementById("ui").appendChild(_audio);
119229
119230 function _validateAndSet(state, validStates, callbackBeforeSuccess) {
119231     var i, valid = false;
119232
119233     for (i = 0; i < validStates.length; i++) {
119234         if (validStates[i] === _state) {
119235             valid = true;
119236         }
119237     }
119238
119239     if (!valid) {
119240         _console.warn("Attempted to initiate AudioPlayer." + state +
119241             " in invalid state. current state: " + _state);
119242     } else {
119243         if (typeof(callbackBeforeSuccess) === "function") {
119244             callbackBeforeSuccess.apply();
119245         }
119246         event.trigger("MultimediaAudioStateChanged", [state], true);
119247     }
119248
119249     return valid;
119250 }
119251
119252 function _validateAudioType(fileUrl) {
119253     var matched = fileUrl.match(/\.(\w*)$/),
119254         type = matched ? matched[1] : "";
119255
119256     if (_audio && _audio.canPlayType("audio/" + type) === "") {
119257         _console.warn("Attempting to load an audio that might not work in the current browser [" + fileUrl + "]");
119258     }
119259 }
119260
119261 _self = {
119262     onStateChange: undefined,
119263
119264     open: function (fileUrl) {
119265         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.open wrong number of arguments", new Exception());
119266         utils.validateArgumentType(fileUrl, "string", ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.open invalid parameter! expected string, fileUrl: " +
119267             fileUrl, new Exception());
119268
119269         if (fileUrl.match(/^rtsp:\/\//)) {
119270             exception.raise(exception.types.MethodNotImplemented, "rtsp:// scheme not yet supported. sorry :(");
119271         }
119272
119273         _validateAndSet(_STATES.OPENED, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED, null], function () {
119274             _validateAudioType(fileUrl);
119275             _currentAudioFile = fileSystem.getURI(fileUrl);
119276             _audio.setAttribute("src", _currentAudioFile);
119277             _audio.load();
119278         });
119279     },
119280
119281     play: function (repeatTimes) {
119282         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.play wrong number of arguments", new Exception());
119283         utils.validateArgumentType(repeatTimes, "integer", ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.play invalid parameter! expected integer, repeatTimes: " + repeatTimes, new Exception());
119284
119285         if (repeatTimes < 0) {
119286             exception.raise(ExceptionTypes.INVALID_PARAMETER, "value of repeatTimes must be greater than 0", new Exception());
119287         }
119288
119289         if (repeatTimes !== 0) {
119290             _validateAndSet(_STATES.PLAYING, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED], function () {
119291                 _loopCount = repeatTimes;
119292                 _audio.play();
119293             });
119294         }
119295     },
119296
119297     pause: function () {
119298         _validateAndSet(_STATES.PAUSED, [_STATES.PLAYING], function () {
119299             _audio.pause();
119300         });
119301     },
119302
119303     resume: function () {
119304         _validateAndSet(_STATES.PLAYING, [_STATES.PAUSED], function () {
119305             _audio.play();
119306         });
119307     },
119308
119309     stop: function () {
119310         _validateAndSet(_STATES.STOPPED, [_STATES.PAUSED, _STATES.PLAYING], function () {
119311             try {
119312                 _audio.pause();
119313                 _audio.currentTime = 0;
119314             } catch (e) {
119315                 //HACK: do nothing, this could throw a dom exception 11 sometimes when playing an mp3 or before the file has loaded.
119316                 //see http://developer.palm.com/distribution/viewtopic.php?f=11&t=7568
119317             }
119318         });
119319     }
119320 };
119321
119322 module.exports = _self;
119323
119324 });
119325 define('ripple/platform/wac/1.0/CalendarItem', function (require, exports, module) {
119326 /*
119327  *  Copyright 2011 Research In Motion Limited.
119328  *
119329  * Licensed under the Apache License, Version 2.0 (the "License");
119330  * you may not use this file except in compliance with the License.
119331  * You may obtain a copy of the License at
119332  *
119333  * http://www.apache.org/licenses/LICENSE-2.0
119334  *
119335  * Unless required by applicable law or agreed to in writing, software
119336  * distributed under the License is distributed on an "AS IS" BASIS,
119337  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119338  * See the License for the specific language governing permissions and
119339  * limitations under the License.
119340  */
119341 var constants = require('ripple/constants'),
119342     db = require('ripple/db'),
119343     exception = require('ripple/exception'),
119344     Exception = require('ripple/platform/wac/1.0/Exception'),
119345     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes');
119346
119347 module.exports = function () {
119348     this.calendarItemId = undefined;
119349     this.alarmDate = undefined;
119350     this.eventStartTime = undefined;
119351     this.eventEndTime = undefined;
119352     this.eventName = undefined;
119353     this.eventNotes = undefined;
119354     this.alarmed = undefined;
119355
119356     this.update = function () {
119357         var events = db.retrieveObject(constants.PIM.CALENDAR_LIST_KEY) || [],
119358             that = this,
119359             eventIndex = events.reduce(function (match, value, i) {
119360                 return value.calendarItemId === that.calendarItemId ?
119361                     i : match;
119362             }, -1);
119363
119364
119365         if (eventIndex >= 0) {
119366             events[eventIndex] = this;
119367             db.saveObject(constants.PIM.CALENDAR_LIST_KEY, events);
119368         }
119369         else {
119370             exception.raise(ExceptionTypes.INVALID_PARAMETER, "Calendar Item not found: " + (this.calendarItemId || ""), new Exception());
119371         }
119372     };
119373 };
119374
119375 });
119376 define('ripple/platform/wac/1.0/CallRecord', function (require, exports, module) {
119377 /*
119378  *  Copyright 2011 Research In Motion Limited.
119379  *
119380  * Licensed under the Apache License, Version 2.0 (the "License");
119381  * you may not use this file except in compliance with the License.
119382  * You may obtain a copy of the License at
119383  *
119384  * http://www.apache.org/licenses/LICENSE-2.0
119385  *
119386  * Unless required by applicable law or agreed to in writing, software
119387  * distributed under the License is distributed on an "AS IS" BASIS,
119388  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119389  * See the License for the specific language governing permissions and
119390  * limitations under the License.
119391  */
119392 module.exports = function () {
119393     this.callRecordType = undefined;
119394     this.callRecordId = undefined;
119395     this.callRecordAddress = undefined;
119396     this.callRecordName = undefined;
119397     this.durationSeconds = undefined;
119398     this.startTime = undefined;
119399 };
119400
119401 });
119402 define('ripple/platform/wac/1.0/CallRecordTypes', function (require, exports, module) {
119403 /*
119404  *  Copyright 2011 Research In Motion Limited.
119405  *
119406  * Licensed under the Apache License, Version 2.0 (the "License");
119407  * you may not use this file except in compliance with the License.
119408  * You may obtain a copy of the License at
119409  *
119410  * http://www.apache.org/licenses/LICENSE-2.0
119411  *
119412  * Unless required by applicable law or agreed to in writing, software
119413  * distributed under the License is distributed on an "AS IS" BASIS,
119414  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119415  * See the License for the specific language governing permissions and
119416  * limitations under the License.
119417  */
119418 module.exports = {
119419     RECEIVED: "received",
119420     OUTGOING: "outgoing",
119421     MISSED: "missed"
119422 };
119423
119424 });
119425 define('ripple/platform/wac/1.0/Camera', function (require, exports, module) {
119426 /*
119427  *  Copyright 2011 Research In Motion Limited.
119428  *
119429  * Licensed under the Apache License, Version 2.0 (the "License");
119430  * you may not use this file except in compliance with the License.
119431  * You may obtain a copy of the License at
119432  *
119433  * http://www.apache.org/licenses/LICENSE-2.0
119434  *
119435  * Unless required by applicable law or agreed to in writing, software
119436  * distributed under the License is distributed on an "AS IS" BASIS,
119437  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119438  * See the License for the specific language governing permissions and
119439  * limitations under the License.
119440  */
119441 var exception = require('ripple/exception'),
119442     Exception = require('ripple/platform/wac/1.0/Exception'),
119443     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
119444     constants = require('ripple/constants'),
119445     _console = require('ripple/console'),
119446     utils = require('ripple/utils'),
119447     notifications = require('ripple/notifications'),
119448     _currentlySet,
119449     _img,
119450     _buttons,
119451     _self,
119452     _videoCapture;
119453
119454
119455 function _populateWindow(domObject) {
119456     var record = document.createElement("button"),
119457         pause = document.createElement("button"),
119458         stop = document.createElement("button");
119459
119460     _img = document.createElement("img");
119461     _img.setAttribute("id", "jil-camera-window");
119462     //_img.setAttribute("src", document.querySelector("#extension-url").innerHTML + constants.CAMERA.WINDOW_ANIMATION);
119463     _img.setAttribute("src", document.documentURI.replace(/index\.html$/, "") + constants.CAMERA.WINDOW_ANIMATION);
119464     _img.setAttribute("width", "100%");
119465     _currentlySet = domObject;
119466     domObject.appendChild(_img);
119467
119468     _buttons = document.createElement("div");
119469     _buttons.setAttribute("id", "jil-camera-window-buttons");
119470     _buttons.setAttribute("style", "display: none");
119471
119472     record.setAttribute("id", "jil-camera-window-buttons-record");
119473     record.innerHTML = "Record";
119474     pause.setAttribute("id", "jil-camera-window-buttons-pause");
119475     pause.innerHTML = "Pause";
119476     stop.setAttribute("id", "jil-camera-window-buttons-stop");
119477     stop.innerHTML = "Stop";
119478     stop.addEventListener("click", _self.stopVideoCapture);
119479
119480     _buttons.appendChild(record);
119481     _buttons.appendChild(pause);
119482     _buttons.appendChild(stop);
119483
119484     domObject.appendChild(_buttons);
119485
119486 }
119487
119488 function _verifySetWindow(method) {
119489     if (!_img) {
119490         exception.raise(ExceptionTypes.UNKNOWN, "Camera." +
119491           method + " was (most likely) called before using the setWindow method.", new Exception());
119492     }
119493 }
119494
119495 _self = {
119496     onCameraCaptured: undefined, //function (fileName) { }
119497
119498     captureImage: function (fileName, lowRes) {
119499         utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "captureImage invalid number of parameters", new Exception());
119500         utils.validateMultipleArgumentTypes([fileName, lowRes], ['string', 'boolean'], ExceptionTypes.INVALID_PARAMETER, "invalid parameter type", new Exception());
119501
119502         _verifySetWindow("captureImage");
119503         var msg = constants.CAMERA.WARNING_TEXT;
119504         msg = msg.replace("{file}", fileName);
119505         notifications.openNotification("normal", msg);
119506         _console.log("simulated saved image as: " + fileName);
119507         if (_self.onCameraCaptured) {
119508             _self.onCameraCaptured.apply(_self, [fileName]);
119509         }
119510
119511         return fileName;
119512     },
119513     setWindow: function (domObject) {
119514
119515         if (_currentlySet) {
119516             _currentlySet.removeChild(_img);
119517             _currentlySet.removeChild(_buttons);
119518             _currentlySet = null;
119519             _img = null;
119520             _buttons = null;
119521         }
119522         if (domObject !== null) {
119523             _populateWindow(domObject);
119524         }
119525     },
119526     startVideoCapture: function (fileName, lowRes, maxDurationSeconds, showDefaultControls) {
119527         _verifySetWindow("startVideoCapture");
119528         utils.validateNumberOfArguments(1, 4, arguments.length, ExceptionTypes.INVALID_PARAMETER, "startVideoCapture invalid number of parameters", new Exception());
119529         utils.validateMultipleArgumentTypes(
119530             [fileName, lowRes, maxDurationSeconds, showDefaultControls],
119531             ['string', 'boolean', 'integer', 'boolean'],
119532             ExceptionTypes.INVALID_PARAMETER,
119533             "invalid parameter type", new Exception());
119534         _console.log("started recording video");
119535         var interval = window.setTimeout(function () {
119536             _self.stopVideoCapture();
119537         }, maxDurationSeconds * 1000);
119538
119539         if (showDefaultControls) {
119540             _buttons.removeAttribute("style");
119541         }
119542
119543         _videoCapture = {
119544             fileName: fileName,
119545             stop: function () {
119546                 window.clearInterval(interval);
119547                 var msg = constants.CAMERA.WARNING_TEXT;
119548                 msg = msg.replace("{file}", fileName);
119549                 notifications.openNotification("normal", msg);
119550                 if (_self.onCameraCaptured) {
119551                     _self.onCameraCaptured.apply(_self, [fileName]);
119552                 }
119553             }
119554         };
119555
119556         return fileName;
119557     },
119558     stopVideoCapture: function () {
119559         utils.validateNumberOfArguments(0, 0, arguments.length, ExceptionTypes.INVALID_PARAMETER, "stopVideoCapture invalid number of parameters", new Exception());
119560         if (_videoCapture) {
119561             _console.log("simulated saving a video as: " + _videoCapture.fileName);
119562             if (_buttons) {
119563                 _buttons.setAttribute("style", "display: none");
119564             }
119565             _videoCapture.stop();
119566             _videoCapture = null;
119567         }
119568     }
119569
119570 };
119571
119572 module.exports = _self;
119573
119574 });
119575 define('ripple/platform/wac/1.0/Config', function (require, exports, module) {
119576 /*
119577  *  Copyright 2011 Research In Motion Limited.
119578  *
119579  * Licensed under the Apache License, Version 2.0 (the "License");
119580  * you may not use this file except in compliance with the License.
119581  * You may obtain a copy of the License at
119582  *
119583  * http://www.apache.org/licenses/LICENSE-2.0
119584  *
119585  * Unless required by applicable law or agreed to in writing, software
119586  * distributed under the License is distributed on an "AS IS" BASIS,
119587  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119588  * See the License for the specific language governing permissions and
119589  * limitations under the License.
119590  */
119591 var utils = require('ripple/utils'),
119592     notifications = require('ripple/notifications'),
119593     constants = require('ripple/constants'),
119594     deviceSettings = require('ripple/deviceSettings'),
119595     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
119596     Exception = require('ripple/platform/wac/1.0/Exception'),
119597     _self = {
119598         ringtoneVolume: undefined,
119599         msgRingtoneVolume: undefined,
119600         vibrationSetting: undefined,
119601
119602         setDefaultRingtone: function (ringtoneUrl) {
119603             utils.validateArgumentType(ringtoneUrl, "string", ExceptionTypes.INVALID_PARAMETER, "ringtoneUrl paramter is not a string", new Exception());
119604             notifications.openNotification("normal", "Setting default ringtone to: " + ringtoneUrl);
119605         },
119606
119607         setAsWallpaper: function (wallpaperUrl) {
119608             utils.validateArgumentType(wallpaperUrl, "string", ExceptionTypes.INVALID_PARAMETER, "wallpaperUrl paramter is not a string", new Exception());
119609             notifications.openNotification("normal", "Setting wallpaper to: " + wallpaperUrl);
119610         }
119611     };
119612
119613 _self.__defineGetter__("ringtoneVolume", function () {
119614     return deviceSettings.retrieve("Config.ringtoneVolume");
119615 });
119616
119617 _self.__defineGetter__("msgRingtoneVolume", function () {
119618     return deviceSettings.retrieve("Config.msgRingtoneVolume");
119619 });
119620
119621 _self.__defineGetter__("vibrationSetting", function () {
119622     return deviceSettings.retrieve("Config.vibrationSetting");
119623 });
119624
119625 module.exports = _self;
119626
119627 });
119628 define('ripple/platform/wac/1.0/DataNetworkConnectionTypes', function (require, exports, module) {
119629 /*
119630  *  Copyright 2011 Research In Motion Limited.
119631  *
119632  * Licensed under the Apache License, Version 2.0 (the "License");
119633  * you may not use this file except in compliance with the License.
119634  * You may obtain a copy of the License at
119635  *
119636  * http://www.apache.org/licenses/LICENSE-2.0
119637  *
119638  * Unless required by applicable law or agreed to in writing, software
119639  * distributed under the License is distributed on an "AS IS" BASIS,
119640  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119641  * See the License for the specific language governing permissions and
119642  * limitations under the License.
119643  */
119644 var utils = require('ripple/utils'),
119645     _self = {
119646         "BLUETOOTH": undefined,
119647         "EDGE": undefined,
119648         "EVDO": undefined,
119649         "GPRS": undefined,
119650         "IRDA": undefined,
119651         "LTE": undefined,
119652         "ONEXRTT": undefined,
119653         "WIFI": undefined
119654     };
119655
119656 utils.forEach(_self, function (value, property) {
119657     _self.__defineGetter__(property, function () {
119658         return property;
119659     });
119660 });
119661
119662 module.exports = _self;
119663
119664 });
119665 define('ripple/platform/wac/1.0/DataNetworkInfo', function (require, exports, module) {
119666 /*
119667  *  Copyright 2011 Research In Motion Limited.
119668  *
119669  * Licensed under the Apache License, Version 2.0 (the "License");
119670  * you may not use this file except in compliance with the License.
119671  * You may obtain a copy of the License at
119672  *
119673  * http://www.apache.org/licenses/LICENSE-2.0
119674  *
119675  * Unless required by applicable law or agreed to in writing, software
119676  * distributed under the License is distributed on an "AS IS" BASIS,
119677  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119678  * See the License for the specific language governing permissions and
119679  * limitations under the License.
119680  */
119681 var event = require('ripple/event'),
119682     utils = require('ripple/utils'),
119683     _console = require('ripple/console'),
119684     deviceSettings = require('ripple/deviceSettings'),
119685     DataNetworkConnectionTypes = require('ripple/platform/wac/1.0/DataNetworkConnectionTypes'),
119686     Exception = require('ripple/platform/wac/1.0/Exception'),
119687     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
119688
119689 _self = {
119690     isDataNetworkConnected: undefined,
119691     networkConnectionType: undefined,
119692     onNetworkConnectionChanged: undefined,
119693
119694     getNetworkConnectionName: function (networkConnectionType) {
119695         var foundConnectionType;
119696         utils.validateArgumentType(networkConnectionType, "string", ExceptionTypes.INVALID_PARAMETER, "networkConnectionType is invalid, expected a string", new Exception());
119697         foundConnectionType = DataNetworkConnectionTypes[networkConnectionType.toUpperCase()];
119698         return foundConnectionType || null;
119699     }
119700 };
119701
119702 event.on("DataNetworkConnectionChanged", function (newConnectionName) {
119703     var callback = _self.onNetworkConnectionChanged,
119704         msg = "Fired onNetworkConnectionChanged with newConnectionName: " + newConnectionName;
119705
119706     if (callback && typeof callback === "function") {
119707         callback.apply(null, [newConnectionName]);
119708     }
119709     else {
119710         msg += " --> BUT there was no registered callback found.";
119711     }
119712
119713     _console.log(msg);
119714 });
119715
119716 _self.__defineGetter__("isDataNetworkConnected", function () {
119717     return deviceSettings.retrieveAsBoolean("DataNetworkInfo.isDataNetworkConnected");
119718 });
119719
119720 _self.__defineGetter__("networkConnectionType", function () {
119721     var value = deviceSettings.retrieve("DataNetworkInfo.networkConnectionType");
119722     return value instanceof Array ? value : [value];
119723 });
119724
119725 module.exports = _self;
119726
119727 });
119728 define('ripple/platform/wac/1.0/Device', function (require, exports, module) {
119729 /*
119730  *  Copyright 2011 Research In Motion Limited.
119731  *
119732  * Licensed under the Apache License, Version 2.0 (the "License");
119733  * you may not use this file except in compliance with the License.
119734  * You may obtain a copy of the License at
119735  *
119736  * http://www.apache.org/licenses/LICENSE-2.0
119737  *
119738  * Unless required by applicable law or agreed to in writing, software
119739  * distributed under the License is distributed on an "AS IS" BASIS,
119740  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119741  * See the License for the specific language governing permissions and
119742  * limitations under the License.
119743  */
119744 var constants = require('ripple/constants'),
119745     exception = require('ripple/exception'),
119746     _console = require('ripple/console'),
119747     utils = require('ripple/utils'),
119748     notifications = require('ripple/notifications'),
119749     ApplicationTypes = require('ripple/platform/wac/1.0/ApplicationTypes'),
119750     Exception = require('ripple/platform/wac/1.0/Exception'),
119751     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
119752     _applicationTypes = {
119753         FILES: "FILES",
119754         MEDIAPLAYER: "MEDIAPLAYER",
119755         PHONECALL: "PHONECALL",
119756         PICTURES: "PICTURES"
119757     },
119758     _self;
119759
119760 function _throwUnsupportedException(method) {
119761     exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
119762 }
119763
119764 _self = {
119765     // Properties
119766     clipboardString: undefined,
119767     widgetEngineName: undefined,
119768     widgetEngineProvider: undefined,
119769     widgetEngineVersion: undefined,
119770
119771     // Methods
119772     getAvailableApplications: function () {
119773         return constants.PLATFORMS.WAC.APPLICATIONS || [];
119774     },
119775
119776     getDirectoryFileNames: function () {
119777         _throwUnsupportedException("Device.getDirectoryFileNames");
119778     },
119779     getFile: function () {
119780         _throwUnsupportedException("Device.getFile");
119781     },
119782
119783     launchApplication: function launchApplication(application, startParameter) {
119784         if (!application || typeof(application) !== "string") {
119785             exception.raise(ExceptionTypes.INVALID_PARAMETER,
119786                     "Invalid argument 'application' at Device.launchApplication(): expected to be of type 'string' but was of type: " + (application ? typeof(application) : "null"),
119787                     Exception);
119788         }
119789
119790         if (startParameter && typeof(startParameter) !== "string") {
119791             exception.raise(ExceptionTypes.INVALID_PARAMETER,
119792                     "Invalid argument 'startParameter' at Device.launchApplication(): expected to be 'string' but was : " + typeof(startParameter),
119793                     Exception);
119794         }
119795
119796         // rudimentary implementation for now
119797         var message = "The widget has requested application: '" + application + "' to be launched. \n\n";
119798
119799         if (startParameter) {
119800             message += "The following start parameter was sent in: " + startParameter + "\n\n";
119801         }
119802
119803         if (_applicationTypes[application] && !startParameter) {
119804             message += "Launching this application can also be done with an optional startParameter which was not provided" + "\n\n";
119805         }
119806
119807         if (!ApplicationTypes[application]) {
119808             message += "Note: the application requested is not part of the common values specified by the WAC API.";
119809         }
119810
119811         notifications.openNotification("normal", message);
119812         _console.log(message);
119813     },
119814
119815     copyFile: function () {
119816         _throwUnsupportedException("Device.copyFile");
119817     },
119818     deleteFile: function () {
119819         _throwUnsupportedException("Device.deleteFile");
119820     },
119821     findFiles: function () {
119822         _throwUnsupportedException("Device.findFiles");
119823     },
119824     getFileSystemRoots: function () {
119825         _throwUnsupportedException("Device.getFileSystemRoots");
119826     },
119827     getFileSystemSize: function () {
119828         _throwUnsupportedException("Device.getFileSystemSize");
119829     },
119830     moveFile: function () {
119831         _throwUnsupportedException("Device.moveFile");
119832     },
119833     onFilesFound: function () {
119834         _throwUnsupportedException("Device.onFilesFound");
119835     },
119836     setRingtone: function () {
119837         _throwUnsupportedException("Device.setRingtone");
119838     },
119839
119840     vibrate: function (duration) {
119841         utils.validateArgumentType(duration, "number", ExceptionTypes.INVALID_PARAMETER, "duration paramter is not a number", new Exception());
119842         notifications.openNotification("normal", "Vibrating for " + duration + " second(s).");
119843     }
119844
119845 };
119846
119847 _self.__defineGetter__("widgetEngineName", function () {
119848     return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_NAME;
119849 });
119850
119851 _self.__defineGetter__("widgetEngineProvider", function () {
119852     return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_PROVIDER;
119853 });
119854
119855 _self.__defineGetter__("widgetEngineVersion", function () {
119856     return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_VERSION;
119857 });
119858
119859 module.exports = _self;
119860
119861 });
119862 define('ripple/platform/wac/1.0/DeviceInfo', function (require, exports, module) {
119863 /*
119864  *  Copyright 2011 Research In Motion Limited.
119865  *
119866  * Licensed under the Apache License, Version 2.0 (the "License");
119867  * you may not use this file except in compliance with the License.
119868  * You may obtain a copy of the License at
119869  *
119870  * http://www.apache.org/licenses/LICENSE-2.0
119871  *
119872  * Unless required by applicable law or agreed to in writing, software
119873  * distributed under the License is distributed on an "AS IS" BASIS,
119874  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119875  * See the License for the specific language governing permissions and
119876  * limitations under the License.
119877  */
119878 var utils = require('ripple/utils'),
119879     deviceSettings = require('ripple/deviceSettings'),
119880     platform = require('ripple/platform'),
119881     devices = require('ripple/devices'),
119882     _self;
119883
119884 _self = {
119885     ownerInfo: undefined, // return AddressBookItem
119886     phoneColorDepthDefault: undefined,
119887     phoneFirmware: undefined,
119888     phoneManufacturer: undefined,
119889     phoneModel: undefined,
119890     phoneOS: undefined,
119891     phoneSoftware: undefined,
119892     phoneScreenHeightDefault: undefined,
119893     phoneScreenWidthDefault: undefined,
119894     totalMemory: undefined
119895 };
119896
119897 function _getDeviceAttribute(attr) {
119898     var devicePointer = devices.getCurrentDevice();
119899     utils.forEach(attr.split("."), function (dot) {
119900         devicePointer = devicePointer[dot];
119901     });
119902     return devicePointer;
119903 }
119904
119905 _self.__defineGetter__("phoneColorDepthDefault", function () {
119906     return deviceSettings.retrieveAsInt("DeviceInfo.phoneColorDepthDefault");
119907 });
119908
119909 _self.__defineGetter__("phoneFirmware", function () {
119910     return _getDeviceAttribute("firmware");
119911 });
119912
119913 _self.__defineGetter__("phoneManufacturer", function () {
119914     return _getDeviceAttribute("manufacturer");
119915 });
119916
119917 _self.__defineGetter__("phoneOS", function () {
119918     return _getDeviceAttribute("osName") + " " + _getDeviceAttribute("osVersion");
119919 });
119920
119921 _self.__defineGetter__("phoneModel", function () {
119922     return _getDeviceAttribute("model");
119923 });
119924
119925 _self.__defineGetter__("phoneSoftware", function () {
119926     return _getDeviceAttribute("osVersion");
119927 });
119928
119929 _self.__defineGetter__("phoneScreenHeightDefault", function () {
119930     return _getDeviceAttribute("screen.height");
119931 });
119932
119933 _self.__defineGetter__("phoneScreenWidthDefault", function () {
119934     return _getDeviceAttribute("screen.width");
119935 });
119936
119937 _self.__defineGetter__("totalMemory", function () {
119938     return deviceSettings.retrieveAsInt("DeviceInfo.totalMemory");
119939 });
119940
119941 module.exports = _self;
119942
119943 });
119944 define('ripple/platform/wac/1.0/DeviceStateInfo', function (require, exports, module) {
119945 /*
119946  *  Copyright 2011 Research In Motion Limited.
119947  *
119948  * Licensed under the Apache License, Version 2.0 (the "License");
119949  * you may not use this file except in compliance with the License.
119950  * You may obtain a copy of the License at
119951  *
119952  * http://www.apache.org/licenses/LICENSE-2.0
119953  *
119954  * Unless required by applicable law or agreed to in writing, software
119955  * distributed under the License is distributed on an "AS IS" BASIS,
119956  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119957  * See the License for the specific language governing permissions and
119958  * limitations under the License.
119959  */
119960 var utils = require('ripple/utils'),
119961     exception = require('ripple/exception'),
119962     _console = require('ripple/console'),
119963     geo = require('ripple/geo'),
119964     event = require('ripple/event'),
119965     deviceSettings = require('ripple/deviceSettings'),
119966     PositionInfo = require('ripple/platform/wac/1.0/PositionInfo'),
119967     Exception = require('ripple/platform/wac/1.0/Exception'),
119968     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
119969     _self;
119970
119971 event.on("ScreenChangeDimensions", function (width, height) {
119972     try {
119973         if (typeof _self.onScreenChangeDimensions === 'function') {
119974             _self.onScreenChangeDimensions(width, height);
119975         }
119976         _console.log("called DeviceStateInfo.onScreenChangeDimensions callback function with width = " + width + " and height = " + height);
119977     } catch (e) {
119978         exception.handle(e, false);
119979     }
119980 });
119981
119982 _self = {
119983     availableMemory: undefined,
119984     language: undefined,
119985     keypadLightOn: undefined,
119986     backLightOn: undefined,
119987     processorUtilizationPercent: undefined,
119988     audioPath: undefined,
119989
119990     onPositionRetrieved: undefined,
119991
119992     requestPositionInfo: function (method) {
119993         utils.validateNumberOfArguments(1, 1, arguments.length,
119994             ExceptionTypes.INVALID_PARAMETER, "requestPositionInfo invalid number of parameters", new Exception());
119995         utils.validateArgumentType(method, "string",
119996             ExceptionTypes.INVALID_PARAMETER, "requestPositionInfo invalid parameter", new Exception());
119997
119998         if (!(method.match(/gps|agps|cellid/))) {
119999             exception.raise(ExceptionTypes.INVALID_PARAMETER,
120000                     "Invalid method, expected (gps, agps or cellid)", Exception);
120001         }
120002
120003         if (typeof _self.onPositionRetrieved === "function") {
120004             var delay = geo.delay * 1000,
120005                 timeout = geo.timeout;
120006             setTimeout(function () {
120007                 var pos = PositionInfo,
120008                     errorObj = {};
120009
120010                 if (timeout) {
120011                     //create
120012                     utils.forEach(pos, function (val, key) {
120013                         errorObj[key] = undefined;
120014                     });
120015                     pos = errorObj;
120016                 }
120017                 _self.onPositionRetrieved(pos, method);
120018             }, delay);
120019         }
120020     },
120021
120022     onScreenChangeDimensions: undefined,
120023
120024     onFlipEvent: undefined
120025 };
120026
120027 _self.__defineGetter__("availableMemory", function () {
120028     return deviceSettings.retrieveAsInt("DeviceStateInfo.availableMemory");
120029 });
120030
120031 _self.__defineGetter__("language", function () {
120032     return deviceSettings.retrieve("DeviceStateInfo.language");
120033 });
120034
120035 _self.__defineGetter__("keypadLightOn", function () {
120036     return deviceSettings.retrieveAsBoolean("DeviceStateInfo.keypadLightOn");
120037 });
120038
120039 _self.__defineGetter__("backLightOn", function () {
120040     return deviceSettings.retrieveAsBoolean("DeviceStateInfo.backLightOn");
120041 });
120042
120043 _self.__defineGetter__("audioPath", function () {
120044     return deviceSettings.retrieve("DeviceStateInfo.audioPath");
120045 });
120046
120047 _self.__defineGetter__("processorUtilizationPercent", function () {
120048     return deviceSettings.retrieve("DeviceStateInfo.processorUtilizationPercent");
120049 });
120050
120051 module.exports = _self;
120052
120053
120054 });
120055 define('ripple/platform/wac/1.0/EventRecurrenceTypes', function (require, exports, module) {
120056 /*
120057  *  Copyright 2011 Research In Motion Limited.
120058  *
120059  * Licensed under the Apache License, Version 2.0 (the "License");
120060  * you may not use this file except in compliance with the License.
120061  * You may obtain a copy of the License at
120062  *
120063  * http://www.apache.org/licenses/LICENSE-2.0
120064  *
120065  * Unless required by applicable law or agreed to in writing, software
120066  * distributed under the License is distributed on an "AS IS" BASIS,
120067  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120068  * See the License for the specific language governing permissions and
120069  * limitations under the License.
120070  */
120071 module.exports = {
120072     NOT_REPEAT: "NOT_REPEAT",
120073     DAILY: "DAILY",
120074     EVERY_WEEKDAY: "EVERY_WEEKDAY",
120075     WEEKLY_ON_DAY: "WEEKLY_ON_DAY",
120076     MONTHLY_ON_DAY: "MONTHLY_ON_DAY",
120077     MONTHLY_ON_DAY_COUNT: "MONTHLY_ON_DAY_COUNT",
120078     YEARLY: "YEARLY"
120079 };
120080
120081 });
120082 define('ripple/platform/wac/1.0/Exception', function (require, exports, module) {
120083 /*
120084  *  Copyright 2011 Research In Motion Limited.
120085  *
120086  * Licensed under the Apache License, Version 2.0 (the "License");
120087  * you may not use this file except in compliance with the License.
120088  * You may obtain a copy of the License at
120089  *
120090  * http://www.apache.org/licenses/LICENSE-2.0
120091  *
120092  * Unless required by applicable law or agreed to in writing, software
120093  * distributed under the License is distributed on an "AS IS" BASIS,
120094  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120095  * See the License for the specific language governing permissions and
120096  * limitations under the License.
120097  */
120098 module.exports = function () {
120099     this.message = "";
120100     this.type =  "";
120101
120102     this.toString = function () {
120103         var result = this.type + ': "' + this.message + '"';
120104
120105         if (this.stack) {
120106             result += "\n" + this.stack;
120107         }
120108         return result;
120109     };
120110 };
120111
120112 });
120113 define('ripple/platform/wac/1.0/ExceptionTypes', function (require, exports, module) {
120114 /*
120115  *  Copyright 2011 Research In Motion Limited.
120116  *
120117  * Licensed under the Apache License, Version 2.0 (the "License");
120118  * you may not use this file except in compliance with the License.
120119  * You may obtain a copy of the License at
120120  *
120121  * http://www.apache.org/licenses/LICENSE-2.0
120122  *
120123  * Unless required by applicable law or agreed to in writing, software
120124  * distributed under the License is distributed on an "AS IS" BASIS,
120125  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120126  * See the License for the specific language governing permissions and
120127  * limitations under the License.
120128  */
120129 var _self =  {};
120130
120131 _self.__defineGetter__("INVALID_PARAMETER", function () {
120132     return "invalid_parameter";
120133 });
120134
120135 _self.__defineGetter__("SECURITY", function () {
120136     return "security";
120137 });
120138
120139 _self.__defineGetter__("UNKNOWN", function () {
120140     return "unknown";
120141 });
120142
120143 _self.__defineGetter__("UNSUPPORTED", function () {
120144     return "unsupported";
120145 });
120146
120147 module.exports = _self;
120148
120149 });
120150 define('ripple/platform/wac/1.0/File', function (require, exports, module) {
120151 /*
120152  *  Copyright 2011 Research In Motion Limited.
120153  *
120154  * Licensed under the Apache License, Version 2.0 (the "License");
120155  * you may not use this file except in compliance with the License.
120156  * You may obtain a copy of the License at
120157  *
120158  * http://www.apache.org/licenses/LICENSE-2.0
120159  *
120160  * Unless required by applicable law or agreed to in writing, software
120161  * distributed under the License is distributed on an "AS IS" BASIS,
120162  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120163  * See the License for the specific language governing permissions and
120164  * limitations under the License.
120165  */
120166 module.expots = function () {
120167     this.createDate = undefined;
120168     this.fileName = undefined;
120169     this.filePath = undefined;
120170     this.fileSize = undefined;
120171     this.isDirectory = undefined;
120172     this.lastModifyDate = undefined;
120173 };
120174
120175 });
120176 define('ripple/platform/wac/1.0/Message', function (require, exports, module) {
120177 /*
120178  *  Copyright 2011 Research In Motion Limited.
120179  *
120180  * Licensed under the Apache License, Version 2.0 (the "License");
120181  * you may not use this file except in compliance with the License.
120182  * You may obtain a copy of the License at
120183  *
120184  * http://www.apache.org/licenses/LICENSE-2.0
120185  *
120186  * Unless required by applicable law or agreed to in writing, software
120187  * distributed under the License is distributed on an "AS IS" BASIS,
120188  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120189  * See the License for the specific language governing permissions and
120190  * limitations under the License.
120191  */
120192 var exception = require('ripple/exception'),
120193     Attachment = require('ripple/platform/wac/1.0/Attachment'),
120194     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
120195     Exception = require('ripple/platform/wac/1.0/Exception');
120196
120197 function _throwUnsupportedException(method) {
120198     exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
120199 }
120200
120201 module.exports = function () {
120202     this.messageId = Math.uuid(undefined, 16);
120203     this.callbackNumber = undefined;
120204     this.destinationAddress = [];
120205     this.isRead = undefined;
120206     this.messagePriority = undefined;
120207     this.messageType = undefined;
120208     this.subject = undefined;
120209     this.body = undefined;
120210     this.sourceAddress = undefined;
120211     this.validityPeriodHours = undefined;
120212     this.time = undefined;
120213     this.ccAddress = [];
120214     this.bccAddress = [];
120215     this.attachments = [];
120216
120217     this.addAttachment = function (fileFullName) {
120218         var attachment = new Attachment();
120219         attachment.fileName = fileFullName;
120220         this.attachments.push(attachment);
120221     };
120222     this.deleteAttachment = function (attachment) {
120223
120224         for (var i = this.attachments.length - 1; i >= 0; i--) {
120225             if (this.attachments[i].fileName === attachment.fileName) {
120226                 this.attachments.splice(i, 1);
120227             }
120228         }
120229     };
120230     this.saveAttachment = function (fileFullName, attachment) {
120231         _throwUnsupportedException("Widget.Messaging.Message.addAddress");
120232     };
120233     this.addAddress = function (type, address) {
120234
120235         var addresses = address.split(";");
120236
120237         switch (type) {
120238         case "destination":
120239             this.destinationAddress = this.destinationAddress.concat(addresses);
120240             break;
120241         case "cc":
120242             this.ccAddress = this.ccAddress.concat(addresses);
120243             break;
120244         case "bcc":
120245             this.bccAddress = this.bccAddress.concat(addresses);
120246             break;
120247         }
120248     };
120249
120250     this.deleteAddress = function (type, address) {
120251         var addresses = address.split(";"),
120252             filter = function (orig) {
120253                 return orig.filter(function (address) {
120254                     return !addresses.some(function (x) {
120255                         return address === x;
120256                     });
120257                 });
120258             };
120259
120260         switch (type) {
120261         case "destination":
120262             this.destinationAddress = filter(this.destinationAddress);
120263             break;
120264         case "cc":
120265             this.ccAddress = filter(this.ccAddress);
120266             break;
120267         case "bcc":
120268             this.bccAddress = filter(this.bccAddress);
120269             break;
120270         }
120271     };
120272
120273 };
120274
120275 });
120276 define('ripple/platform/wac/1.0/MessageFolderTypes', function (require, exports, module) {
120277 /*
120278  *  Copyright 2011 Research In Motion Limited.
120279  *
120280  * Licensed under the Apache License, Version 2.0 (the "License");
120281  * you may not use this file except in compliance with the License.
120282  * You may obtain a copy of the License at
120283  *
120284  * http://www.apache.org/licenses/LICENSE-2.0
120285  *
120286  * Unless required by applicable law or agreed to in writing, software
120287  * distributed under the License is distributed on an "AS IS" BASIS,
120288  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120289  * See the License for the specific language governing permissions and
120290  * limitations under the License.
120291  */
120292 module.exports = {
120293     DRAFTS: "drafts",
120294     INBOX: "inbox",
120295     OUTBOX: "outbox",
120296     SENTBOX: "sentbox"
120297 };
120298
120299 });
120300 define('ripple/platform/wac/1.0/MessageQuantities', function (require, exports, module) {
120301 /*
120302  *  Copyright 2011 Research In Motion Limited.
120303  *
120304  * Licensed under the Apache License, Version 2.0 (the "License");
120305  * you may not use this file except in compliance with the License.
120306  * You may obtain a copy of the License at
120307  *
120308  * http://www.apache.org/licenses/LICENSE-2.0
120309  *
120310  * Unless required by applicable law or agreed to in writing, software
120311  * distributed under the License is distributed on an "AS IS" BASIS,
120312  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120313  * See the License for the specific language governing permissions and
120314  * limitations under the License.
120315  */
120316 module.exports = {
120317     totalMessageCnt: undefined,
120318     totalMessageReadCnt: undefined,
120319     totalMessageUnreadCnt: undefined
120320 };
120321
120322 });
120323 define('ripple/platform/wac/1.0/MessageTypes', function (require, exports, module) {
120324 /*
120325  *  Copyright 2011 Research In Motion Limited.
120326  *
120327  * Licensed under the Apache License, Version 2.0 (the "License");
120328  * you may not use this file except in compliance with the License.
120329  * You may obtain a copy of the License at
120330  *
120331  * http://www.apache.org/licenses/LICENSE-2.0
120332  *
120333  * Unless required by applicable law or agreed to in writing, software
120334  * distributed under the License is distributed on an "AS IS" BASIS,
120335  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120336  * See the License for the specific language governing permissions and
120337  * limitations under the License.
120338  */
120339 module.exports = {
120340     EmailMessage: "email",
120341     MMSMessage: "mms",
120342     SMSMessage: "sms"
120343 };
120344
120345 });
120346 define('ripple/platform/wac/1.0/Messaging', function (require, exports, module) {
120347 /*
120348  *  Copyright 2011 Research In Motion Limited.
120349  *
120350  * Licensed under the Apache License, Version 2.0 (the "License");
120351  * you may not use this file except in compliance with the License.
120352  * You may obtain a copy of the License at
120353  *
120354  * http://www.apache.org/licenses/LICENSE-2.0
120355  *
120356  * Unless required by applicable law or agreed to in writing, software
120357  * distributed under the License is distributed on an "AS IS" BASIS,
120358  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120359  * See the License for the specific language governing permissions and
120360  * limitations under the License.
120361  */
120362 var exception = require('ripple/exception'),
120363     utils = require('ripple/utils'),
120364     constants = require('ripple/constants'),
120365     notifications = require('ripple/notifications'),
120366     _console = require('ripple/console'),
120367     Message = require('ripple/platform/wac/1.0/Message'),
120368     MessageTypes = require('ripple/platform/wac/1.0/MessageTypes'),
120369     Exception = require('ripple/platform/wac/1.0/Exception'),
120370     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes');
120371
120372 function _throwUnsupportedException(method) {
120373     exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
120374 }
120375
120376 module.exports = {
120377     onMessageArrived: undefined,
120378     onMessageSendingFailure: undefined,
120379     onMessagesFound: undefined,
120380
120381     createMessage: function (messageType) {
120382         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "createMessage invalid number of arguments", new Exception());
120383         utils.validateArgumentType(messageType, "string", ExceptionTypes.INVALID_PARAMETER, "createMessage invalid arguments", new Exception());
120384
120385         if (!utils.some(MessageTypes, function (value) {
120386                 return value === messageType;
120387             })) {
120388             exception.raise(ExceptionTypes.INVALID_PARAMETER, "createMessage invalid arguments", new Exception());
120389         }
120390
120391         var message = new Message();
120392         message.messageType = messageType;
120393
120394         return message;
120395     },
120396     deleteMessage: function () {
120397         _throwUnsupportedException("Messaging.deleteMessage");
120398     },
120399     getMessage: function () {
120400         _throwUnsupportedException("Messaging.getMessage");
120401     },
120402     getMessageQuantities: function () {
120403         _throwUnsupportedException("Messaging.getMessageQuantities");
120404     },
120405     sendMessage: function (msg) {
120406         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.UNSUPPORTED, "sendMessage invalid number of arguments", new Exception());
120407         if (msg instanceof Message === false) {
120408             exception.raise(ExceptionTypes.INVALID_PARAMETER, "expected a valid Message object", new Exception());
120409         }
120410
120411         //TODO: Must be modded to fail and to then call the onMessageSendingFailure callback
120412         var message = "Sent " + msg.messageType + " " + msg.messageId + " to " + msg.destinationAddress;
120413
120414         // insert fail check here
120415         notifications.openNotification("normal", message);
120416         _console.log(message);
120417     },
120418     moveMessageToFolder: function () {
120419         _throwUnsupportedException("Messaging.moveMessageToFolder");
120420     },
120421     copyMessageToFolder: function () {
120422         _throwUnsupportedException("Messaging.copyMessageToFolder");
120423     },
120424     createFolder: function () {
120425         _throwUnsupportedException("Messaging.createFolder");
120426     },
120427     deleteFolder: function () {
120428         _throwUnsupportedException("Messaging.deleteFolder");
120429     },
120430     getFolderNames: function () {
120431         _throwUnsupportedException("Messaging.getFolderNames");
120432     },
120433     findMessages: function () {
120434         _throwUnsupportedException("Messaging.findMessages");
120435     },
120436     getCurrentEmailAccount: function () {
120437         _throwUnsupportedException("Messaging.getCurrentEmailAccount");
120438     },
120439     getEmailAccounts: function () {
120440         _throwUnsupportedException("Messaging.getEmailAccounts");
120441     },
120442     setCurrentEmailAccount: function () {
120443         _throwUnsupportedException("Messaging.setCurrentEmailAccount");
120444     },
120445     deleteEmailAccount: function () {
120446         _throwUnsupportedException("Messaging.deleteEmailAccount");
120447     }
120448
120449 };
120450
120451 });
120452 define('ripple/platform/wac/1.0/Multimedia', function (require, exports, module) {
120453 /*
120454  *  Copyright 2011 Research In Motion Limited.
120455  *
120456  * Licensed under the Apache License, Version 2.0 (the "License");
120457  * you may not use this file except in compliance with the License.
120458  * You may obtain a copy of the License at
120459  *
120460  * http://www.apache.org/licenses/LICENSE-2.0
120461  *
120462  * Unless required by applicable law or agreed to in writing, software
120463  * distributed under the License is distributed on an "AS IS" BASIS,
120464  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120465  * See the License for the specific language governing permissions and
120466  * limitations under the License.
120467  */
120468 var event = require('ripple/event'),
120469     VideoPlayer = require('ripple/platform/wac/1.0/VideoPlayer'),
120470     AudioPlayer = require('ripple/platform/wac/1.0/AudioPlayer'),
120471     constants = require('ripple/constants'),
120472     _volume = 5,
120473     _audioState,
120474     _videoState,
120475     _self;
120476
120477 event.on("MultimediaVolumeChanged", function updateVolume(volume) {
120478     _volume = volume;
120479 });
120480
120481 event.on("MultimediaAudioStateChanged", function updateAudioState(state) {
120482     _audioState = state;
120483 });
120484
120485 event.on("MultimediaVideoStateChanged", function updateVideoState(state) {
120486     _videoState = state;
120487 });
120488
120489 _self = {
120490
120491     isAudioPlaying: undefined,
120492     isVideoPlaying: undefined,
120493
120494     getVolume: function () {
120495         return _volume;
120496     },
120497
120498     stopAll: function () {
120499         VideoPlayer.stop();
120500         AudioPlayer.stop();
120501     }
120502 };
120503
120504 _self.__defineGetter__("isAudioPlaying", function () {
120505     return _audioState === constants.MULTIMEDIA.AUDIO_STATES.PLAYING;
120506 });
120507
120508 _self.__defineGetter__("isVideoPlaying", function () {
120509     return _videoState === "playing";
120510 });
120511
120512 module.exports = _self;
120513
120514 });
120515 define('ripple/platform/wac/1.0/PIM', function (require, exports, module) {
120516 /*
120517  *  Copyright 2011 Research In Motion Limited.
120518  *
120519  * Licensed under the Apache License, Version 2.0 (the "License");
120520  * you may not use this file except in compliance with the License.
120521  * You may obtain a copy of the License at
120522  *
120523  * http://www.apache.org/licenses/LICENSE-2.0
120524  *
120525  * Unless required by applicable law or agreed to in writing, software
120526  * distributed under the License is distributed on an "AS IS" BASIS,
120527  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120528  * See the License for the specific language governing permissions and
120529  * limitations under the License.
120530  */
120531 var _self,
120532     exception = require('ripple/exception'),
120533     Exception = require('ripple/platform/wac/1.0/Exception'),
120534     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
120535     AddressBookItem = require('ripple/platform/wac/1.0/AddressBookItem'),
120536     CalendarItem = require('ripple/platform/wac/1.0/CalendarItem'),
120537     utils = require('ripple/utils'),
120538     db = require('ripple/db'),
120539     constants = require('ripple/constants');
120540
120541 function _throwUnsupportedException(method) {
120542     exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
120543 }
120544
120545 function _toAddressBookItem(contact) {
120546     if (!contact) {
120547         return null;
120548     }
120549
120550     var addressBookItem = new AddressBookItem();
120551
120552     utils.forEach(contact, function (prop, key) {
120553         addressBookItem[key] = contact[key];
120554     });
120555
120556     return addressBookItem;
120557 }
120558
120559 function _toCalendarItem(item) {
120560     if (!item) {
120561         return null;
120562     }
120563
120564     var calendarItem = new CalendarItem();
120565
120566     utils.forEach(item, function (prop, key) {
120567         calendarItem[key] = item[key];
120568     });
120569
120570     return calendarItem;
120571 }
120572
120573 function _getData(type) {
120574     var data = db.retrieveObject(type) || [];
120575     return data;
120576 }
120577
120578 function _saveData(type, items) {
120579     db.saveObject(type, items);
120580 }
120581
120582 function _getContacts() {
120583     var contacts = _getData(constants.PIM.ADDRESS_LIST_KEY),
120584         gord,
120585         dan,
120586         brent,
120587         pj,
120588         mark;
120589
120590     if (contacts.length === 0) {
120591
120592         gord = new AddressBookItem();
120593         gord.addressBookItemId = "0";
120594         gord.fullName = "Gord Tanner";
120595         gord.eMail = "gord@tinyHippos.com";
120596         gord.company = "tinyHippos Inc";
120597         gord.title = "Code Poet";
120598         gord.address = "121 Charles Street W, Kitchener, Ontario, Canada";
120599
120600         dan = new AddressBookItem();
120601         dan.addressBookItemId = "1";
120602         dan.fullName = "Dan Silivestru";
120603         dan.eMail = "dan@tinyHippos.com";
120604         dan.company = "tinyHippos Inc";
120605         dan.title = "Co-Founder And Chief Technology Officer";
120606         dan.address = "121 Charles Street W, Kitchener, Ontario, Canada";
120607
120608         pj = new AddressBookItem();
120609         pj.addressBookItemId = "2";
120610         pj.fullName = "PJ Lowe";
120611         pj.eMail = "pj@tinyHippos.com";
120612         pj.company = "tinyHippos Inc";
120613         pj.title = "Co-Founder And Chief Operations Officer";
120614         pj.address = "121 Charles Street W, Kitchener, Ontario, Canada";
120615
120616         brent = new AddressBookItem();
120617         brent.addressBookItemId = "2";
120618         brent.fullName = "Brent Lintner";
120619         brent.eMail = "brent@tinyHippos.com";
120620         brent.company = "tinyHippos Inc";
120621         brent.title = "Co-Founder And Chief Operations Officer";
120622         brent.address = "121 Charles Street W, Kitchener, Ontario, Canada";
120623
120624         mark = new AddressBookItem();
120625         mark.addressBookItemId = "3";
120626         mark.fullName = "Mark McArdle";
120627         mark.eMail = "mark@tinyHippos.com";
120628         mark.company = "tinyHippos Inc";
120629         mark.title = "Chief Executive Officer";
120630         mark.address = "121 Charles Street W, Kitchener, Ontario, Canada";
120631
120632         contacts.push(gord);
120633         contacts.push(dan);
120634         contacts.push(pj);
120635         contacts.push(brent);
120636         contacts.push(mark);
120637
120638         _saveData(constants.PIM.ADDRESS_LIST_KEY, contacts);
120639     }
120640     return contacts.map(_toAddressBookItem);
120641 }
120642
120643 function _getEvents() {
120644     var events = _getData(constants.PIM.CALENDAR_LIST_KEY);
120645     return events.map(_toCalendarItem);
120646 }
120647
120648 function _get(type, id, fetchIDFunc) {
120649     var items = _getData(type);
120650     return items.reduceRight(function (match, item) {
120651         return fetchIDFunc(item) === id ? item : match;
120652     }, null);
120653 }
120654
120655 function _getAddressBookID(item) {
120656     return item.addressBookItemId;
120657 }
120658
120659 function _getCalendarID(item) {
120660     return item.calendarItemId;
120661 }
120662
120663 function _getContact(id) {
120664     return _toAddressBookItem(_get(constants.PIM.ADDRESS_LIST_KEY, id, _getAddressBookID));
120665 }
120666
120667 function _getEvent(id) {
120668     return _toCalendarItem(_get(constants.PIM.CALENDAR_LIST_KEY, id, _getCalendarID));
120669 }
120670
120671 function _add(type, item, idProp) {
120672     var items = _getData(type);
120673
120674     if (!item[idProp]) {
120675         item[idProp] = Math.uuid(undefined, 16);
120676     }
120677
120678     items.push(item);
120679     _saveData(type, items);
120680 }
120681
120682 function _delete(type, id, fetchIDFunc) {
120683     var items = _getData(type);
120684
120685     _saveData(type, items.filter(function (item) {
120686         return fetchIDFunc(item) !== id;
120687     }));
120688 }
120689
120690 function _validateArgs(min, max, len) {
120691     utils.validateNumberOfArguments(min, max, len,
120692         ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception());
120693 }
120694
120695 function _validateType(arg, argType) {
120696     utils.validateArgumentType(arg, argType,
120697         ExceptionTypes.INVALID_PARAMETER,  "argument of wrong type provided",
120698         new Exception());
120699 }
120700
120701 function _validateAddressBookItem(item) {
120702     if ((item instanceof AddressBookItem) === false) {
120703         exception.raise(ExceptionTypes.INVALID_PARAMETER, "invalid contact, not instance of AddressBookItem.", new Exception());
120704     }
120705 }
120706
120707 _self = {
120708     addAddressBookItem: function (contact) {
120709         _validateArgs(1, 1, arguments.length);
120710         _validateAddressBookItem(contact);
120711
120712         _add(constants.PIM.ADDRESS_LIST_KEY, contact, "addressBookItemId");
120713     },
120714     createAddressBookGroup: function (groupName) {
120715         _throwUnsupportedException("Widget.PIM.createAddressBookGroup");
120716     },
120717     createAddressBookItem: function () {
120718         return new AddressBookItem();
120719     },
120720     deleteAddressBookItem: function (contactid) {
120721         _validateArgs(1, 1, arguments.length);
120722         _validateType(contactid, "string");
120723         _delete(constants.PIM.ADDRESS_LIST_KEY, contactid, _getAddressBookID);
120724     },
120725     deleteAddressBookGroup: function (groupName) {
120726         _throwUnsupportedException("Widget.PIM.deleteAddressBookGroup");
120727     },
120728     getAddressBookItem: function (contactid) {
120729         _validateArgs(1, 1, arguments.length);
120730         _validateType(contactid, "string");
120731         return _getContact(contactid);
120732     },
120733     getAddressBookItemsCount: function () {
120734         _validateArgs(0, 0, arguments.length);
120735         var items = _getContacts();
120736         return items.length;
120737     },
120738     getAvailableAddressGroupNames: function () {
120739         _throwUnsupportedException("Widget.PIM.getAvailableAddressGroupNames");
120740     },
120741     getAddressBookGroupMembers: function (groupName) {
120742         _throwUnsupportedException("Widget.PIM.getAddressBookGroupMembers");
120743     },
120744     findAddressBookItems: function (comparisonContact, startInx, endInx) {
120745         _validateArgs(3, 3, arguments.length);
120746         utils.validateMultipleArgumentTypes([comparisonContact, startInx, endInx], ["object", "number", "number"], ExceptionTypes.INVALID_PARAMETER,  "argument of wrong type provided",
120747             new Exception());
120748
120749         if (endInx < 0) {
120750             exception.raise(ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception());
120751         }
120752
120753         startInx = startInx < 0 ? 0 : startInx;
120754
120755         var contacts = _getContacts();
120756         utils.find(comparisonContact, contacts, startInx, endInx, _self.onAddressBookItemsFound);
120757     },
120758
120759     addCalendarItem: function (calendarItem) {
120760         _validateArgs(1, 1, arguments.length);
120761         _add(constants.PIM.CALENDAR_LIST_KEY, calendarItem, "calendarItemId");
120762     },
120763     deleteCalendarItem: function (calendarId) {
120764         _validateArgs(1, 1, arguments.length);
120765         _delete(constants.PIM.CALENDAR_LIST_KEY, calendarId, _getCalendarID);
120766     },
120767     getCalendarItem: function (calendarId) {
120768         _validateArgs(1, 1, arguments.length);
120769         return _getEvent(calendarId);
120770     },
120771     findCalendarItems: function (itemToMatch, startInx, endInx) {
120772         _validateArgs(1, 3, arguments.length);
120773         var events = _getEvents();
120774         utils.find(itemToMatch, events, startInx, endInx, _self.onCalendarItemsFound);
120775     },
120776     getCalendarItems: function (startTime, endTime) {
120777         var events = _getEvents();
120778
120779         return events.reduce(function (matches, event) {
120780             if (event.eventStartTime >= startTime && event.eventStartTime <= endTime) {
120781                 matches.push(event);
120782             }
120783             return matches;
120784         }, []);
120785     },
120786     exportAsVCard: function (addressBookItems) {
120787         _throwUnsupportedException("Widget.PIM.exportAsVCard");
120788     },
120789
120790     onAddressBookItemsFound: undefined, // function (addressBookItemsFound) { }
120791     onCalendarItemsFound: undefined, // function (calendarItemsFound) { }
120792     onCalendarItemAlert: undefined, // function (calendarItem) { }
120793     onVCardExportingFinish: undefined // function (vCardFilePath) { }
120794 };
120795
120796 module.exports = _self;
120797
120798 });
120799 define('ripple/platform/wac/1.0/PositionInfo', function (require, exports, module) {
120800 /*
120801  *  Copyright 2011 Research In Motion Limited.
120802  *
120803  * Licensed under the Apache License, Version 2.0 (the "License");
120804  * you may not use this file except in compliance with the License.
120805  * You may obtain a copy of the License at
120806  *
120807  * http://www.apache.org/licenses/LICENSE-2.0
120808  *
120809  * Unless required by applicable law or agreed to in writing, software
120810  * distributed under the License is distributed on an "AS IS" BASIS,
120811  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120812  * See the License for the specific language governing permissions and
120813  * limitations under the License.
120814  */
120815 var geo = require('ripple/geo'),
120816     event = require('ripple/event'),
120817     exception = require('ripple/exception'),
120818     utils = require('ripple/utils'),
120819     _self = {
120820         latitude: undefined,
120821         longitude: undefined,
120822         altitude: undefined,
120823         cellID: undefined,
120824         accuracy: undefined,
120825         altitudeAccuracy: undefined,
120826         timeStamp: undefined
120827     };
120828
120829 utils.forEach(_self, function (value, property) {
120830     _self.__defineGetter__(property, function () {
120831         return geo.getPositionInfo()[property];
120832     });
120833 });
120834
120835 module.exports = _self;
120836
120837 });
120838 define('ripple/platform/wac/1.0/PowerInfo', function (require, exports, module) {
120839 /*
120840  *  Copyright 2011 Research In Motion Limited.
120841  *
120842  * Licensed under the Apache License, Version 2.0 (the "License");
120843  * you may not use this file except in compliance with the License.
120844  * You may obtain a copy of the License at
120845  *
120846  * http://www.apache.org/licenses/LICENSE-2.0
120847  *
120848  * Unless required by applicable law or agreed to in writing, software
120849  * distributed under the License is distributed on an "AS IS" BASIS,
120850  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120851  * See the License for the specific language governing permissions and
120852  * limitations under the License.
120853  */
120854 var _self,
120855     event = require('ripple/event'),
120856     _console = require('ripple/console'),
120857     deviceSettings = require('ripple/deviceSettings'),
120858     _lastPercentRemaining;
120859
120860 _self = {
120861     isCharging: undefined,
120862     percentRemaining: undefined,
120863
120864     onChargeStateChange: undefined,
120865     onLowBattery: undefined,
120866     onChargeLevelChange: undefined
120867 };
120868
120869 function _getCurrentChargeState(percentRemaining, isCharging) {
120870     var batteryState;
120871     if (percentRemaining === 100 && isCharging) {
120872         batteryState = "full";
120873     }
120874     else if (!isCharging) {
120875         batteryState = "discharging";
120876     }
120877     else {
120878         batteryState = "charging";
120879     }
120880     return batteryState;
120881 }
120882
120883 event.on("DeviceBatteryStateChanged", function (isCharging) {
120884     var callback = _self.onChargeStateChange,
120885         msg = "",
120886         batteryLevel = _self.percentRemaining,
120887         batteryState;
120888
120889     batteryState = _getCurrentChargeState(batteryLevel, isCharging);
120890
120891     msg += "Fired onChargeStateChange with batteryState: " + batteryState;
120892
120893     if (callback && typeof callback === "function") {
120894         callback.apply(null, [batteryState]);
120895     }
120896     else {
120897         msg += " --> BUT there was no registered callback found.";
120898     }
120899
120900     _console.log(msg);
120901 });
120902
120903 event.on("DeviceBatteryLevelChanged", function (percentRemaining) {
120904
120905     var callback = _self.onChargeLevelChange,
120906         lowBatteryCallback = _self.onLowBattery,
120907         msg = "Fired onChargeLevelChange with percentRemaining: " + percentRemaining;
120908
120909     // blah, stupid Options returning strings
120910     percentRemaining = parseInt(percentRemaining, 10);
120911
120912     if (callback && typeof callback === "function") {
120913         callback.apply(null, [percentRemaining]);
120914     }
120915     else {
120916         msg += " --> BUT there was no registered callback found.";
120917     }
120918
120919     _console.log(msg);
120920
120921     if (percentRemaining <= 10) {
120922
120923         msg = "Fired onLowBattery with percentRemaining: " + percentRemaining;
120924
120925         if (lowBatteryCallback && typeof lowBatteryCallback === "function") {
120926             lowBatteryCallback.apply(null, [percentRemaining]);
120927         }
120928         else {
120929             msg += " --> BUT there was no registered callback found.";
120930         }
120931
120932         _console.log(msg);
120933     }
120934
120935     if (percentRemaining === 100 || (percentRemaining < 100 && _lastPercentRemaining === 100)) {
120936         event.trigger("DeviceBatteryStateChanged", [_self.isCharging]);
120937     }
120938
120939     _lastPercentRemaining = percentRemaining;
120940
120941 });
120942
120943 _self.__defineGetter__("isCharging", function () {
120944     return deviceSettings.retrieveAsBoolean("PowerInfo.isCharging");
120945 });
120946
120947 _self.__defineGetter__("percentRemaining", function () {
120948     return deviceSettings.retrieveAsInt("PowerInfo.percentRemaining");
120949 });
120950
120951 module.exports = _self;
120952
120953 });
120954 define('ripple/platform/wac/1.0/RadioInfo', function (require, exports, module) {
120955 /*
120956  *  Copyright 2011 Research In Motion Limited.
120957  *
120958  * Licensed under the Apache License, Version 2.0 (the "License");
120959  * you may not use this file except in compliance with the License.
120960  * You may obtain a copy of the License at
120961  *
120962  * http://www.apache.org/licenses/LICENSE-2.0
120963  *
120964  * Unless required by applicable law or agreed to in writing, software
120965  * distributed under the License is distributed on an "AS IS" BASIS,
120966  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120967  * See the License for the specific language governing permissions and
120968  * limitations under the License.
120969  */
120970 var _self,
120971     event = require('ripple/event'),
120972     _console = require('ripple/console'),
120973     deviceSettings = require('ripple/deviceSettings');
120974
120975 _self = {
120976     isRoaming: undefined,
120977     radioSignalStrengthPercent: undefined,
120978     isRadioEnabled: undefined,
120979     radioSignalSource: undefined,
120980     onSignalSourceChange: undefined
120981 };
120982
120983 event.on("RadioSignalSourceChanged", function () {
120984     var callback = _self.onSignalSourceChange,
120985         isRoaming = _self.isRoaming,
120986         signalSource = _self.radioSignalSource,
120987         msg = "Fired onSignalSourceChange. signalSource: " + signalSource + ", isRoaming: " + isRoaming;
120988
120989     if (callback && typeof callback === "function") {
120990         callback.apply(null, [signalSource, isRoaming]);
120991     }
120992     else {
120993         msg += " --> BUT there was no registered callback found.";
120994     }
120995
120996     _console.log(msg);
120997 });
120998
120999 _self.__defineGetter__("radioSignalSource", function () {
121000     return deviceSettings.retrieve("RadioInfo.radioSignalSource");
121001 });
121002
121003 _self.__defineGetter__("isRoaming", function () {
121004     return deviceSettings.retrieveAsBoolean("RadioInfo.isRoaming");
121005 });
121006
121007 _self.__defineGetter__("isRadioEnabled", function () {
121008     return deviceSettings.retrieveAsBoolean("RadioInfo.isRadioEnabled");
121009 });
121010
121011 _self.__defineGetter__("radioSignalStrengthPercent", function () {
121012     return deviceSettings.retrieveAsInt("RadioInfo.radioSignalStrengthPercent");
121013 });
121014
121015 module.exports = _self;
121016
121017 });
121018 define('ripple/platform/wac/1.0/RadioSignalSourceTypes', function (require, exports, module) {
121019 /*
121020  *  Copyright 2011 Research In Motion Limited.
121021  *
121022  * Licensed under the Apache License, Version 2.0 (the "License");
121023  * you may not use this file except in compliance with the License.
121024  * You may obtain a copy of the License at
121025  *
121026  * http://www.apache.org/licenses/LICENSE-2.0
121027  *
121028  * Unless required by applicable law or agreed to in writing, software
121029  * distributed under the License is distributed on an "AS IS" BASIS,
121030  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121031  * See the License for the specific language governing permissions and
121032  * limitations under the License.
121033  */
121034 var _self,
121035     utils = require('ripple/utils');
121036
121037 _self = {
121038     "CDMA": undefined,
121039     "GSM": undefined,
121040     "LTE": undefined,
121041     "TDSCDMA": undefined,
121042     "WCDMA": undefined
121043 };
121044
121045 utils.forEach(_self, function (value, property) {
121046     _self.__defineGetter__(property, function () {
121047         return property;
121048     });
121049 });
121050
121051 module.exports = _self;
121052
121053 });
121054 define('ripple/platform/wac/1.0/Telephony', function (require, exports, module) {
121055 /*
121056  *  Copyright 2011 Research In Motion Limited.
121057  *
121058  * Licensed under the Apache License, Version 2.0 (the "License");
121059  * you may not use this file except in compliance with the License.
121060  * You may obtain a copy of the License at
121061  *
121062  * http://www.apache.org/licenses/LICENSE-2.0
121063  *
121064  * Unless required by applicable law or agreed to in writing, software
121065  * distributed under the License is distributed on an "AS IS" BASIS,
121066  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121067  * See the License for the specific language governing permissions and
121068  * limitations under the License.
121069  */
121070 var _self,
121071     exception = require('ripple/exception'),
121072     utils = require('ripple/utils'),
121073     db = require('ripple/db'),
121074     constants = require('ripple/constants'),
121075     Device = require('ripple/platform/wac/1.0/Device'),
121076     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
121077     Exception = require('ripple/platform/wac/1.0/Exception');
121078
121079
121080 function _throwUnsupportedException(method) {
121081     exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
121082 }
121083
121084 _self = {
121085
121086     // Public Callbacks
121087     onCallEvent: undefined,// function (callType, phoneNumber) { },
121088     onCallRecordsFound: undefined,// function (callRecords) { };
121089
121090     // Public Methods
121091     initiateVoiceCall: function (phoneNumber) {
121092         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "initiateVoiceCall invalid number of parameters", new Exception());
121093         //HACK: should this be hardcoded?
121094         //I am still not even sure this is the correct behaviour
121095         Device.launchApplication("PHONECALL", phoneNumber);
121096
121097         if (_self.onCallEvent) {
121098             //HACK: shouldn't be hardcoded
121099             //also what should the context be? isn't spec'ed
121100             _self.onCallEvent.apply(_self, ["outgoing", phoneNumber]);
121101         }
121102     },
121103     getCallRecordCnt: function (callRecordType) {
121104         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "getCallRecordCnt invalid number of parameters", new Exception());
121105         var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY);
121106
121107         return utils.sum(calls, function (call) {
121108             return call.callRecordType === callRecordType;
121109         });
121110     },
121111     getCallRecord: function (callRecordType, id) {
121112         utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "getCallRecord invalid number of parameters", new Exception());
121113         var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY);
121114
121115         return utils.map(calls, function (call) {
121116             return call.callRecordType === callRecordType ? call : null;
121117         }).reduce(function (match, call) {
121118             return match || call.callRecordId === id || null;
121119         }, null);
121120     },
121121     deleteCallRecord: function (callRecordType, id) {
121122         utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "deleteCallRecord invalid number of parameters", new Exception());
121123         var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY),
121124             indexToDelete = calls.reduce(function (result, call, index) {
121125                 return call.callRecordType === callRecordType &&
121126                        call.callRecordId === id ? index : result;
121127             }, -1);
121128
121129         if (indexToDelete >= 0) {
121130             calls.splice(indexToDelete, 1);
121131             db.saveObject(constants.TELEPHONY.CALL_LIST_KEY, calls);
121132         }
121133
121134     },
121135
121136     deleteAllCallRecords: function (callRecordType) {
121137         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "deleteAllCallRecords invalid number of parameters", new Exception());
121138         var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY),
121139             indexesToDelete = calls.reduce(function (result, call, index) {
121140                 if (call.callRecordType === callRecordType) {
121141                     result.push(index);
121142                 }
121143                 return result;
121144             }, []);
121145
121146         utils.forEach(indexesToDelete, function (index) {
121147             calls.splice(index, 1);
121148         });
121149
121150         if (indexesToDelete.length > 0) {
121151             db.saveObject(constants.TELEPHONY.CALL_LIST_KEY, calls);
121152         }
121153
121154     },
121155
121156     findCallRecords: function (comparisonRecord, startInx, endInx) {
121157         utils.validateNumberOfArguments(1, 3, arguments.length, ExceptionTypes.INVALID_PARAMETER, "findCallRecords invalid number of parameters", new Exception());
121158         var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY);
121159         utils.find(comparisonRecord, calls, startInx, endInx, _self.onCallRecordsFound);
121160
121161     }
121162
121163 };
121164
121165 module.exports = _self;
121166
121167 });
121168 define('ripple/platform/wac/1.0/VideoPlayer', function (require, exports, module) {
121169 /*
121170  *  Copyright 2011 Research In Motion Limited.
121171  *
121172  * Licensed under the Apache License, Version 2.0 (the "License");
121173  * you may not use this file except in compliance with the License.
121174  * You may obtain a copy of the License at
121175  *
121176  * http://www.apache.org/licenses/LICENSE-2.0
121177  *
121178  * Unless required by applicable law or agreed to in writing, software
121179  * distributed under the License is distributed on an "AS IS" BASIS,
121180  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121181  * See the License for the specific language governing permissions and
121182  * limitations under the License.
121183  */
121184 var _self,
121185     _console = require('ripple/console'),
121186     event = require('ripple/event'),
121187     utils = require('ripple/utils'),
121188     fileSystem = require('ripple/fileSystem'),
121189     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
121190     Exception = require('ripple/platform/wac/1.0/Exception'),
121191     exception = require('ripple/exception'),
121192     _currentlySet,
121193     _currentVideoFile,
121194     _state = null,
121195     _loopCount, _video,
121196     _STATES = {
121197         "OPENED": "opened",
121198         "STOPPED": "stopped",
121199         "PAUSED": "paused",
121200         "PLAYING": "playing",
121201         "COMPLETED": "completed"
121202     };
121203
121204 function _validateVideoType(fileUrl) {
121205     var matched = fileUrl.match(/\.(\w*)$/),
121206         maps = {
121207             "ogv": "ogg",
121208             "flv": "mp4"
121209         },
121210         type = matched ? matched[1] : "";
121211
121212     if (_video && _video.canPlayType("video/" + (maps[type] || type)) === "") {
121213         _console.warn("Attempting to load a video that might not work in the current browser [" + fileUrl + "]");
121214     }
121215 }
121216
121217 function _validateAndSet(state, validStates, callbackBeforeSuccess) {
121218     var i, valid = false;
121219
121220     for (i = 0; i < validStates.length; i++) {
121221         if (validStates[i] === _state) {
121222             valid = true;
121223         }
121224     }
121225
121226     if (!valid) {
121227         _console.warn("Attempted to initiate VideoPlayer." + state +
121228             " in invalid state. current state: " + _state);
121229     } else {
121230         if (typeof(callbackBeforeSuccess) === "function") {
121231             callbackBeforeSuccess.apply();
121232         }
121233         event.trigger("MultimediaVideoStateChanged", [state], true);
121234     }
121235
121236     return valid;
121237 }
121238
121239 event.on("MultimediaVideoStateChanged", function (state) {
121240     _state = state;
121241     if (typeof _self.onStateChange === "function") {
121242         _self.onStateChange.apply(_self, [state]);
121243     }
121244 });
121245
121246 _self = module.exports = {
121247     onStateChange: undefined,
121248
121249     open: function (fileUrl) {
121250         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER,
121251            "VideoPlayer.open invalid number of arguments", new Exception());
121252         utils.validateArgumentType(fileUrl, "string", ExceptionTypes.INVALID_PARAMETER,
121253            "VideoPlayer.open expected valid fileUrl but got ->" + fileUrl, new Exception());
121254
121255         if (!_video) {
121256             return;
121257         }
121258
121259         _validateAndSet(_STATES.OPENED, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED, null], function () {
121260             _validateVideoType(fileUrl);
121261             _currentVideoFile = fileSystem.getURI(fileUrl);
121262             _video.setAttribute("src", _currentVideoFile);
121263             _video.setAttribute("width", "100%");
121264             _video.addEventListener("ended", function () {
121265                 event.trigger("MultimediaVideoStateChanged", [_STATES.COMPLETED], true);
121266                 if (_loopCount > 1) {
121267                     _self.open(_currentVideoFile);
121268                     _self.play(_loopCount--);
121269                 }
121270             }, false);
121271         });
121272     },
121273
121274     setWindow: function (domObject) {
121275         utils.validateNumberOfArguments(0, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER,
121276            "VideoPlayer.setWindow invalid number of arguments", new Exception());
121277
121278         if (_currentlySet) {
121279             _currentlySet.removeChild(_video);
121280             _currentlySet = null;
121281             _video = null;
121282         }
121283
121284         if (domObject !== null) {
121285             _video = utils.createElement("video", {
121286                 "id": "multimedia-video"
121287             });
121288             domObject.appendChild(_video);
121289             _currentlySet = domObject;
121290             event.trigger("MultimediaAppVideoPlayerCreated", [_video], true);
121291         }
121292     },
121293
121294     play: function (repeatTimes) {
121295         utils.validateNumberOfArguments(1, 1, arguments.length,
121296             ExceptionTypes.INVALID_PARAMETER, "invalid number of arguments (expected one)", new Exception());
121297
121298         if (typeof repeatTimes !== "number" || repeatTimes < 0) {
121299             exception.raise(ExceptionTypes.INVALID_PARAMETER, "VideoPlayer.play was passed an invalid number of play times: " + repeatTimes, new Exception());
121300         }
121301         if (repeatTimes !== 0) {
121302             if (!_video) {
121303                 return;
121304             }
121305             _loopCount = repeatTimes;
121306             _validateAndSet(_STATES.PLAYING, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED], function () {
121307                 _video.play();
121308             });
121309         }
121310     },
121311
121312     pause: function () {
121313         if (!_video) {
121314             return;
121315         }
121316         _validateAndSet(_STATES.PAUSED, [_STATES.PLAYING], function () {
121317             _video.pause();
121318         });
121319     },
121320
121321     resume: function () {
121322         if (!_video) {
121323             return;
121324         }
121325         _validateAndSet(_STATES.PLAYING, [_STATES.PAUSED], function () {
121326             _video.play();
121327         });
121328     },
121329
121330     stop: function () {
121331         if (!_video) {
121332             return;
121333         }
121334         _validateAndSet(_STATES.STOPPED, [_STATES.PAUSED, _STATES.PLAYING], function () {
121335             _video.pause();
121336             _video.setAttribute("src", _currentVideoFile); // hack
121337         });
121338     }
121339
121340 };
121341
121342 });
121343 define('ripple/platform/wac/1.0/Widget', function (require, exports, module) {
121344 /*
121345  *  Copyright 2011 Research In Motion Limited.
121346  *
121347  * Licensed under the Apache License, Version 2.0 (the "License");
121348  * you may not use this file except in compliance with the License.
121349  * You may obtain a copy of the License at
121350  *
121351  * http://www.apache.org/licenses/LICENSE-2.0
121352  *
121353  * Unless required by applicable law or agreed to in writing, software
121354  * distributed under the License is distributed on an "AS IS" BASIS,
121355  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121356  * See the License for the specific language governing permissions and
121357  * limitations under the License.
121358  */
121359 var event = require('ripple/event'),
121360     _console = require('ripple/console'),
121361     app = require('ripple/app'),
121362     platform = require('ripple/platform'),
121363     exception = require('ripple/exception'),
121364     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
121365     Exception = require('ripple/platform/wac/1.0/Exception'),
121366     utils = require('ripple/utils'),
121367     db = require('ripple/db'),
121368     _self;
121369
121370 event.on("ScreenChangeDimensions", function (height, width) {
121371     try {
121372         // TODO: are these per spec to call?
121373         if (typeof app.onMaximize === 'function') {
121374             app.onMaximize();
121375         }
121376         if (typeof app.onRestore === 'function') {
121377             app.onRestore();
121378         }
121379         _console.log("called Widget.onRestore and Widget.onMaximize callback function");
121380     }
121381     catch (e) {
121382         exception.handle(e, false);
121383     }
121384 });
121385
121386 event.on("WidgetWakeup", function () {
121387     if (_self.onWakeup) {
121388         _self.onWakeup();
121389     }
121390 });
121391
121392 event.on("WidgetMaximize", function () {
121393     if (_self.onMaximize) {
121394         _self.onMaximize();
121395     }
121396 });
121397
121398 event.on("WidgetFocus", function () {
121399     if (_self.onFocus) {
121400         _self.onFocus();
121401     }
121402 });
121403
121404 event.on("WidgetRestore", function () {
121405     if (_self.onRestore) {
121406         _self.onRestore();
121407     }
121408 });
121409
121410 _self = {
121411     onWakeup: undefined,
121412     onMaximize: undefined,
121413     onFocus: undefined,
121414     onRestore: undefined,
121415
121416     openURL: function (url) {
121417         window.open(url);
121418     },
121419
121420     setPreferenceForKey: function (value, key) {
121421
121422         utils.validateNumberOfArguments(1, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "setPreferenceForKey invalid number of paramters", new Exception());
121423         utils.validateArgumentType(key, "string", ExceptionTypes.INVALID_PARAMETER, "setPreferenceForKey invalid parameter! Key:" +
121424             key + ", Value: " + value, new Exception());
121425
121426         var msg = "",
121427             prefix;
121428         if (app.isPreferenceReadOnly(key)) {
121429             msg += "Cannot modify a read only preference. Preference key: " + key;
121430         }
121431         else {
121432             prefix = platform.getPersistencePrefix();
121433             if (value === null) {
121434                 msg += "deleting preference " + key;
121435                 db.remove(key, prefix);
121436             }
121437             else {
121438                 msg += "setting preference " + key + " == " + value;
121439                 utils.validateArgumentType(value, "string", ExceptionTypes.INVALID_PARAMETER, msg, new Exception());
121440                 db.save(key, value, prefix);
121441             }
121442         }
121443
121444
121445         _console.log(msg);
121446
121447         // Trigger storageUpdatedEvent
121448         event.trigger("StorageUpdatedEvent");
121449
121450     },
121451
121452     // return value or undefined
121453     preferenceForKey: function (key) {
121454
121455         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "preferenceForKey invalid number of parameters", new Exception());
121456         utils.validateArgumentType(key, "string", ExceptionTypes.INVALID_PARAMETER, "preferenceForKey invalid paramters", new Exception());
121457
121458         var prefix = platform.getPersistencePrefix(),
121459             value = db.retrieve(key, prefix);
121460
121461         if (!value && value !== "") {
121462             value = undefined;
121463         }
121464
121465         _console.log("retrieving preference " + key + " == " + value);
121466
121467         return value;
121468
121469     }
121470 };
121471
121472 module.exports = _self;
121473
121474 });
121475 define('ripple/platform/wac/1.0/WidgetManager', function (require, exports, module) {
121476 /*
121477  *  Copyright 2011 Research In Motion Limited.
121478  *
121479  * Licensed under the Apache License, Version 2.0 (the "License");
121480  * you may not use this file except in compliance with the License.
121481  * You may obtain a copy of the License at
121482  *
121483  * http://www.apache.org/licenses/LICENSE-2.0
121484  *
121485  * Unless required by applicable law or agreed to in writing, software
121486  * distributed under the License is distributed on an "AS IS" BASIS,
121487  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121488  * See the License for the specific language governing permissions and
121489  * limitations under the License.
121490  */
121491 var exception = require('ripple/exception'),
121492     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
121493     Exception = require('ripple/platform/wac/1.0/Exception');
121494
121495 module.exports = {
121496     // This method is used to check the installation status of a specific widget.
121497     checkWidgetInstallationStatus: function () {
121498
121499         exception.raise(ExceptionTypes.UNSUPPORTED, "WidgetManager.checkWidgetInstallationStatus not supported", new Exception());
121500     }
121501 };
121502
121503 });
121504 define('ripple/platform/wac/1.0/spec/config', function (require, exports, module) {
121505 /*
121506  *  Copyright 2011 Research In Motion Limited.
121507  *
121508  * Licensed under the Apache License, Version 2.0 (the "License");
121509  * you may not use this file except in compliance with the License.
121510  * You may obtain a copy of the License at
121511  *
121512  * http://www.apache.org/licenses/LICENSE-2.0
121513  *
121514  * Unless required by applicable law or agreed to in writing, software
121515  * distributed under the License is distributed on an "AS IS" BASIS,
121516  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121517  * See the License for the specific language governing permissions and
121518  * limitations under the License.
121519  */
121520 var platform = require('ripple/platform'),
121521     utils = require('ripple/utils'),
121522     db = require('ripple/db'),
121523     constants = require('ripple/constants');
121524
121525 module.exports = {
121526     fileName: "config.xml",
121527     validateVersion: function (configValidationObject) {
121528         var valid = true;
121529         valid = !((!configValidationObject.widget.validationResult[0].attributes.xmlns.valid) ||
121530             (!configValidationObject.widget.validationResult[0].attributes["xmlns:JIL"].valid));
121531
121532         return valid;
121533     },
121534     extractInfo: function (configValidationObject) {
121535         if (!configValidationObject) {
121536             return null;
121537         }
121538
121539         var widgetInfo = {},
121540             configFeatures,
121541             configPreferences,
121542             preferenceName,
121543             platform;
121544
121545         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
121546         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
121547         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
121548         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
121549
121550         widgetInfo.features = {};
121551
121552         configFeatures = configValidationObject.widget.children.feature.validationResult;
121553         utils.forEach(configFeatures, function (f) {
121554             if (f.valid === true) {
121555                 var feature = {id: f.attributes.name.value,
121556                          required: f.attributes.required.valid};
121557                 widgetInfo.features[feature.id] = feature;
121558             }
121559         });
121560
121561         widgetInfo.preferences = {};
121562
121563         configPreferences = configValidationObject.widget.children.preference.validationResult;
121564
121565         platform = require('ripple/platform');
121566         utils.forEach(configPreferences, function (preference) {
121567             preferenceName = preference.attributes.name.value;
121568             if (preferenceName) {
121569                 widgetInfo.preferences[preferenceName] = {
121570                     "key": preferenceName,
121571                     "value": preference.attributes.value.value || "",
121572                     "readonly": preference.attributes.readonly.value === "true"
121573                 };
121574
121575                 db.save(preferenceName,
121576                         widgetInfo.preferences[preferenceName].value,
121577                         platform.getPersistencePrefix(widgetInfo.id));
121578             }
121579         });
121580
121581         return widgetInfo;
121582     },
121583     schema: {
121584         rootElement: "widget",
121585         widget: {
121586             nodeName: "widget",
121587             required: true,
121588             occurrence: 1,
121589             helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in configuration document and may have following child elments: name,description,icon,author,license,content,maximum_display_mode,update,feature,access,billing. \"widget\" element MAY have following attributes: id,version,height,width,xml:lang",
121590             attributes: {
121591                 xmlns: {
121592                     attributeName: "xmlns",
121593                     required: true,
121594                     type: "list",
121595                     listValues: ["http://www.w3.org/ns/widgets"]
121596                 },
121597                 "xmlns:JIL": {
121598                     attributeName: "xmlns:JIL",
121599                     required: true,
121600                     type: "list",
121601                     listValues: ["http://www.jil.org/ns/widgets1.2"]
121602                 },
121603                 "xmlns:its": {
121604                     attributeName: "xmlns:its",
121605                     helpText: "Indicates Text Directionality can be used. According to W3C spec, this feature is at risk, therefore we don't currently validate this.",
121606                     required: false,
121607                     type: "string"
121608                 },
121609                 id: {
121610                     attributeName: "id",
121611                     required: true,
121612                     type: "string"
121613                 },
121614                 version: {
121615                     attributeName: "version",
121616                     helpText: "Version must be in the following format: jil-rec-version-tag = major-version \".\" minor-version [\".\" version-desc]",
121617                     required: true,
121618                     type: "regex",
121619                     regex: /^\d{1,2}\.\d{1,2}(\.[A-Za-z0-9]{1,10})?$/
121620                 },
121621                 height: {
121622                     attributeName: "height",
121623                     required: true,
121624                     type: "integer"
121625                 },
121626                 width: {
121627                     attributeName: "width",
121628                     required: true,
121629                     type: "integer"
121630                 },
121631                 viewmodes: {
121632                     attributeName: "viewmodes",
121633                     required: false,
121634                     type: "list",
121635                     listValues: ["floating", "fullscreen"]
121636                 },
121637                 "xml:lang": {
121638                     attributeName: "xml:lang",
121639                     required: false,
121640                     type: "iso-language"
121641                 }
121642             },
121643             children: {
121644                 preference: {
121645                     nodeName: "preference",
121646                     required: false,
121647                     occurrence: 0,
121648                     attributes: {
121649                         name: {
121650                             attributeName: "name",
121651                             type: "string",
121652                             required: true
121653                         },
121654                         value: {
121655                             type: "string",
121656                             attributeName: "value",
121657                             required: false
121658                         },
121659                         readonly: {
121660                             attributeName: "readonly",
121661                             type: "boolean",
121662                             required: false
121663                         }
121664                     }
121665                 },
121666                 name: {
121667                     nodeName: "name",
121668                     required: false,
121669                     occurrence: 0,
121670                     type: "string",
121671                     attributes: {
121672                         "short": {
121673                             attributeName: "short",
121674                             type: "string",
121675                             required: false
121676                         },
121677                         "xml:lang": {
121678                             attributeName: "xml:lang",
121679                             type: "string",
121680                             required: false,
121681                             unique: true
121682                         }
121683                     }
121684                 },
121685                 description: {
121686                     nodeName: "description",
121687                     required: false,
121688                     occurrence: 0,
121689                     type: "string",
121690                     attributes: {
121691                         "xml:lang": {
121692                             attributeName: "xml:lang",
121693                             type: "string",
121694                             required: false,
121695                             unique: true
121696                         }
121697                     }
121698                 },
121699                 icon: {
121700                     nodeName: "icon",
121701                     required: false,
121702                     occurrence: 0,
121703                     attributes: {
121704                         src: {
121705                             attributeName: "src",
121706                             type: "string",
121707                             required: true
121708                         },
121709                         height: {
121710                             attributeName: "height",
121711                             required: false,
121712                             type: "integer"
121713                         },
121714                         width: {
121715                             attributeName: "width",
121716                             required: false,
121717                             type: "integer"
121718                         },
121719                         "xml:lang": {
121720                             attributeName: "xml:lang",
121721                             type: "string",
121722                             required: false,
121723                             unique: true
121724                         }
121725                     }
121726                 },
121727                 author: {
121728                     nodeName: "author",
121729                     required: false,
121730                     occurrence: 1,
121731                     type: "string",
121732                     attributes: {
121733                         email: {
121734                             attributeName: "email",
121735                             type: "regex",
121736                             required: false,
121737                             regex: constants.REGEX.EMAIL
121738                         },
121739                         href: {
121740                             attributeName: "href",
121741                             type: "regex",
121742                             required: false,
121743                             regex: constants.REGEX.URL
121744                         },
121745                         "xml:lang": {
121746                             attributeName: "xml:lang",
121747                             type: "string",
121748                             required: false,
121749                             unique: true
121750                         }
121751                     }
121752                 },
121753                 license: {
121754                     nodeName: "license",
121755                     required: false,
121756                     occurrence: 1,
121757                     type: "string",
121758                     attributes: {
121759                         href: {
121760                             attributeName: "href",
121761                             type: "regex",
121762                             required: false,
121763                             regex: constants.REGEX.URL
121764                         },
121765                         "xml:lang": {
121766                             attributeName: "xml:lang",
121767                             type: "string",
121768                             required: false,
121769                             unique: true
121770                         }
121771                     }
121772                 },
121773                 content: {
121774                     nodeName: "content",
121775                     required: false,
121776                     occurrence: 1,
121777                     attributes: {
121778                         src: {
121779                             attributeName: "src",
121780                             type: "string",
121781                             required: true
121782                         },
121783                         encoding: {
121784                             attributeName: "encoding",
121785                             type: "string",
121786                             required: false
121787                         },
121788                         type: {
121789                             attributeName: "type",
121790                             type: "string",
121791                             required: false
121792                         }
121793                     }
121794                 },
121795                 feature: {
121796                     nodeName: "feature",
121797                     required: false,
121798                     occurrence: 0,
121799                     attributes: {
121800                         name: {
121801                             attributeName: "name",
121802                             type: "list",
121803                             required: true,
121804                             listValues: ["http://jil.org/jil/api/1.1/widget", "http://jil.org/jil/api/1.1.5/exception",
121805                                             "http://jil.org/jil/api/1.1.5/exceptiontypes", "http://jil.org/jil/api/1.1/device",
121806                                             "http://jil.org/jil/api/1.1/accountinfo", "http://jil.org/jil/api/1.1/deviceinfo",
121807                                             "http://jil.org/jil/api/1.1.1/datanetworkinfo", "http://jil.org/jil/api/1.1/devicestateinfo",
121808                                             "http://jil.org/jil/api/1.1/accelerometerinfo", "http://jil.org/jil/api/1.1/config",
121809                                             "http://jil.org/jil/api/1.1.1/file", "http://jil.org/jil/api/1.1/positioninfo",
121810                                             "http://jil.org/jil/api/1.1/powerinfo", "http://jil.org/jil/api/1.1.1/radioinfo",
121811                                             "http://jil.org/jil/api/1.1.5/radiosignalsourcetypes", "http://jil.org/jil/api/1.1.5/applicationtypes",
121812                                             "http://jil.org/jil/api/1.1/messaging", "http://jil.org/jil/api/1.1/account",
121813                                             "http://jil.org/jil/api/1.1/attachment", "http://jil.org/jil/api/1.1/message",
121814                                             "http://jil.org/jil/api/1.1.4/messagefoldertypes", "http://jil.org/jil/api/1.1/messagequantities",
121815                                             "http://jil.org/jil/api/1.1/messagetypes", "http://jil.org/jil/api/1.1/multimedia",
121816                                             "http://jil.org/jil/api/1.1/audioplayer", "http://jil.org/jil/api/1.1.2/camera",
121817                                             "http://jil.org/jil/api/1.1.2/videoplayer", "http://jil.org/jil/api/1.1.1/pim",
121818                                             "http://jil.org/jil/api/1.1/addressbookitem", "http://jil.org/jil/api/1.1/calendaritem",
121819                                             "http://jil.org/jil/api/1.1/eventrecurrencetypes", "http://jil.org/jil/api/1.1.1/telephony",
121820                                             "http://jil.org/jil/api/1.1/callrecord", "http://jil.org/jil/api/1.1.1/callrecordtypes",
121821                                             "http://jil.org/jil/api/1.1.1/widgetmanager"]
121822                         },
121823                         required: {
121824                             attributeName: "required",
121825                             type: "boolean",
121826                             required: false
121827                         }
121828                     }
121829                 },
121830                 "JIL:maximum_display_mode": {
121831                     nodeName: "JIL:maximum_display_mode",
121832                     required: false,
121833                     occurrence: 1,
121834                     attributes: {
121835                         height: {
121836                             attributeName: "height",
121837                             type: "integer",
121838                             required: false
121839                         },
121840                         width: {
121841                             attributeName: "width",
121842                             type: "integer",
121843                             required: false
121844                         }
121845                     }
121846                 },
121847                 "JIL:update": {
121848                     nodeName: "JIL:update",
121849                     required: false,
121850                     occurrence: 1,
121851                     attributes: {
121852                         href: {
121853                             attributeName: "href",
121854                             type: "regex",
121855                             required: true,
121856                             regex: constants.REGEX.URL
121857                         },
121858                         period: {
121859                             attributeName: "period",
121860                             helpText: "Possible values for the period attribute are: 0, 1, 2, 3 meaning: every time the widget is opened in maximum display mode, every day, every week, every month; respectivly",
121861                             type: "list",
121862                             required: true,
121863                             listValues: ["0", "1", "2", "3"]
121864                         }
121865                     }
121866                 },
121867                 "JIL:access": {
121868                     nodeName: "JIL:access",
121869                     required: false,
121870                     occurrence: 1,
121871                     attributes: {
121872                         network: {
121873                             attributeName: "network",
121874                             type: "boolean",
121875                             required: false
121876                         },
121877                         localfs: {
121878                             attributeName: "localfs",
121879                             type: "boolean",
121880                             required: false
121881                         },
121882                         remote_scripts: {
121883                             attributeName: "remote_scripts",
121884                             type: "boolean",
121885                             required: false
121886                         }
121887                     }
121888                 },
121889                 "JIL:billing": {
121890                     nodeName: "JIL:billing",
121891                     required: false,
121892                     occurrence: 1,
121893                     attributes: {
121894                         required: {
121895                             attributeName: "required",
121896                             type: "boolean",
121897                             required: true
121898                         }
121899                     }
121900                 }
121901             }
121902         }
121903     }
121904 };
121905
121906 });
121907 define('ripple/platform/wac/1.0/spec/device', function (require, exports, module) {
121908 /*
121909  *  Copyright 2011 Research In Motion Limited.
121910  *
121911  * Licensed under the Apache License, Version 2.0 (the "License");
121912  * you may not use this file except in compliance with the License.
121913  * You may obtain a copy of the License at
121914  *
121915  * http://www.apache.org/licenses/LICENSE-2.0
121916  *
121917  * Unless required by applicable law or agreed to in writing, software
121918  * distributed under the License is distributed on an "AS IS" BASIS,
121919  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121920  * See the License for the specific language governing permissions and
121921  * limitations under the License.
121922  */
121923 var constants = require('ripple/constants'),
121924     event = require('ripple/event');
121925
121926 module.exports = {
121927     "AccountInfo": {
121928         "phoneUserUniqueId": {
121929             "name": "User Unique Id",
121930             "control": {
121931                 "type": "text",
121932                 "value": new Date().getTime().toString()
121933             }
121934         },
121935         "phoneMSISDN":  {
121936             "name": "MSISDN",
121937             "control": {
121938                 "type": "text",
121939                 "value": "15199999999"
121940             }
121941         },
121942         "phoneOperatorName":  {
121943             "name": "Operator Name",
121944             "control": {
121945                 "type": "text",
121946                 "value": ""
121947             }
121948         },
121949         "userAccountBalance":  {
121950             "name": "Account Balance",
121951             "control": {
121952                 "type": "number",
121953                 "value": 0
121954             }
121955         },
121956         "userSubscriptionType":  {
121957             "name": "Subscription Type",
121958             "control": {
121959                 "type": "select",
121960                 "value": "other"
121961             },
121962             "options": {
121963                 "other": "other",
121964                 "prepaid": "prepaid",
121965                 "postpaid": "postpaid"
121966             }
121967         }
121968     },
121969     "RadioInfo": {
121970         "isRoaming": {
121971             "name": "Is Roaming",
121972             "control": {
121973                 "type": "checkbox",
121974                 "value": false
121975             },
121976             "callback": function () {
121977                 event.trigger("RadioSignalSourceChanged");
121978             }
121979         },
121980         "isRadioEnabled":  {
121981             "name": "Is Radio Enabled",
121982             "control": {
121983                 "type": "checkbox",
121984                 "value": true
121985             }
121986         },
121987         "radioSignalSource": {
121988             "name": "Radio Signal Source",
121989             "control": {
121990                 "type": "select",
121991                 "value": "GSM"
121992             },
121993             // TODO: try not to duplicate from RadioSignalSourceTypes
121994             "options": {
121995                 "CDMA": "cdma",
121996                 "GSM": "gsm",
121997                 "LTE": "lte",
121998                 "TDSCDMA": "tdscdma",
121999                 "WCDMA": "wcdma"
122000             },
122001             "callback": function () {
122002                 event.trigger("RadioSignalSourceChanged");
122003             }
122004         },
122005         "radioSignalStrengthPercent": {
122006             "name": "Signal Strength %",
122007             "control": {
122008                 "type": "select",
122009                 "value": 80
122010             },
122011             "options": (function () {
122012                 var i,
122013                     optionList = {};
122014
122015                 for (i = 0; i <= 100; i++) {
122016                     optionList[i] = i;
122017                 }
122018
122019                 return optionList;
122020             }())
122021         }
122022     },
122023     "Config": {
122024         "ringtoneVolume": {
122025             "name": "Ringtone Volume",
122026             "control": {
122027                 "type": "select",
122028                 "value": 10
122029             },
122030             "options": (function () {
122031                 var i,
122032                     optionList = {};
122033
122034                 for (i = 0; i <= 10; i++) {
122035                     optionList[i] = i;
122036                 }
122037
122038                 return optionList;
122039             }())
122040         },
122041         "msgRingtoneVolume":  {
122042             "name": "Msg Ringtone Volume",
122043             "control": {
122044                 "type": "select",
122045                 "value": 10
122046             },
122047             "options": (function () {
122048                 var i,
122049                     optionList = {};
122050
122051                 for (i = 0; i <= 10; i++) {
122052                     optionList[i] = i;
122053                 }
122054
122055                 return optionList;
122056             }())
122057         },
122058         "vibrationSetting":  {
122059             "name": "Vibration",
122060             "control": {
122061                 "type": "select",
122062                 "value": "off"
122063             },
122064             "options": {
122065                 "on": "ON",
122066                 "off": "OFF"
122067             }
122068         }
122069     },
122070     "Account": {
122071         "accountName":  {
122072             "name": "Name",
122073             "control": {
122074                 "type": "text",
122075                 "value": ""
122076             }
122077         },
122078         "accountId":  {
122079             "name": "Id",
122080             "control": {
122081                 "type": "text",
122082                 "value": ""
122083             }
122084         }
122085     },
122086     "DeviceInfo": {
122087         "totalMemory": {
122088             "name": "Total Memory",
122089             "control": {
122090                 "type": "range",
122091                 "value": 262144,
122092                 "min": 0,
122093                 "max": 4096000
122094             }
122095         },
122096         "phoneColorDepthDefault": {
122097             "name": "Color Depth",
122098             "control": {
122099                 "type": "number",
122100                 "value": 24
122101             }
122102         }
122103     },
122104     "DeviceStateInfo": {
122105         "availableMemory": {
122106             "name": "Available Memory",
122107             "control": {
122108                 "type": "range",
122109                 "value": 262144,
122110                 "min": 0,
122111                 "max": 4096000
122112             }
122113         },
122114         "keypadLightOn":   {
122115             "name": "Keypad Light On",
122116             "control": {
122117                 "type": "checkbox",
122118                 "value": false
122119             }
122120         },
122121         "backLightOn": {
122122             "name": "Back Light On",
122123             "control": {
122124                 "type": "checkbox",
122125                 "value": false
122126             }
122127         },
122128         "audioPath":  {
122129             "name": "Audio Path",
122130             "control": {
122131                 "type": "select",
122132                 "value": "receiver"
122133             },
122134             "options": {
122135                 "speaker": "speaker",
122136                 "receiver": "receiver",
122137                 "earphone": "earphone"
122138             }
122139         },
122140         "processorUtilizationPercent":  {
122141             "name": "CPU Utilization %",
122142             "control": {
122143                 "type": "select",
122144                 "value": "5"
122145             },
122146             "options": (function () {
122147                 var i,
122148                     optionList = {};
122149
122150                 for (i = 0; i <= 100; i++) {
122151                     optionList[i] = i;
122152                 }
122153
122154                 return optionList;
122155             }())
122156         },
122157         "language":  {
122158             "name": "Language",
122159             "control": {
122160                 "type": "select",
122161                 "value": "eng"
122162             },
122163             "options": (function () {
122164                 var i,
122165                     optionList = {},
122166                     iterator = constants.LANG.ISO6392_LIST;
122167
122168                 for (i = 0; i <= iterator.length; i++) {
122169                     optionList[iterator[i]] = iterator[i];
122170                 }
122171
122172                 return optionList;
122173             }())
122174         }
122175     },
122176     "DataNetworkInfo": {
122177         "isDataNetworkConnected": {
122178             "name": "Data Network Is Connected",
122179             "control": {
122180                 "type": "checkbox",
122181                 "value": true
122182             }
122183         },
122184         "networkConnectionType": {
122185             "name": "Network Connection Type",
122186             "control": {
122187                 "type": "select",
122188                 "value": ["GPRS"]
122189             },
122190             // TODO: try not to duplicate from DataNetworkConnectionTypes
122191             "options": {
122192                 "BLUETOOTH": "bluetooth",
122193                 "EDGE": "edge",
122194                 "EVDO": "evdo",
122195                 "GPRS": "gprs",
122196                 "IRDA": "irda",
122197                 "LTE": "lte",
122198                 "ONEXRTT": "1xrtt",
122199                 "WIFI": "wifi"
122200             },
122201             "callback": function (setting) {
122202                 event.trigger("DataNetworkConnectionChanged", [setting]);
122203             }
122204         }
122205     },
122206     "PowerInfo": {
122207         "isCharging": {
122208             "name": "Battery Is Charging",
122209             "control": {
122210                 "type": "checkbox",
122211                 "value": true
122212             },
122213             "callback": function (setting) {
122214                 event.trigger("DeviceBatteryStateChanged", [setting]);
122215             }
122216         },
122217         "percentRemaining":  {
122218             "name": "Battery Remaining %",
122219             "control": {
122220                 "type": "select",
122221                 "value": 100
122222             },
122223             "options": (function () {
122224                 var i,
122225                     optionList = {};
122226
122227                 for (i = 0; i <= 100; i++) {
122228                     optionList[i] = i;
122229                 }
122230
122231                 return optionList;
122232             }()),
122233             "callback": function (setting) {
122234                 event.trigger("DeviceBatteryLevelChanged", [setting]);
122235             }
122236         }
122237     }
122238 };
122239
122240 });
122241 define('ripple/platform/wac/1.0/spec/events', function (require, exports, module) {
122242 /*
122243  *  Copyright 2011 Research In Motion Limited.
122244  *
122245  * Licensed under the Apache License, Version 2.0 (the "License");
122246  * you may not use this file except in compliance with the License.
122247  * You may obtain a copy of the License at
122248  *
122249  * http://www.apache.org/licenses/LICENSE-2.0
122250  *
122251  * Unless required by applicable law or agreed to in writing, software
122252  * distributed under the License is distributed on an "AS IS" BASIS,
122253  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
122254  * implied.
122255  * See the License for the specific language governing permissions and
122256  * limitations under the License.
122257  */
122258
122259 var event = require('ripple/event');
122260
122261 module.exports = {
122262     "WidgetWakeup": {
122263         callback: function () {
122264             event.trigger("WidgetWakeup");
122265         }
122266     },
122267     "WidgetMaximize": {
122268         callback: function () {
122269             event.trigger("WidgetMaximize");
122270         }
122271     },
122272     "WidgetFocus": {
122273         callback: function () {
122274             event.trigger("WidgetFocus");
122275         }
122276     },
122277     "WidgetRestore": {
122278         callback: function () {
122279             event.trigger("WidgetRestore");
122280         }
122281     }
122282 };
122283
122284 });
122285 define('ripple/platform/wac/1.0/spec/ui', function (require, exports, module) {
122286 /*
122287  *  Copyright 2011 Research In Motion Limited.
122288  *
122289  * Licensed under the Apache License, Version 2.0 (the "License");
122290  * you may not use this file except in compliance with the License.
122291  * You may obtain a copy of the License at
122292  *
122293  * http://www.apache.org/licenses/LICENSE-2.0
122294  *
122295  * Unless required by applicable law or agreed to in writing, software
122296  * distributed under the License is distributed on an "AS IS" BASIS,
122297  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122298  * See the License for the specific language governing permissions and
122299  * limitations under the License.
122300  */
122301 module.exports = {
122302     plugins: [
122303         "accelerometer",
122304         //"deviceSettings",
122305         "fileSystem",
122306         "geoView",
122307 /*
122308         "multimedia",
122309         "audioPlayer",
122310         "telephony",
122311 */
122312         "platformEvents",
122313         "storage",
122314         "widgetConfig"
122315     ]
122316 };
122317
122318 });
122319 define('ripple/platform/wac/1.0/spec', function (require, exports, module) {
122320 module.exports = {
122321
122322     id: "wac",
122323     version: "1.0",
122324     name: "WAC",
122325     type: "plaform",
122326
122327     persistencePrefix: "wac-",
122328
122329     config: require('ripple/platform/wac/1.0/spec/config'),
122330     device: require('ripple/platform/wac/1.0/spec/device'),
122331     ui: require('ripple/platform/wac/1.0/spec/ui'),
122332     events: require('ripple/platform/wac/1.0/spec/events'),
122333
122334     objects: {
122335         navigator: {
122336             path: "w3c/1.0/navigator"
122337         },
122338         WidgetManager: {
122339             path: "wac/1.0/WidgetManager",
122340             feature: "http://jil.org/jil/api/1.1.1/widgetmanager"
122341         },
122342         Widget: {
122343             path: "wac/1.0/Widget",
122344             feature: "http://jil.org/jil/api/1.1/widget",
122345             children: {
122346                 Device: {
122347                     path: "wac/1.0/Device",
122348                     feature: "http://jil.org/jil/api/1.1/device",
122349                     children: {
122350                         AccountInfo: {
122351                             path: "wac/1.0/AccountInfo",
122352                             feature: "http://jil.org/jil/api/1.1/accountinfo"
122353                         },
122354                         ApplicationTypes: {
122355                             path: "wac/1.0/ApplicationTypes",
122356                             feature: "http://jil.org/jil/api/1.1.5/applicationtypes"
122357                         },
122358                         DataNetworkInfo: {
122359                             path: "wac/1.0/DataNetworkInfo",
122360                             feature: "http://jil.org/jil/api/1.1.1/datanetworkinfo",
122361                             children: {
122362                                 DataNetworkConnectionTypes: {
122363                                     path: "wac/1.0/DataNetworkConnectionTypes"
122364                                 }
122365                             }
122366                         },
122367                         DeviceInfo: {
122368                             path: "wac/1.0/DeviceInfo",
122369                             feature: "http://jil.org/jil/api/1.1/deviceinfo"
122370                         },
122371                         DeviceStateInfo: {
122372                             path: "wac/1.0/DeviceStateInfo",
122373                             feature: "http://jil.org/jil/api/1.1/devicestateinfo",
122374                             children: {
122375                                 Config: {
122376                                     path: "wac/1.0/Config",
122377                                     feature: "http://jil.org/jil/api/1.1/config"
122378                                 },
122379                                 AccelerometerInfo: {
122380                                     path: "wac/1.0/AccelerometerInfo",
122381                                     feature: "http://jil.org/jil/api/1.1/accelerometerinfo"
122382                                 }
122383                             }
122384                         },
122385                         File: {
122386                             path: "wac/1.0/File",
122387                             feature: "http://jil.org/jil/api/1.1.1/file"
122388                         },
122389                         PositionInfo: {
122390                             path: "wac/1.0/PositionInfo",
122391                             feature: "http://jil.org/jil/api/1.1/positioninfo"
122392                         },
122393                         RadioInfo: {
122394                             path: "wac/1.0/RadioInfo",
122395                             feature: "http://jil.org/jil/api/1.1.1/radioinfo",
122396                             children: {
122397                                 RadioSignalSourceTypes: {
122398                                     path: "wac/1.0/RadioSignalSourceTypes",
122399                                     feature: "http://jil.org/jil/api/1.1.5/radiosignalsourcetypes"
122400                                 }
122401                             }
122402                         },
122403                         PowerInfo: {
122404                             path: "wac/1.0/PowerInfo",
122405                             feature: "http://jil.org/jil/api/1.1/powerinfo"
122406                         }
122407                     }
122408                 },
122409                 ExceptionTypes: {
122410                     path: "wac/1.0/ExceptionTypes",
122411                     feature: "http://jil.org/jil/api/1.1.5/exceptiontypes"
122412                 },
122413                 Exception: {
122414                     path: "wac/1.0/Exception",
122415                     feature: "http://jil.org/jil/api/1.1.5/exception"
122416                 },
122417                 Multimedia: {
122418                     path: "wac/1.0/Multimedia",
122419                     feature: "http://jil.org/jil/api/1.1/multimedia",
122420                     children: {
122421                         Camera: {
122422                             path: "wac/1.0/Camera",
122423                             feature: "http://jil.org/jil/api/1.1.2/camera"
122424                         },
122425                         AudioPlayer: {
122426                             path: "wac/1.0/AudioPlayer",
122427                             feature: "http://jil.org/jil/api/1.1/audioplayer"
122428                         },
122429                         VideoPlayer: {
122430                             path: "wac/1.0/VideoPlayer",
122431                             feature: "http://jil.org/jil/api/1.1.2/videoplayer"
122432                         }
122433                     }
122434                 },
122435                 Telephony: {
122436                     path: "wac/1.0/Telephony",
122437                     feature: "http://jil.org/jil/api/1.1.1/telephony",
122438                     children: {
122439                         CallRecord: {
122440                             path: "wac/1.0/CallRecord",
122441                             feature: "http://jil.org/jil/api/1.1/callrecord"
122442                         },
122443                         CallRecordTypes: {
122444                             path: "wac/1.0/CallRecordTypes",
122445                             feature: "http://jil.org/jil/api/1.1.1/callrecordtypes"
122446                         }
122447                     }
122448                 },
122449                 PIM: {
122450                     path: "wac/1.0/PIM",
122451                     feature: "http://jil.org/jil/api/1.1.1/pim",
122452                     children: {
122453                         AddressBookItem: {
122454                             path: "wac/1.0/AddressBookItem",
122455                             feature: "http://jil.org/jil/api/1.1/addressbookitem"
122456                         },
122457                         CalendarItem: {
122458                             path: "wac/1.0/CalendarItem",
122459                             feature: "http://jil.org/jil/api/1.1/calendaritem"
122460                         },
122461                         EventRecurrenceTypes: {
122462                             path: "wac/1.0/EventRecurrenceTypes",
122463                             feature: "http://jil.org/jil/api/1.1/eventrecurrencetypes"
122464                         }
122465                     }
122466                 },
122467                 Messaging: {
122468                     path: "wac/1.0/Messaging",
122469                     feature: "http://jil.org/jil/api/1.1/messaging",
122470                     children: {
122471                         Account: {
122472                             path: "wac/1.0/Account",
122473                             feature: "http://jil.org/jil/api/1.1/account"
122474                         },
122475                         Attachment: {
122476                             path: "wac/1.0/Attachment",
122477                             feature: "http://jil.org/jil/api/1.1/attachment"
122478                         },
122479                         Message: {
122480                             path: "wac/1.0/Message",
122481                             feature: "http://jil.org/jil/api/1.1/message"
122482                         },
122483                         MessageFolderTypes: {
122484                             path: "wac/1.0/MessageFolderTypes",
122485                             feature: "http://jil.org/jil/api/1.1.4/messagefoldertypes"
122486                         },
122487                         MessageQuantities: {
122488                             path: "wac/1.0/MessageQuantities",
122489                             feature: "http://jil.org/jil/api/1.1/messagequantities"
122490                         },
122491                         MessageTypes: {
122492                             path: "wac/1.0/MessageTypes",
122493                             feature: "http://jil.org/jil/api/1.1/messagetypes"
122494                         }
122495                     }
122496                 }
122497             }
122498         }
122499     }
122500
122501 };
122502
122503 });
122504 define('ripple/platform/wac/2.0/accelerometer', function (require, exports, module) {
122505 /*
122506  *  Copyright 2011 Intel Corporation.
122507  *
122508  * Licensed under the Apache License, Version 2.0 (the "License");
122509  * you may not use this file except in compliance with the License.
122510  * You may obtain a copy of the License at
122511  *
122512  * http://www.apache.org/licenses/LICENSE-2.0
122513  *
122514  * Unless required by applicable law or agreed to in writing, software
122515  * distributed under the License is distributed on an "AS IS" BASIS,
122516  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122517  * See the License for the specific language governing permissions and
122518  * limitations under the License.
122519  */
122520
122521 var utils = require('ripple/utils'),
122522     event = require('ripple/event'),
122523     Acceleration = function (x, y, z) {
122524         return {
122525             xAxis: x || 0,
122526             yAxis: y || 0,
122527             zAxis: z || 0
122528         };
122529     },
122530     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
122531     _accelerometerInfo = new Acceleration(),
122532     _defaultInterval = 100,
122533     _watches = {},
122534     _self;
122535
122536 module.exports = _self = {
122537     getCurrentAcceleration: function (onSuccess, onError) {
122538         function _getCurrentAcceleration() {
122539             setTimeout(function () {
122540                 onSuccess(utils.copy(_accelerometerInfo));
122541             }, 1);
122542             return null;
122543         }
122544
122545         return wac2_utils.validateTypeMismatch(onSuccess, onError, "getCurrentAcceleration", _getCurrentAcceleration); 
122546     },
122547
122548     watchAcceleration: function (accelerometerSuccess, accelerometerError, options) {
122549         function _watchAcceleration() {
122550             var watchId = (new Date()).getTime() | 0,
122551                 watchObj = {},
122552                 opt = Object(options),
122553                 minNotificationInterval = opt.minNotificationInterval | 0,
122554                 accelerometerInterval = _defaultInterval;
122555
122556             if (minNotificationInterval > 0) {
122557                 accelerometerInterval = minNotificationInterval;
122558             }
122559
122560             watchObj = {
122561                 onSuccess: accelerometerSuccess,
122562                 onError: accelerometerError,
122563                 interval: accelerometerInterval
122564             };
122565
122566             _watches[watchId] = watchObj;
122567
122568             _watches[watchId].intervalId = setInterval(function () {
122569                 _self.getCurrentAcceleration(_watches[watchId].onSuccess, _watches[watchId].onError);
122570             }, _watches[watchId].interval);
122571
122572             return watchId;
122573         }
122574
122575         return wac2_utils.validateTypeMismatch(accelerometerSuccess, accelerometerError, "watchAcceleration", _watchAcceleration); 
122576     },
122577
122578     clearWatch: function (watchId) {
122579
122580         var id = watchId | 0;
122581
122582         if (_watches[id]) {
122583             clearInterval(_watches[id].intervalId);
122584             delete(_watches[id]);
122585             return null;
122586         }
122587
122588         return undefined;
122589     }
122590 };
122591
122592 event.on("AccelerometerInfoChangedEvent", function (accelerometerInfo) {
122593     _accelerometerInfo.xAxis = accelerometerInfo.accelerationIncludingGravity.x;
122594     _accelerometerInfo.yAxis = accelerometerInfo.accelerationIncludingGravity.y;
122595     _accelerometerInfo.zAxis = accelerometerInfo.accelerationIncludingGravity.z;
122596 });
122597
122598
122599 });
122600 define('ripple/platform/wac/2.0/calendar', function (require, exports, module) {
122601 /*
122602  *  Copyright 2011 Intel Corporation.
122603  *
122604  * Licensed under the Apache License, Version 2.0 (the "License");
122605  * you may not use this file except in compliance with the License.
122606  * You may obtain a copy of the License at
122607  *
122608  * http://www.apache.org/licenses/LICENSE-2.0
122609  *
122610  * Unless required by applicable law or agreed to in writing, software
122611  * distributed under the License is distributed on an "AS IS" BASIS,
122612  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122613  * See the License for the specific language governing permissions and
122614  * limitations under the License.
122615  */
122616
122617 var db = require('ripple/db'),
122618     utils = require('ripple/utils'),
122619     exception = require('ripple/exception'),
122620     constants = require('ripple/constants'),
122621     errorcode = require('ripple/platform/wac/2.0/errorcode'),
122622     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
122623     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
122624     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
122625     _console = require('ripple/console'),
122626     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
122627     _SIM_CALENDAR = 0, _DEVICE_CALENDAR = 1,
122628     _NO_RECURRENCE = 0, _DAILY_RECURRENCE = 1, _WEEKLY_RECURRENCE = 2,
122629     _MONTHLY_RECURRENCE = 3, _YEARLY_RECURRENCE = 4,
122630     _TENTATIVE_STATUS = 0, _CONFIRMED_STATUS = 1, _CANCELLED_STATUS = 2,
122631     _NO_ALARM = 0, _SILENT_ALARM = 1, _SOUND_ALARM = 2,
122632     _calendars = [], _DB_CALENDARS_KEY = "wac2-db-calendars",
122633     _FAKEWAITTIME = 5, _FAKE_LONG_WAITTIME = 10,
122634     _save_calendars, _eventPropCheck, _eventFilterCheck,
122635     _addEventAllowed = true, _deleteEventAllowed = true,
122636     _updateEventAllowed = true, _findEventsAllowed = true,
122637     CalendarEventProperties, Calendar, CalendarEvent;
122638
122639 _save_calendars = function (_name, _type, _events) {
122640     var i;
122641     for (i = 0; i < _calendars.length; i++) {
122642         if (_calendars[i].name === _name && _calendars[i].type === _type) {
122643             _calendars[i].events = _events;
122644             break;
122645         }
122646     }
122647     db.saveObject(_DB_CALENDARS_KEY, _calendars);
122648 };
122649
122650 _eventPropCheck = function (prop, dst) {
122651     var i;
122652     if (prop.description !== null && prop.description !== undefined) {
122653         dst.description = String(prop.description);
122654     }
122655     if (prop.summary !== null && prop.summary !== undefined) {
122656         dst.summary = String(prop.summary);
122657     } 
122658     if (prop.startTime !== null && prop.startTime !== undefined) {
122659         if (!wac2_utils.isValidDate(prop.startTime)) {
122660             return false;
122661         }
122662         dst.startTime = new Date(prop.startTime);
122663     }
122664     dst.duration = prop.duration | 0;
122665     if (prop.location !== null && prop.location !== undefined) {
122666         dst.location = String(prop.location);
122667     }
122668     if (prop.categories !== null && prop.categories !== undefined) {
122669         if (!wac2_utils.isValidArray(prop.categories))  {
122670             return false;
122671         }
122672         dst.categories = [];
122673         for (i = 0; i < prop.categories.length; i++) {
122674             dst.categories.push(String(prop.categories[i]));
122675         }
122676     }
122677     if (prop.recurrence !== null && prop.recurrence !== undefined) {
122678         if (prop.recurrence === _NO_RECURRENCE ||
122679             prop.recurrence === _DAILY_RECURRENCE ||
122680             prop.recurrence === _WEEKLY_RECURRENCE ||
122681             prop.recurrence === _MONTHLY_RECURRENCE ||
122682             prop.recurrence === _YEARLY_RECURRENCE) {
122683             dst.recurrence = prop.recurrence | 0;
122684         } else {
122685             return false;
122686         }
122687     }
122688     if (dst.recurrence === _NO_RECURRENCE) {
122689         dst.expires = null;
122690         dst.interval = null;
122691     } else {
122692         // expires and interval matters when recurrence is not NO_RECURRENCE
122693         if (prop.expires !== null && prop.expires !== undefined) {
122694             if (!wac2_utils.isValidDate(prop.expires)) {
122695                 return false;
122696             }
122697             dst.expires = new Date(prop.expires);
122698         }
122699         // expires === undefined -> to recur indefinitely
122700         // expires === null -> keep dst.expires unchanged, even it's null
122701         if (prop.expires === undefined) {
122702             dst.expires = null;
122703         }
122704         if (prop.interval !== null && prop.interval !== undefined) {
122705             dst.interval = prop.interval | 0;
122706         }
122707     }
122708
122709     if (prop.status !== null && prop.status !== undefined) {
122710         if (prop.status === _TENTATIVE_STATUS ||
122711             prop.status === _CONFIRMED_STATUS ||
122712             prop.status === _CANCELLED_STATUS) {
122713             dst.status = prop.status | 0;
122714         } else {
122715             return false;
122716         }
122717     }
122718
122719     if (prop.alarmType !== null && prop.alarmType !== undefined) {
122720         if (prop.alarmType === _NO_ALARM ||
122721             prop.alarmType === _SILENT_ALARM ||
122722             prop.alarmType === _SOUND_ALARM) {
122723             dst.alarmType = prop.alarmType;
122724         } else {
122725             return false;
122726         }
122727     } 
122728     if (dst.alarmType !== _NO_ALARM && prop.alarmTrigger !== undefined && prop.alarmTrigger !== undefined) {
122729         dst.alarmTrigger = prop.alarmTrigger | 0;
122730     }
122731 };
122732
122733 _eventFilterCheck = function (filter) {
122734     if (filter.id !== undefined && filter.id !== null) {
122735         filter.id = String(filter.id);
122736     } else {
122737         filter.id = undefined;
122738     }
122739     if (filter.summary !== undefined && filter.summary !== null) {
122740         filter.summary = String(filter.summary);
122741     } else {
122742         filter.summary = undefined;
122743     }
122744     if (filter.description !== undefined && filter.description !== null) {
122745         filter.description = String(filter.description);
122746     } else {
122747         filter.description = undefined;
122748     }
122749     if (filter.location !== undefined && filter.location !== null) {
122750         filter.location = String(filter.location);
122751     } else {
122752         filter.location = undefined;
122753     }
122754     if (filter.catetory !== undefined && filter.catetory !== null) {
122755         filter.catetory = String(filter.catetory);
122756     } else {
122757         filter.catetory = undefined;
122758     }
122759     if (filter.status !== undefined && filter.status !== null) {
122760         var i;
122761         if (!wac2_utils.isValidArray(filter.status))  {
122762             return false;
122763         }
122764         for (i = 0; i < filter.status.length; i++) {
122765             filter.status[i] = filter.status[i] | 0;
122766             if (filter.status[i] > _CANCELLED_STATUS || filter.status[i] < _TENTATIVE_STATUS)
122767                 return false;
122768         }
122769     } else {
122770         filter.status = undefined;
122771     }
122772     if (filter.initialStartDate !== undefined && filter.initialStartDate !== null) {
122773         if (!wac2_utils.isValidDate(filter.initialStartDate)) {
122774             return false;
122775         }
122776         filter.initialStartDate = new Date(filter.initialStartDate);
122777     } else {
122778         filter.initialStartDate = undefined;
122779     }
122780     if (filter.endStartDate !== undefined && filter.endStartDate !== null) {
122781         if (!wac2_utils.isValidDate(filter.endStartDate)) {
122782             return false;
122783         }
122784         filter.endStartDate = new Date(filter.endStartDate);
122785     } else {
122786         filter.endStartDate = undefined;
122787     }
122788     return true;
122789 };
122790
122791 CalendarEventProperties = function (prop) {
122792     var _self;
122793     _self = {
122794         description : "",
122795         summary : "",
122796         startTime : new Date(),
122797         duration : 0,
122798         location : "",
122799         categories : undefined,
122800         recurrence : _NO_RECURRENCE,
122801         expires : null,  // ignored if recurrence == NO_RECURRENCE
122802         interval : null, // ignored if recurrence == NO_RECURRENCE
122803         status : _CONFIRMED_STATUS,
122804         alarmTrigger : 0,
122805         alarmType : _NO_ALARM
122806     };
122807     if (prop) {
122808         if (_eventPropCheck(prop, _self) === false) {
122809             return undefined;
122810         }
122811     }
122812     return _self;
122813 };
122814
122815 CalendarEvent = function (prop, genNewID) {
122816     var id, _self = new CalendarEventProperties(prop);
122817
122818     /* if error occurs during checking, _self is an empty object.
122819        so i randomly pick description to check if property check fails */
122820     if (_self.description === undefined) {
122821         return undefined;
122822     }
122823
122824     if (genNewID === true) {
122825         id = Math.uuid(undefined, 16);
122826     } else {
122827         id = prop.id;
122828     }
122829     _self.__defineGetter__("id", function () {
122830         return id;
122831     });
122832     return _self;
122833 };
122834
122835 Calendar = function (type, name, events) {
122836     var _type = type,
122837         _name = name,
122838         _events = events, _self;
122839
122840     _self = {
122841         createEvent: function (evtProp) {
122842             var rst = {};
122843             rst = new CalendarEventProperties(evtProp);
122844             /* if error occurs during checking, rst is an empty object.
122845                so i randomly pick description to check if property check fails */
122846             if (rst.description === undefined) {
122847                 exception.raise(exception.types.Argument, "EventProperties: input parameter contains invalid values", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
122848                 return undefined;
122849             } else {
122850                 return rst;
122851             }
122852         },
122853
122854         addEvent: function (onSuccess, onError, calEvent) {
122855             var pendingOperation, pendingObj = {},
122856                 newEvent = {}, _doAddEvent, _calEvent = Object(calEvent);
122857
122858             _doAddEvent = function () {
122859                 if (!_addEventAllowed) {
122860                     if (onError) {
122861                         setTimeout(function () {
122862                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
122863                         }, 1);
122864                     }
122865                     return undefined;
122866                 }
122867                 newEvent = new CalendarEvent(_calEvent, true);
122868                 /* if newEvent.id === undefined,
122869                    means somthing wrong in calEvent  */
122870                 if (newEvent.id === undefined) {
122871                     if (onError) {
122872                         setTimeout(function () {
122873                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
122874                         }, 1);
122875                     }
122876                     return undefined;
122877                 }
122878
122879                 pendingObj = new PendingObject();
122880                 pendingObj.pendingID = setTimeout(function () {
122881                     pendingObj.setCancelFlag(false);
122882                     _events[newEvent.id] = newEvent;
122883                     _save_calendars(_name, _type, _events);
122884                     onSuccess(new CalendarEvent(newEvent), false);
122885                 }, _FAKEWAITTIME);
122886                 pendingOperation = new PendingOperation(pendingObj);
122887                 return pendingOperation;
122888             };
122889
122890             return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:addEvent", _doAddEvent);
122891         },
122892
122893         updateEvent: function (onSuccess, onError, calEvent) {
122894             var pendingOperation, pendingObj = {},
122895                 chkEvent, _doUpdateEvent, _calEvent = Object(calEvent);
122896
122897             _doUpdateEvent = function () {
122898                 if (!_updateEventAllowed) {
122899                     if (onError) {
122900                         setTimeout(function () {
122901                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
122902                         }, 1);
122903                     }
122904                     return undefined;
122905                 }
122906                 if (!_events[_calEvent.id]) {
122907                     if (onError) {
122908                         setTimeout(function () {
122909                             onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
122910                         }, 1);
122911                     }
122912                     return undefined;
122913                 }
122914
122915                 chkEvent = new CalendarEvent(_events[_calEvent.id], false);
122916                 /* _eventPropCheck will also update chkEvent btw */
122917                 if (_eventPropCheck(_calEvent, chkEvent) === false) {
122918                     if (onError) {
122919                         setTimeout(function () {
122920                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
122921                         }, 1);
122922                     }
122923                     return undefined;
122924                 }
122925                 pendingObj = new PendingObject();
122926                 pendingObj.pendingID = setTimeout(function () {
122927                     pendingObj.setCancelFlag(false);
122928
122929                     _events[chkEvent.id] = chkEvent;
122930                     _save_calendars(_name, _type, _events);
122931                     onSuccess();
122932                 }, _FAKEWAITTIME);
122933                 pendingOperation = new PendingOperation(pendingObj);
122934                 return pendingOperation;
122935             };
122936
122937             return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:updateEvent", _doUpdateEvent);
122938         },
122939
122940         deleteEvent: function (onSuccess, onError, id) {
122941             var pendingOperation, pendingObj = {},
122942                 _doDeleteEvent;
122943
122944             _doDeleteEvent = function () {
122945                 /* according to spec  "If any of the input parameters are not 
122946                    compatible with the expected type for that parameter, 
122947                    a DeviceAPIError with code TYPE_MISMATCH_ERR MUST be 
122948                    synchronously thrown." 
122949                    so an error is raised synchronously */
122950                 utils.validateArgumentType(id, "string", null,
122951                                        "Calendar:deleteEvent: " + " invalid id parameter",
122952                                        new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
122953
122954                 if (!_deleteEventAllowed) {
122955                     if (onError) {
122956                         setTimeout(function () {
122957                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
122958                         }, 1);
122959                     }
122960                     return undefined;
122961                 }
122962                 if (!_events[id]) {
122963                     if (onError) {
122964                         setTimeout(function () {
122965                             onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
122966                         }, 1);
122967                     }
122968                     return undefined;
122969                 }
122970
122971                 pendingObj = new PendingObject();
122972                 pendingObj.pendingID = setTimeout(function () {
122973                     pendingObj.setCancelFlag(false);
122974
122975                     delete _events[id];
122976                     _save_calendars(_name, _type, _events);
122977                     onSuccess();
122978                 }, _FAKEWAITTIME);
122979                 pendingOperation = new PendingOperation(pendingObj);
122980                 return pendingOperation;
122981             };
122982
122983             return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:deleteEvent", _doDeleteEvent);
122984         },
122985
122986         findEvents: function (onSuccess, onError, eventFilter) {
122987             var pendingOperation, pendingObj = {}, i,
122988                 tmp = [], valid_tmp = false, rst = [], _doFindEvents,
122989                 _eventFilter = Object(eventFilter);
122990
122991             _doFindEvents = function () {
122992                 if (!_eventFilterCheck(_eventFilter)) {
122993                     if (onError) {
122994                         setTimeout(function () {
122995                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
122996                         }, 1);
122997                     }
122998                     return undefined;
122999                 }
123000                 if (!_findEventsAllowed) {
123001                     if (onError) {
123002                         setTimeout(function () {
123003                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
123004                         }, 1);
123005                     }
123006                     return undefined;
123007                 }
123008
123009                 pendingObj = new PendingObject();
123010                 pendingObj.pendingID = setTimeout(function () {
123011                     pendingObj.setCancelFlag(false);
123012                     if (_eventFilter.id !== undefined) {
123013                         tmp = wac2_utils.matchOptionString(_events, "id", _eventFilter.id);
123014                         valid_tmp = true;
123015                     }
123016                     if (_eventFilter.summary !== undefined) {
123017                         if (valid_tmp) {
123018                             tmp = wac2_utils.matchOptionString(tmp, "summary", _eventFilter.summary);
123019                         } else {
123020                             tmp = wac2_utils.matchOptionString(_events, "summary", _eventFilter.summary);
123021                             valid_tmp = true;
123022                         }
123023                     }
123024                     if (_eventFilter.description !== undefined) {
123025                         if (valid_tmp) {
123026                             tmp = wac2_utils.matchOptionString(tmp, "description", _eventFilter.description);
123027                         } else {
123028                             tmp = wac2_utils.matchOptionString(_events, "description", _eventFilter.description);
123029                             valid_tmp = true;
123030                         }
123031                     }
123032                     if (_eventFilter.location !== undefined) {
123033                         if (valid_tmp) {
123034                             tmp = wac2_utils.matchOptionString(tmp, "location", _eventFilter.location);
123035                         } else {
123036                             tmp = wac2_utils.matchOptionString(_events, "location", _eventFilter.location);
123037                             valid_tmp = true;
123038                         }
123039                     }
123040                     if (_eventFilter.category !== undefined) {
123041                         if (valid_tmp) {
123042                             tmp = wac2_utils.matchOptionArrayString(tmp, "categories", _eventFilter.category);
123043                         } else {
123044                             tmp = wac2_utils.matchOptionArrayString(_events, "categories", _eventFilter.category);
123045                             valid_tmp = true;
123046                         }
123047                     }
123048                     if (_eventFilter.status !== undefined) {
123049                         if (valid_tmp) {
123050                             tmp = wac2_utils.matchOptionShortArray(tmp, "status", _eventFilter.status);
123051                         } else {
123052                             tmp = wac2_utils.matchOptionShortArray(_events, "status", _eventFilter.status);
123053                             valid_tmp = true;
123054                         }
123055                     }
123056                     if (_eventFilter.initialStartDate !== undefined ||
123057                         _eventFilter.endStartDate !== undefined) {
123058                         if (valid_tmp) {
123059                             tmp = wac2_utils.matchOptionDate(tmp, "startTime", _eventFilter.initialStartDate, _eventFilter.endStartDate);
123060                         } else {
123061                             tmp = wac2_utils.matchOptionDate(_events, "startTime", _eventFilter.initialStartDate, _eventFilter.endStartDate);
123062                             valid_tmp = true;
123063                         }
123064                     }
123065
123066                     // to make id readonly
123067                     if (valid_tmp) {
123068                         for (i = 0; i < tmp.length; i++) {
123069                             rst.push(new CalendarEvent(tmp[i], false));
123070                         }
123071                     } else {
123072                         for (var e in _events) {
123073                             rst.push(new CalendarEvent(_events[e], false));
123074                         }
123075                     }
123076                     onSuccess(rst);
123077                 }, _FAKE_LONG_WAITTIME);
123078                 pendingOperation = new PendingOperation(pendingObj);
123079                 return pendingOperation;
123080             };
123081
123082             return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:findEvent", _doFindEvents);
123083         },
123084     };
123085     _self.__defineGetter__("type", function () {
123086         return _type;
123087     });
123088     _self.__defineGetter__("name", function () {
123089         return name;
123090     });
123091     return _self;
123092 };
123093
123094 module.exports = function () {
123095     this.__defineGetter__("SIM_CALENDAR", function () {
123096         return 0;
123097     });
123098     this.__defineGetter__("DEVICE_CALENDAR", function () {
123099         return 1;
123100     });
123101     this.__defineGetter__("NO_RECURRENCE", function () { 
123102         return 0;
123103     });
123104     this.__defineGetter__("DAILY_RECURRENCE", function () {
123105         return 1;
123106     });
123107     this.__defineGetter__("WEEKLY_RECURRENCE", function () {
123108         return 2;
123109     });
123110     this.__defineGetter__("MONTHLY_RECURRENCE", function () {
123111         return 3;
123112     });
123113     this.__defineGetter__("YEARLY_RECURRENCE", function () {
123114         return 4;
123115     });
123116     this.__defineGetter__("TENTATIVE_STATUS", function () {
123117         return 0;
123118     });
123119     this.__defineGetter__("CONFIRMED_STATUS", function () {
123120         return 1;
123121     });
123122     this.__defineGetter__("CANCELLED_STATUS", function () {
123123         return 2;
123124     });
123125     this.__defineGetter__("NO_ALARM", function () {
123126         return 0;
123127     });
123128     this.__defineGetter__("SILENT_ALARM", function () {
123129         return 1;
123130     });
123131     this.__defineGetter__("SOUND_ALARM", function () {
123132         return 2;
123133     });
123134
123135     this.getCalendars = function (onSuccess, onError) {
123136         var i, pendingOperation, pendingObj = {}, cal, _doGetCalendars;
123137
123138         _doGetCalendars = function () {
123139             pendingObj = new PendingObject();
123140
123141             pendingObj.pendingID = setTimeout(function () {
123142                 pendingObj.setCancelFlag(false);
123143                 cal = db.retrieveObject(_DB_CALENDARS_KEY) || [];
123144                 _calendars = [];
123145                 if (cal.length === 0) {
123146                     _calendars.push(new Calendar(_SIM_CALENDAR, "sim cal", {}));
123147                     _calendars.push(new Calendar(_DEVICE_CALENDAR, "dev cal", {}));
123148                 } else {
123149                     for (i = 0; i < cal.length; i++) {
123150                         /* after getting Date out of DB, Date will become 
123151                            a string, so need to recast it back to Date */
123152                         /* NOTE: id becomes writable, so need to recast it
123153                            before passing to application */
123154                         for (var e in cal[i].events) {
123155                             if ((cal[i].events[e].startTime !== undefined) &&
123156                                 cal[i].events[e].startTime !== null) {
123157                                 cal[i].events[e].startTime = new Date(cal[i].events[e].startTime);
123158                             }
123159                             if ((cal[i].events[e].expires !== undefined) &&
123160                                 cal[i].events[e].expires !== null) {
123161                                 cal[i].events[e].expires = new Date(cal[i].events[e].expires);
123162                             }
123163                         }
123164                         _calendars.push(new Calendar(cal[i].type, cal[i].name, cal[i].events));
123165                     }
123166                 }
123167                 if (_calendars.length !== 0) {
123168                     onSuccess(utils.copy(_calendars));
123169                 } else {
123170                     if (onError) {
123171                         onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
123172                     }
123173                 }
123174             }, _FAKEWAITTIME);
123175             pendingOperation = new PendingOperation(pendingObj);
123176             return pendingOperation;
123177         };
123178     
123179         return wac2_utils.validateTypeMismatch(onSuccess, onError, "getCalendars", _doGetCalendars);
123180     };
123181
123182     this.handleSubFeatures = function (subFeatures) {
123183         if (wac2_utils.isEmptyObject(subFeatures) ||
123184             subFeatures["http://wacapps.net/api/pim.calendar"] ||
123185             (subFeatures["http://wacapps.net/api/pim.calendar.read"] &&
123186             subFeatures["http://wacapps.net/api/pim.calendar.write"])) {
123187             return;
123188         } 
123189         if (subFeatures["http://wacapps.net/api/pim.calendar.read"]) {
123190             _addEventAllowed = false;
123191             _deleteEventAllowed = false;
123192             _updateEventAllowed = false;
123193             return;
123194         } 
123195         if (subFeatures["http://wacapps.net/api/pim.calendar.write"]) {
123196             _findEventsAllowed = false;
123197             return;
123198         } 
123199         _console.warn("WAC-2.0-Calendar-handleSubFeatures: something wrong");
123200     };
123201 };
123202
123203 });
123204 define('ripple/platform/wac/2.0/camera', function (require, exports, module) {
123205 /*
123206  *  Copyright 2011 Intel Corporation.
123207  *
123208  * Licensed under the Apache License, Version 2.0 (the "License");
123209  * you may not use this file except in compliance with the License.
123210  * You may obtain a copy of the License at
123211  *
123212  * http://www.apache.org/licenses/LICENSE-2.0
123213  *
123214  * Unless required by applicable law or agreed to in writing, software
123215  * distributed under the License is distributed on an "AS IS" BASIS,
123216  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123217  * See the License for the specific language governing permissions and
123218  * limitations under the License.
123219  */
123220
123221 var utils = require('ripple/utils'),
123222     constants = require('ripple/constants'),
123223     _console = require('ripple/console'),
123224     errorcode = require('ripple/platform/wac/2.0/errorcode'),
123225     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
123226     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
123227     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
123228     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils');
123229
123230 module.exports = function () {
123231     var _cameraArray, Camera, _videoStatus = {},
123232         _captureImage, _startVideoCapture,
123233         _doCaptureImage, _doStartVideoCapture,
123234         _doGetPreview, _doGetCameras,
123235         _stopVideoCapture, _createPreviewNode,
123236         _FAKEWAITTIME = 5,
123237         _defaultHighRes = true,
123238         _defaultImageFilename = "_capture.jpg",
123239         _defaultVideoFilename = "_capture.avi",
123240         _captureImageAllowed = true,
123241         _startVideoCaptureAllowed = true,
123242         _stopVideoCaptureAllowed = true,
123243         _createPreviewNodeAllowed = true;
123244
123245     _doCaptureImage = function (onSuccess, onError, capFilename, capHighRes, pendingObj) {
123246         pendingObj.pendingID = setTimeout(function () {
123247             var dname = "", fname = "";
123248             //pretend to do sth.
123249             pendingObj.setCancelFlag(false);  // too late to cancel
123250             if (capFilename.indexOf("/") !== -1) {
123251                 dname = capFilename.replace(/(.*\/)[^\/]+$/i, "$1");
123252                 fname = capFilename.replace(/.*\/([^\/]*)$/i, "$1");
123253                 //replace extension with jpg
123254                 fname = fname.replace(/\.[^\/\.]+$/i, ".jpg");
123255             } else {
123256                 dname = "";
123257                 fname = capFilename.replace(/\.[^\/\.]+$/i, ".jpg");
123258             }
123259             if (fname === "") {
123260                 fname = _defaultImageFilename;
123261             }
123262             if (fname.search(/\.jpg$/) === -1) {
123263                 fname = fname + ".jpg";
123264             }
123265             if (capHighRes) {
123266                 onSuccess(dname + "high-" + fname);
123267             } else {
123268                 onSuccess(dname + "low-" + fname);
123269             }
123270         }, _FAKEWAITTIME);
123271     };
123272
123273     _captureImage = function (onSuccess, onError, options) {
123274         var pendingOperation = {}, pendingObj,
123275             filename = this.id + _defaultImageFilename,
123276             highRes = _defaultHighRes, opt;
123277
123278         if (onSuccess) {
123279             utils.validateArgumentType(onSuccess, "function", null, "captureImage: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
123280         }
123281         if (onError) {
123282             utils.validateArgumentType(onError, "function", null, "captureImage: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
123283         }
123284         if (options) {
123285             opt = new Object(options);
123286             /* NOTE: if desktinationFilename or highRes is not provided by
123287                user, i.e. undefined or null, a default value is used.
123288              */
123289             if (opt.destinationFilename !== null && opt.destinationFilename !== undefined) {
123290             // TODO: validate filename via Filesystem.resolve()
123291                 filename = String(opt.destinationFilename);
123292             }
123293             if (opt.highRes !== null && opt.highRes !== undefined) {
123294                 highRes = Boolean(opt.highRes);
123295             }
123296         }
123297         if (!_captureImageAllowed) {
123298             if (onError) {
123299                 setTimeout(function () {
123300                     onError(new DeviceApiError(errorcode.SECURITY_ERR));
123301                 }, 1);
123302             }
123303             return undefined;
123304         }
123305
123306         if (onSuccess) {
123307             pendingObj = new PendingObject();
123308             _doCaptureImage(onSuccess, onError, filename, highRes, pendingObj);
123309             pendingOperation = new PendingOperation(pendingObj);
123310             return pendingOperation;
123311         } else {
123312             if (onError) {
123313                 setTimeout(function () {
123314                     onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
123315                 }, 1);
123316             }
123317         }
123318         return undefined;
123319     };
123320
123321     _stopVideoCapture = function () {
123322         var dname = "", fname = "", capFilename = _videoStatus[this.id].capFilename;
123323         if (_videoStatus[this.id]) {
123324             if (capFilename.indexOf("/") !== -1) {
123325                 dname = capFilename.replace(/(.*\/)[^\/]+$/i, "$1");
123326                 fname = capFilename.replace(/.*\/([^\/]*)$/i, "$1");
123327                 //replace extension with avi
123328                 fname = fname.replace(/\.[^\/\.]+$/i, ".avi");
123329             } else {
123330                 dname = "";
123331                 fname = capFilename.replace(/\.[^\/\.]+$/i, ".avi");
123332             }
123333             if (fname === "") {
123334                 fname = _defaultVideoFilename;
123335             }
123336             if (fname.search(/\.avi$/) === -1) {
123337                 fname = fname + ".avi";
123338             }
123339             if (_videoStatus[this.id].capHighRes) {
123340                 _videoStatus[this.id].capSuccess(dname + "high-" + fname);
123341             } else {
123342                 _videoStatus[this.id].capSuccess(dname + "low-" + fname);
123343             }
123344             delete _videoStatus[this.id];
123345         }
123346     };
123347
123348     _doStartVideoCapture = function (camID, onSuccess, onError, filename, highRes, pendingObj) {
123349         var videoStatus = {};
123350         _videoStatus[camID] = videoStatus;
123351         pendingObj.userCancel = function () {
123352             delete _videoStatus[camID];
123353         };
123354         pendingObj.getCancelFlag = function () {
123355             return !!_videoStatus[camID];
123356         };
123357         pendingObj.pendingID = setTimeout(function () {
123358             // waiting to be cancelled
123359             videoStatus = {
123360                 capSuccess: onSuccess,
123361                 capError: onError,
123362                 capFilename: filename,
123363                 capHighRes: highRes
123364             };
123365             _videoStatus[camID] = videoStatus;
123366         }, _FAKEWAITTIME);
123367     };
123368
123369     _startVideoCapture = function (onSuccess, onError, options) {
123370         var pendingOperation = {}, pendingObj,
123371             filename = this.id + _defaultVideoFilename,
123372             highRes = _defaultHighRes, opt;
123373
123374         if (onSuccess) {
123375             utils.validateArgumentType(onSuccess, "function", null, "startVideoCapture: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
123376         }
123377         if (onError) {
123378             utils.validateArgumentType(onError, "function", null, "startVideoCapture: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
123379         }
123380         if (options) {
123381             opt = new Object(options);
123382             /* NOTE: if desktinationFilename or highRes is not provided by
123383                user, i.e. undefined or null, a default value is used.
123384              */
123385             if (opt.destinationFilename !== null && opt.destinationFilename !== undefined) {
123386             // TODO: validate filename via Filesystem.resolve()
123387                 filename = String(opt.destinationFilename);
123388             }
123389             if (opt.highRes !== null && opt.highRes !== undefined) {
123390                 highRes = Boolean(opt.highRes);
123391             }
123392         }
123393         if (!_captureImageAllowed) {
123394             if (onError) {
123395                 setTimeout(function () {
123396                     onError(new DeviceApiError(errorcode.SECURITY_ERR));
123397                 }, 1);
123398             }
123399             return undefined;
123400         }
123401         if (_videoStatus[this.id]) { 
123402             // capture already started
123403             _console.warn("WAC-2.0-startVideoCapture: capture already started");
123404             if (onError) {
123405                 setTimeout(function () {
123406                     onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
123407                 }, 1);
123408             }
123409             return undefined;
123410         }
123411
123412         if (onSuccess) {
123413             pendingObj = new PendingObject();
123414             _doStartVideoCapture(this.id, onSuccess, onError, filename, highRes, pendingObj);
123415             
123416             pendingOperation = new PendingOperation(pendingObj);
123417             return pendingOperation;
123418         } else {
123419             if (onError) {
123420                 setTimeout(function () {
123421                     onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
123422                 }, 1);
123423             }
123424         }
123425         return undefined;
123426     };
123427
123428     _doGetPreview = function (camID, onSuccess, onError, pendingObj) {
123429         var container, demoImg, loc, imageSrc;
123430         container = document.createElement("div");
123431         container.setAttribute("id", camID + "-wac-2-0-camera-preview-container");
123432         demoImg = document.createElement("img");
123433         demoImg.setAttribute("id", camID + "-wac-2-0-camera-demo-image");
123434         loc = document.location;
123435         imageSrc = loc.protocol + "//" + loc.hostname + loc.pathname.replace(/index\.html$/, "") + constants.CAMERA.WINDOW_ANIMATION;
123436         demoImg.setAttribute("src", imageSrc);
123437         demoImg.setAttribute("width", "100%");
123438         container.appendChild(demoImg);
123439         
123440         pendingObj.pendingID = setTimeout(function () {
123441             pendingObj.setCancelFlag(false);  // too late to cancel
123442             onSuccess(container);
123443         }, _FAKEWAITTIME);
123444     };
123445
123446     _createPreviewNode = function (onSuccess, onError) {
123447         var pendingOperation, pendingObj = {};
123448         if (onSuccess) {
123449             utils.validateArgumentType(onSuccess, "function", null, "createPreviewNode: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
123450         }
123451         if (onError) {
123452             utils.validateArgumentType(onError, "function", null, "createPreviewNode: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
123453         }
123454         if (!_createPreviewNodeAllowed) {
123455             if (onError) {
123456                 setTimeout(function () {
123457                     onError(new DeviceApiError(errorcode.SECURITY_ERR));
123458                 }, 1);
123459             }
123460             return undefined;
123461         }
123462         if (onSuccess) {
123463             pendingObj = new PendingObject();
123464             _doGetPreview(this.id, onSuccess, onError, pendingObj);
123465             pendingOperation = new PendingOperation(pendingObj);
123466             return pendingOperation;
123467         } else {
123468             if (onError) {
123469                 setTimeout(function () {
123470                     onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
123471                 }, 1);
123472             }
123473         }
123474         return undefined;
123475     };
123476
123477     Camera = function (cameraID) {
123478         return {
123479             id: cameraID,
123480             captureImage: _captureImage,
123481             startVideoCapture: _startVideoCapture,
123482             stopVideoCapture: _stopVideoCapture,
123483             createPreviewNode: _createPreviewNode
123484         };
123485     };
123486
123487     _cameraArray = [new Camera("rear"), new Camera("front")];
123488
123489     _doGetCameras = function (onSuccess, onError, pendingObj) {
123490         pendingObj.pendingID = setTimeout(function () {
123491             pendingObj.setCancelFlag(false);  // too late to cancel
123492             if (_cameraArray.length !== 0) {
123493                 onSuccess(utils.copy(_cameraArray));
123494             } else {
123495                 // no camera
123496                 if (onError) {
123497                     setTimeout(function () {
123498                         onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
123499                     }, 1);
123500                 }
123501             }
123502         }, _FAKEWAITTIME);
123503     };
123504
123505     this.getCameras = function (onSuccess, onError) {
123506         var pendingOperation, pendingObj = {};
123507         if (onSuccess) {
123508             utils.validateArgumentType(onSuccess, "function", null, "getCameras: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
123509         }
123510         if (onError) {
123511             utils.validateArgumentType(onError, "function", null, "getCameras: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
123512         }
123513         if (onSuccess) {
123514             pendingObj = new PendingObject();
123515             _doGetCameras(onSuccess, onError, pendingObj);
123516             pendingOperation = new PendingOperation(pendingObj);
123517             return pendingOperation;
123518         } else {
123519             if (onError) {
123520                 setTimeout(function () {
123521                     onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
123522                 }, 1);
123523             }
123524         }
123525         return undefined;
123526     };
123527
123528     this.handleSubFeatures = function (subFeatures) {
123529         if (wac2_utils.isEmptyObject(subFeatures) ||
123530             subFeatures["http://wacapps.net/api/camera"] ||
123531             (subFeatures["http://wacapps.net/api/camera.capture"] &&
123532             subFeatures["http://wacapps.net/api/camera.show"])) {
123533             return;
123534         }
123535         if (subFeatures["http://wacapps.net/api/camera.show"] &&
123536            !subFeatures["http://wacapps.net/api/camera.capture"]) {
123537             _captureImageAllowed = false;
123538             _startVideoCaptureAllowed = false;
123539             _stopVideoCaptureAllowed = false;
123540             return;
123541         }
123542         if (subFeatures["http://wacapps.net/api/camera.capture"] &&
123543            !subFeatures["http://wacapps.net/api/camera.show"]) {
123544             _createPreviewNodeAllowed = false;
123545             return;
123546         }
123547         _console.warn("WAC-2.0-Camera-handleSubFeatures: something wrong");
123548     };
123549 };
123550
123551 });
123552 define('ripple/platform/wac/2.0/contact', function (require, exports, module) {
123553 /*
123554  *  Copyright 2011 Intel Corporation.
123555  *
123556  * Licensed under the Apache License, Version 2.0 (the "License");
123557  * you may not use this file except in compliance with the License.
123558  * You may obtain a copy of the License at
123559  *
123560  * http://www.apache.org/licenses/LICENSE-2.0
123561  *
123562  * Unless required by applicable law or agreed to in writing, software
123563  * distributed under the License is distributed on an "AS IS" BASIS,
123564  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123565  * See the License for the specific language governing permissions and
123566  * limitations under the License.
123567  */
123568
123569 var utils = require('ripple/utils'),
123570     db = require('ripple/db'),
123571     constants = require('ripple/constants'),
123572     exception = require('ripple/exception'),
123573     errorcode = require('ripple/platform/wac/2.0/errorcode'),
123574     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
123575     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
123576     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
123577     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
123578     TypeCoerce = require('ripple/platform/wac/2.0/typecoerce'),
123579     Filter = require('ripple/platform/wac/2.0/contactfilter'),
123580     AddressBook,
123581     ContactProperties,
123582     Contact,
123583     Address,
123584     ContactAddress,
123585     PhoneNumber,
123586     EmailAddress,
123587     ContactFilter,
123588     _KEY = "wac2-pim-contact",
123589     _PENDING_TIME = 600,
123590     _addressBooks = [],
123591     _contacts = {},
123592     _security = {
123593         "http://wacapps.net/api/pim.contact": [],
123594         "http://wacapps.net/api/pim.contact.read": ["findContacts"],
123595         "http://wacapps.net/api/pim.contact.write": ["addContact", "updateContact", "deleteContact"],
123596         all: true
123597     },
123598     _self;
123599
123600 function _errorOccurred(onError, code) {
123601     if (!onError)
123602         return;
123603
123604     setTimeout(function () {
123605         onError(new DeviceApiError(code));
123606     }, 1);
123607 }
123608
123609 function _pendingOperate(operate, scope) {
123610     var i, argumentVector = [];
123611
123612     for (i = 0; i < arguments.length - 2; i++)
123613         argumentVector[i] = arguments[i + 2];
123614
123615     return function () {
123616         var pendingObj, pendingOperation;
123617
123618         pendingObj = new PendingObject();
123619         pendingObj.pendingID = window.setTimeout(function () {
123620             pendingObj.setCancelFlag(false);
123621             operate.apply(scope, argumentVector);
123622         }, _PENDING_TIME);
123623
123624         pendingOperation = new PendingOperation(pendingObj);
123625
123626         return pendingOperation;
123627     };
123628 }
123629
123630 function _defaultContacts() {
123631     var id1 = Math.uuid(null, 16),
123632         id2 = Math.uuid(null, 16),
123633         id3 = Math.uuid(null, 16),
123634         id4 = Math.uuid(null, 16),
123635         contacts = {};
123636
123637     contacts.PHONE_ADDRESS_BOOK = {
123638         type: _self().PHONE_ADDRESS_BOOK,
123639         items: [{
123640             id: id1,
123641             firstName: "Leonardo",
123642             lastName: "Gates",
123643             nicknames: ["Leo"],
123644             phoneticName: "",
123645             addresses: [{streetAddress: "Gran Via, 32", postalCode: "50013", city: "Zaragoza", country: "ES"}],
123646             photoURI: "",
123647             phoneNumbers: [],
123648             emails: ["leo@underground.com"]
123649         }, {
123650             id: id2,
123651             firstName: "Jordan",
123652             lastName: "",
123653             nicknames: [""],
123654             phoneticName: "",
123655             addresses: [],
123656             photoURI: "",
123657             phoneNumbers: [],
123658             emails: ["jordan@underground.com"]
123659         }]
123660     };
123661
123662     contacts.SIM_ADDRESS_BOOK = {
123663         type: _self().SIM_ADDRESS_BOOK,
123664         items: [{
123665             id: id3,
123666             firstName: "Raphael",
123667             lastName: "",
123668             nicknames: [""],
123669             phoneticName: "",
123670             addresses: [],
123671             photoURI: "",
123672             phoneNumbers: [],
123673             emails: ["raph@underground.com"]
123674         }]
123675     };
123676
123677     contacts.DEVICE_ADDRESS_BOOK = {
123678         type: _self().DEVICE_ADDRESS_BOOK,
123679         items: [{
123680             id: id4,
123681             firstName: "Michelangelo",
123682             lastName: "",
123683             nicknames: [""],
123684             phoneticName: "",
123685             addresses: [],
123686             photoURI: "",
123687             phoneNumbers: [],
123688             emails: ["mike@underground.com"]
123689         }]
123690     };
123691
123692     return contacts;
123693 }
123694
123695 function _get() {
123696     _contacts = db.retrieveObject(_KEY) || _defaultContacts();
123697 }
123698
123699 function _save() {
123700     db.saveObject(_KEY, _contacts);
123701 }
123702
123703 function _initAddressBooks() {
123704     _get();
123705     utils.forEach(_contacts, function (contactObj, name) {
123706         _addressBooks.push(new AddressBook(contactObj.type, name));
123707     });
123708 }
123709
123710 _self = function () {
123711     var contact = {
123712         getAddressBooks: function (successCallback, errorCallback) {
123713             function _getAddressBooks() {
123714                 if (_addressBooks.length === 0) {
123715                     _initAddressBooks();
123716                 }
123717                 successCallback(_addressBooks);
123718             }
123719             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "getAddressBooks", _getAddressBooks);
123720         },
123721
123722         handleSubFeatures: function (subFeatures) {
123723             for (var subFeature in subFeatures) {
123724                 if (_security[subFeature].length === 0) {
123725                     _security.all = true;
123726                     return;
123727                 }
123728                 _security.all = false;
123729                 utils.forEach(_security[subFeature], function (method) {
123730                     _security[method] = true;
123731                 });
123732             }
123733         }
123734     };
123735
123736     contact.__defineGetter__("SIM_ADDRESS_BOOK", function () {
123737         return 0x0000;
123738     });
123739
123740     contact.__defineGetter__("DEVICE_ADDRESS_BOOK", function () {
123741         return 0x000F;
123742     });
123743
123744     contact.__defineGetter__("PHONE_ADDRESS_BOOK", function () {
123745         return 0x00FF;
123746     });
123747
123748     return contact;
123749 };
123750
123751 AddressBook = function (type, name) {
123752     var addressBook,
123753         contactItems = _contacts[name].items;
123754
123755     addressBook = {
123756         createContact: function (contactProperties) {
123757             var cp, contact = new Contact();
123758
123759             if ((contactProperties !== undefined) &&
123760                 (contactProperties !== null)) {
123761                 cp = TypeCoerce(ContactProperties).cast(contactProperties);
123762                 !cp.firstName    || (contact.firstName    = utils.copy(cp.firstName));
123763                 !cp.lastName     || (contact.lastName     = utils.copy(cp.lastName));
123764                 !cp.nicknames    || (contact.nicknames    = utils.copy(cp.nicknames));
123765                 !cp.phoneticName || (contact.phoneticName = utils.copy(cp.phoneticName));
123766                 !cp.addresses    || (contact.addresses    = utils.copy(cp.addresses));
123767                 !cp.photoURI     || (contact.photoURI     = utils.copy(cp.photoURI));
123768                 !cp.phoneNumbers || (contact.phoneNumbers = utils.copy(cp.phoneNumbers));
123769                 !cp.emails       || (contact.emails       = utils.copy(cp.emails));
123770             }
123771
123772             return contact;
123773         },
123774
123775         addContact: function (successCallback, errorCallback, contact) {
123776             function _addContact() {
123777                 var c;
123778
123779                 if (!contact)
123780                     exception.raise(exception.types.Argument, "addContact invalid message parameter", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
123781
123782                 if (!_security.all && !_security.addContact)
123783                     return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
123784
123785                 c = TypeCoerce(new Contact()).cast(contact);
123786                 contactItems.push(c);
123787                 _save();
123788                 successCallback(c);
123789             }
123790             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "addContact", _pendingOperate(_addContact));
123791         },
123792
123793         updateContact: function (successCallback, errorCallback, contact) {
123794             function _updateContact() {
123795                 var c, isFound = false;
123796
123797                 if (!contact)
123798                     exception.raise(exception.types.Argument, "updateContact invalid message parameter", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
123799
123800                 if (!_security.all && !_security.updateContact)
123801                     return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
123802
123803                 c = TypeCoerce(new Contact()).cast(contact);
123804                 utils.forEach(contactItems, function (contactItem) {
123805                     if (contactItem.id === c.id) {
123806                         !c.firstName    || (contactItem.firstName    = utils.copy(c.firstName));
123807                         !c.lastName     || (contactItem.lastName     = utils.copy(c.lastName));
123808                         !c.nicknames    || (contactItem.nicknames    = utils.copy(c.nicknames));
123809                         !c.phoneticName || (contactItem.phoneticName = utils.copy(c.phoneticName));
123810                         !c.addresses    || (contactItem.addresses    = utils.copy(c.addresses));
123811                         !c.photoURI     || (contactItem.photoURI     = utils.copy(c.photoURI));
123812                         !c.phoneNumbers || (contactItem.phoneNumbers = utils.copy(c.phoneNumbers));
123813                         !c.emails       || (contactItem.emails       = utils.copy(c.emails));
123814
123815                         _save();
123816                         isFound = true;
123817                         successCallback();
123818                     }
123819                 });
123820
123821                 if (!isFound)
123822                     _errorOccurred(errorCallback, errorcode.NOT_FOUND_ERR);
123823             }
123824             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "updateContact", _pendingOperate(_updateContact));
123825         },
123826
123827         deleteContact: function (successCallback, errorCallback, id) {
123828             function _deleteContact() {
123829                 var isFound = false;
123830
123831                 if (!_security.all && !_security.deleteContact)
123832                     return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
123833
123834                 utils.forEach(contactItems, function (contactItem, index) {
123835                     if (contactItem.id === id) {
123836                         contactItems.splice(index, 1);
123837                         _save();
123838                         isFound = true;
123839                         successCallback();
123840                     }
123841                 });
123842
123843                 if (!isFound)
123844                     _errorOccurred(errorCallback, errorcode.NOT_FOUND_ERR);
123845             }
123846             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "deleteContact", _pendingOperate(_deleteContact));
123847         },
123848
123849         findContacts: function (successCallback, errorCallback, filter) {
123850             function _findContacts() {
123851                 var contact, result = [];
123852
123853                 if (!_security.all && !_security.findContacts)
123854                     return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
123855
123856                 utils.forEach(contactItems, function (contactItem) {
123857                     if ((filter              === undefined || filter === null) ||
123858                         (filter.id           === undefined || Filter(filter.id).match(contactItem.id)) &&
123859                         (filter.firstName    === undefined || Filter(filter.firstName).match(contactItem.firstName)) &&
123860                         (filter.lastName     === undefined || Filter(filter.lastName).match(contactItem.lastName)) &&
123861                         (filter.phoneticName === undefined || Filter(filter.phoneticName).match(contactItem.phoneticName)) &&
123862                         (filter.nickname     === undefined || Filter(filter.nickname).match(contactItem.nicknames)) &&
123863                         (filter.phoneNumber  === undefined || Filter(filter.phoneNumber).match(contactItem.phoneNumbers)) &&
123864                         (filter.email        === undefined || Filter(filter.email).match(contactItem.emails)) &&
123865                         (filter.address      === undefined || Filter(filter.address).match(contactItem.addresses))) {
123866                         contact = new Contact(contactItem.id);
123867
123868                         contact.firstName    = utils.copy(contactItem.firstName);
123869                         contact.lastName     = utils.copy(contactItem.lastName);
123870                         contact.nicknames    = utils.copy(contactItem.nicknames);
123871                         contact.phoneticName = utils.copy(contactItem.phoneticName);
123872                         contact.addresses    = utils.copy(contactItem.addresses);
123873                         contact.photoURI     = utils.copy(contactItem.photoURI);
123874                         contact.phoneNumbers = utils.copy(contactItem.phoneNumbers);
123875                         contact.emails       = utils.copy(contactItem.emails);
123876
123877                         result.push(contact);
123878                     }
123879                 });
123880                 successCallback(result);
123881             }
123882             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "findContacts", _pendingOperate(_findContacts));
123883         }
123884     };
123885
123886     addressBook.__defineGetter__("type", function () {
123887         return type;
123888     });
123889
123890     addressBook.__defineGetter__("name", function () {
123891         return name;
123892     });
123893
123894     return addressBook;
123895 };
123896
123897 Address = {
123898     country: "",
123899     region: "",
123900     county: "",
123901     city: "",
123902     streetAddress: "",
123903     additionalInformation: "",
123904     postalCode: ""
123905 };
123906
123907 ContactAddress = function () {
123908     this.types = [""]; // "WORK", "PREF", "HOME"
123909 };
123910
123911 ContactAddress.prototype = Address;
123912
123913 PhoneNumber = {
123914     number: "",
123915     types: [""] // "WORK", "PREF", "HOME", "VOICE", "FAX", "MSG", "CELL",
123916                 // "PAGER", "BBS", "MODEM", "CAR", "ISDN", "VIDEO", "PCS"
123917 };
123918
123919 EmailAddress = {
123920     email: "",
123921     types: [""] // "WORK", "PREF", "HOME"
123922 };
123923
123924 ContactProperties = {
123925     firstName: "",
123926     lastName: "",
123927     nicknames: [""],
123928     phoneticName: "",
123929     addresses: [new ContactAddress()],
123930     photoURI: "",
123931     phoneNumbers: [PhoneNumber],
123932     emails: [EmailAddress]
123933 };
123934
123935 Contact = function (id) {
123936     id = id || Math.uuid(null, 16);
123937
123938     this.__defineGetter__("id", function () {
123939         return id;
123940     });
123941 };
123942
123943 Contact.prototype = ContactProperties;
123944
123945 ContactFilter = {
123946     id: "",
123947     firstName: "",
123948     lastName: "",
123949     phoneticName: "",
123950     nickname: "",
123951     phoneNumber: "",
123952     email: "",
123953     address: ""
123954 };
123955
123956 module.exports = _self;
123957
123958 });
123959 define('ripple/platform/wac/2.0/contactfilter', function (require, exports, module) {
123960 /*\r
123961  *  Copyright 2011 Intel Corporation.\r
123962  *\r
123963  * Licensed under the Apache License, Version 2.0 (the "License");\r
123964  * you may not use this file except in compliance with the License.\r
123965  * You may obtain a copy of the License at\r
123966  *\r
123967  * http://www.apache.org/licenses/LICENSE-2.0\r
123968  *\r
123969  * Unless required by applicable law or agreed to in writing, software\r
123970  * distributed under the License is distributed on an "AS IS" BASIS,\r
123971  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
123972  * See the License for the specific language governing permissions and\r
123973  * limitations under the License.\r
123974  */\r
123975 \r
123976 var utils = require('ripple/utils'),\r
123977     _self;\r
123978 \r
123979 _self = function (criteria) {\r
123980     var pattern,\r
123981         contactFilter;\r
123982 \r
123983     contactFilter = {\r
123984         match: function (target) {\r
123985             var result = false, key, value, index;\r
123986 \r
123987             switch (Object.prototype.toString.call(target)) {\r
123988             case "[object String]":\r
123989                 result = pattern.test(target);\r
123990                 break;\r
123991 \r
123992             case "[object Object]":\r
123993                 for (key in criteria) {\r
123994                     result = true;\r
123995                     value = criteria[key];\r
123996                     if ((value !== undefined) && (!_self(value).match(target[key])))\r
123997                         return false;\r
123998                 }\r
123999                 break;\r
124000 \r
124001             case "[object Array]":\r
124002                 for (index in target) {\r
124003                     if (contactFilter.match(target[index]))\r
124004                         return true;\r
124005                 }\r
124006                 break;\r
124007             }\r
124008 \r
124009             return result;\r
124010         }\r
124011     };\r
124012 \r
124013     if (typeof criteria === "string")\r
124014         pattern = new RegExp(criteria.replace(/(^|[^\\])%+/g, "$1.*").replace(/\\%/g, "%").replace(/.*/, "^$&$"), "i");\r
124015 \r
124016     return contactFilter;\r
124017 };\r
124018 \r
124019 module.exports = _self;\r
124020
124021 });
124022 define('ripple/platform/wac/2.0/dbfs', function (require, exports, module) {
124023 /*
124024  *  Copyright 2011 Research In Motion Limited.
124025  *  Copyright 2011 Intel Corporation.
124026  *
124027  * Licensed under the Apache License, Version 2.0 (the "License");
124028  * you may not use this file except in compliance with the License.
124029  * You may obtain a copy of the License at
124030  *
124031  * http://www.apache.org/licenses/LICENSE-2.0
124032  *
124033  * Unless required by applicable law or agreed to in writing, software
124034  * distributed under the License is distributed on an "AS IS" BASIS,
124035  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124036  * See the License for the specific language governing permissions and
124037  * limitations under the License.
124038  */
124039
124040 /* We know the dbfs is not an accurate simulation of WAC 2.0 filesystem.
124041  *
124042  * 1) We have tried W3C File API, as some of WAC filesystem APIs are synchronous, 
124043  * it is impossible to simulate them by using the asynchronous API in the main
124044  * UI thread and although we could use synchronous W3C API in a worker, it is
124045  * not reasonable to limit WAC filesystem API usage in a worker.
124046  *
124047  * 2) The problem is partially solved by using database to simulate the filesystem,
124048  * For the asynchronous aspect, actually all the files are read into memory (cache 
124049  * object in this file) and the cache operation is synchronous. It is not perfect.
124050  * And the database has 5MB limitation when running in Chrome.
124051  *
124052  * In the future, we might use ajax or NPAPI to get a better simulation.
124053  */
124054
124055 /* Note: The entry object is shared between this module and filesystem */
124056
124057 var db = require('ripple/db'),
124058     utils = require('ripple/utils'),
124059     _console = require('ripple/console'),
124060     _cache = {},
124061     _self;
124062
124063 function _get(path) {
124064     return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
124065         return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
124066     }, _cache);
124067 }
124068
124069 function _getInfo(path) {
124070     var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
124071         name = parent.splice(parent.length - 1, 1).join("");
124072
124073     return {
124074         name: name,
124075         parent: parent.join("/") || "/"
124076     };
124077 }
124078
124079 function _set(path, obj) {
124080     var parent = _cache,
124081         tokens = path.replace(/^\//, '').split("/"),
124082         child = tokens.splice(tokens.length - 1, 1).join("");
124083
124084     tokens.forEach(function (token) {
124085         parent = parent.children[token];
124086     });
124087
124088     parent.children = parent.children || {};
124089     parent.children[child] = obj;
124090 }
124091
124092 function _delete(path) {
124093     var parent = _cache,
124094         tokens = path.replace(/^\//, '').split("/"),
124095         child = tokens.splice(tokens.length - 1, 1).join("");
124096
124097     tokens.forEach(function (token) {
124098         parent = parent.children[token];
124099     });
124100
124101     delete parent.children[child];
124102 }
124103
124104 function _save() {
124105     db.saveObject("wac2-db-filesystem", _cache);
124106 }
124107
124108 function _walk(path, parent) { 
124109     _self.ls(path, function (entries) { 
124110         parent.children = parent.children || {}; 
124111
124112         entries.forEach(function (entry) { 
124113             parent.children[entry.name] = entry; 
124114
124115             if (entry.isDirectory) { 
124116                 _walk(entry.fullPath, entry); 
124117             } else { 
124118                 /* after getting Date out of DB, Date will become 
124119                    a string, so need to recast it back to Date */
124120                 if (entry.lastModifiedDate !== null && entry.lastModifiedDate !== undefined)
124121                     entry.lastModifiedDate = new Date(entry.lastModifiedDate);
124122
124123                 _self.read(entry.fullPath, function (data) { 
124124                     parent.children[entry.name].data = data; 
124125                 }, function (e) { 
124126                     _console.error(e); 
124127                 }); 
124128             } 
124129         }); 
124130     }, function (e) { 
124131         _console.error(e); 
124132     }); 
124133
124134  
124135 function _createPath(path) { 
124136     var parts = path.replace(/^\//, '').split("/"), 
124137         workflow = jWorkflow.order(); 
124138  
124139     parts.forEach(function (part, index) { 
124140         var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/"); 
124141  
124142         workflow.andThen(function (prev, baton) { 
124143             baton.take(); 
124144             _self.mkdir(dir, baton.pass, baton.pass); 
124145         }); 
124146     }); 
124147  
124148     workflow.start(); 
124149 }
124150
124151 _self = {
124152     // The order is consistent with _virtualRoots in filesystem.js
124153     roots: ["/opt/documents", "/opt/images", "/opt/music", "/opt/videos", "/opt/downloads", "/home/user/appdata/simulatedapp/wgt-package", "/home/user/appdata/simulatedapp/wgt-private", "/home/user/appdata/simulatedapp/wgt-private-tmp", "/SDCard", "/opt/attachments"],
124154     initialize: function () {
124155         // TODO: Initialize at bootstrap and emulatorBridge.link 
124156         _cache = db.retrieveObject("wac2-db-filesystem") || {};
124157         // create real root paths if empty
124158         _self.roots.every(function (root) {
124159             _createPath(root);
124160             return true;
124161         }); 
124162        // build the file system cache so that we could access information synchronously
124163         _walk("/", _cache);
124164     },
124165     ls: function (path, success, error) {
124166         try {
124167             var dir = _get(path),
124168                 items = [];
124169
124170             if (dir) {
124171                 utils.forEach(dir.children, function (item) {
124172                     items.push(item);
124173                 });
124174             }
124175             else {
124176                 items = {};
124177             }
124178
124179             success(items);
124180         }
124181         catch (e) {
124182             e.code = 1;
124183             error(e);
124184         }
124185     },
124186     rm: function (path, success, error, options) {
124187         _delete(path);
124188         _save();
124189         success();
124190     },
124191     rmdir: function (path, success, error, options) {
124192         _delete(path);
124193         _save();
124194         success();
124195     },
124196     mkdir: function (path, success, error) {
124197         var entry = _get(path),
124198             info = _getInfo(path);
124199
124200         if (!entry) {
124201             _set(path, {
124202                 name: info.name,
124203                 isDirectory: true,
124204                 fullPath: path
124205             });
124206             entry = _get(path);
124207             _save();
124208         }
124209         
124210         if (entry) {
124211             success(entry);
124212         }
124213         else {
124214             error({code: 1});
124215         }
124216     },
124217     mv: function (from, to, success, error) {
124218         try {
124219             var fromEntry = _get(from),
124220                 toInfo = _getInfo(to);
124221
124222             fromEntry.fullPath = to;
124223             fromEntry.name = toInfo.name;
124224
124225             _set(to, fromEntry);
124226             _delete(from);
124227             _save();
124228             success();
124229         }
124230         catch (e) {
124231             e.code = 1;
124232             error(e);
124233         }
124234     },
124235     touch: function (path, success, error) {
124236         var entry = _get(path),
124237             info  = _getInfo(path);
124238
124239         if (!entry) {
124240             _set(path, {
124241                 lastModifiedDate: new Date(),
124242                 name: info.name,
124243                 isDirectory: false,
124244                 fullPath: path,
124245                 data: ""
124246             });
124247             entry = _get(path);
124248         }
124249         _save();
124250         success(entry);
124251     },
124252     cp: function (from, to, success, error) {
124253         try {
124254             var fromEntry = _get(from),
124255                 copied = utils.copy(fromEntry);
124256
124257             copied.name  = _getInfo(to).name;
124258             copied.fullPath = to;
124259             _set(to, copied);
124260             _save();
124261             success();
124262         }
124263         catch (e) {
124264             e.code = 1;
124265             error(e);
124266         }
124267     },
124268     stat: function (path, success, error) {
124269         var entry = _get(path);
124270         
124271         if (entry) {
124272             success(entry);
124273         } else {
124274             error({code: 1});
124275         }
124276     },
124277     write: function (path, contents, success, error, options) {
124278         var entry = _get(path);
124279
124280         if (entry) {
124281             entry.lastModifiedDate = new Date();
124282             entry.data = contents;
124283             _save();
124284             success();
124285         } else {
124286             error({code: 1});
124287         }
124288
124289     },
124290     read: function (path, success, error) {
124291         var entry = _get(path);
124292
124293         if (entry) {
124294             success(utils.copy(entry.data));
124295         }
124296         else {
124297             error({code: 1});
124298         }
124299     }
124300 };
124301
124302 module.exports = _self;
124303
124304
124305 });
124306 define('ripple/platform/wac/2.0/deviceapierror', function (require, exports, module) {
124307 /*
124308  *  Copyright 2011 Intel Corporation.
124309  *
124310  * Licensed under the Apache License, Version 2.0 (the "License");
124311  * you may not use this file except in compliance with the License.
124312  * You may obtain a copy of the License at
124313  *
124314  * http://www.apache.org/licenses/LICENSE-2.0
124315  *
124316  * Unless required by applicable law or agreed to in writing, software
124317  * distributed under the License is distributed on an "AS IS" BASIS,
124318  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124319  * See the License for the specific language governing permissions and
124320  * limitations under the License.
124321  */
124322
124323 var errorcode = require('ripple/platform/wac/2.0/errorcode');
124324
124325 module.exports = function (code) {
124326     for (var c in errorcode) {
124327         var g = errorcode.__lookupGetter__(c);
124328         if (g) {
124329             this.__defineGetter__(c, g);
124330         }
124331     }
124332
124333     this.code = code;
124334     this.message = errorcode.message[code];
124335     this.type =  "";
124336
124337     this.toString = function () {
124338         var result = this.type + ': "' + this.message + '"';
124339
124340         if (this.stack) {
124341             result += "\n" + this.stack;
124342         }
124343         return result;
124344     };
124345 };
124346
124347
124348 });
124349 define('ripple/platform/wac/2.0/deviceapis', function (require, exports, module) {
124350 /*
124351  *  Copyright 2011 Intel Corporation.
124352  *
124353  * Licensed under the Apache License, Version 2.0 (the "License");
124354  * you may not use this file except in compliance with the License.
124355  * You may obtain a copy of the License at
124356  *
124357  * http://www.apache.org/licenses/LICENSE-2.0
124358  *
124359  * Unless required by applicable law or agreed to in writing, software
124360  * distributed under the License is distributed on an "AS IS" BASIS,
124361  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124362  * See the License for the specific language governing permissions and
124363  * limitations under the License.
124364  */
124365
124366 var platform = require('ripple/platform'),
124367     app = require('ripple/app'),
124368     utils = require('ripple/utils'),
124369     init_done = false,
124370     _activatedSet = {},
124371     _activatedFeatures = [],
124372     _availableSet = {},
124373     _availableFeatures = [],
124374     _features = {},
124375     initFeaturesSet,
124376     populateFeatures;
124377
124378 populateFeatures = function (objects) {
124379     utils.forEach(objects, function (obj, key) {
124380         var objFeatures = {}, rpt, i, j;
124381         if (obj.feature) {
124382             objFeatures = obj.feature.split('|');
124383             utils.forEach(objFeatures, function (feature) {
124384                 var avail = {uri: feature,
124385                              required: false,
124386                              param: null};
124387                 _availableSet[feature] = avail;
124388             });
124389             if (_features) {
124390                 rpt = objFeatures.length;
124391                 j = 0;
124392                 for (i = 0; i < rpt; i++) {
124393                     if (!_features[objFeatures[j]]) {
124394                         objFeatures.splice(j, 1);
124395                     } else {
124396                         j++;
124397                     }
124398                 }
124399             }
124400             utils.forEach(objFeatures, function (feature) {
124401                 var avail = {uri: feature,
124402                              required: true,
124403                              param: null};
124404                 _activatedSet[feature] = avail;
124405             });
124406         }
124407         if (obj.children) {
124408             populateFeatures(obj.children);
124409         }
124410     });
124411 };
124412
124413 initFeaturesSet = function () {
124414     _features = utils.copy(app.getInfo().features);
124415     populateFeatures(platform.current().objects);
124416     utils.forEach(_activatedSet, function (obj, key) {
124417             _activatedFeatures.push(obj);
124418         });
124419     utils.forEach(_availableSet, function (obj, key) {
124420             _availableFeatures.push(obj);
124421         });
124422     init_done = true;
124423 };
124424
124425 module.exports = {
124426     listAvailableFeatures: function () {
124427         if (!init_done)
124428             initFeaturesSet();
124429         return _availableFeatures;
124430     },
124431
124432     listActivatedFeatures: function () {
124433         if (!init_done)
124434             initFeaturesSet();
124435         return _activatedFeatures;
124436     }
124437 };
124438
124439
124440 });
124441 define('ripple/platform/wac/2.0/deviceinteraction', function (require, exports, module) {
124442 /*
124443  *  Copyright 2011 Intel Corporation.
124444  *
124445  * Licensed under the Apache License, Version 2.0 (the "License");
124446  * you may not use this file except in compliance with the License.
124447  * You may obtain a copy of the License at
124448  *
124449  * http://www.apache.org/licenses/LICENSE-2.0
124450  *
124451  * Unless required by applicable law or agreed to in writing, software
124452  * distributed under the License is distributed on an "AS IS" BASIS,
124453  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124454  * See the License for the specific language governing permissions and
124455  * limitations under the License.
124456  */
124457
124458 var notifications = require('ripple/notifications'),
124459     constants = require('ripple/constants'),
124460     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
124461     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
124462     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
124463     errorcode = require('ripple/platform/wac/2.0/errorcode'),
124464     utils = require('ripple/utils'),
124465     event = require('ripple/event'),
124466     deviceSettings = require('ripple/deviceSettings'),
124467     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
124468     _self,
124469     NOTIFY_DURATION_LIMIT = 5000;
124470
124471 function pendingOperation(f) {
124472     var _FAKEWAITTIME = 0,
124473         pendingObj;
124474     
124475     if (_FAKEWAITTIME === 0) {
124476         f();
124477         return undefined;
124478     }
124479     else {
124480         pendingObj = new PendingObject();
124481         pendingObj.pendingID = setTimeout(function () {
124482             pendingObj.setCancelFlag(false);
124483             f();
124484         }, _FAKEWAITTIME);
124485         return new PendingOperation(pendingObj);
124486     }
124487 }
124488
124489 function checkDuration(duration) {
124490     if (duration) {
124491         duration = duration | 0;  
124492         if (duration <= 0 || duration > NOTIFY_DURATION_LIMIT) {
124493             return NOTIFY_DURATION_LIMIT;
124494         } else {
124495             return duration;
124496         }
124497     } else {
124498         return NOTIFY_DURATION_LIMIT;
124499     }
124500 }
124501
124502 function isMute() {
124503     return deviceSettings.retrieve("Config.soundVolume") <= 0;
124504 }
124505
124506 function isInVibrateMode() {
124507     return deviceSettings.retrieve("Config.vibratingMode");
124508 }
124509
124510 function isBacklightOn() {
124511     return deviceSettings.retrieve("Config.backlight");
124512 }
124513
124514 var vibrator = (function () {
124515     var isVibrating = false,
124516         terminateAfterPattern = false,
124517         pattern = null,
124518         pulseIndex = 0,
124519         vibrateTimeout = null,
124520         terminateTimeout = null,
124521         MILLILSECONDS_OF_ONE_VIBRATION = 100,
124522         node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
124523         movementIndex = 0,
124524         movement = [{ left: -10 }, { left: 0 }, { left: 10 }, { left: 0 },
124525              {top: -10 }, { top: 0 }, {top: 10 }, { top: 0 }];
124526
124527     function _clearTimeout() {
124528         if (vibrateTimeout) {
124529             clearInterval(vibrateTimeout);
124530             vibrateTimeout = null;        
124531         }
124532         if (terminateTimeout) {
124533             clearTimeout(terminateTimeout);
124534             terminateTimeout = null;        
124535         }
124536     }  
124537     
124538     function stopVibrate() {
124539         isVibrating = false;
124540         _clearTimeout();
124541         node.css({left: 0, top: 0}, MILLILSECONDS_OF_ONE_VIBRATION);
124542     }
124543     
124544     function vibrate() {
124545         //node.animate(movement[movementIndex], MILLILSECONDS_OF_ONE_VIBRATION);
124546         node.css(movement[movementIndex]);
124547         movementIndex = (movementIndex + 1) % 8;
124548     }
124549     
124550     function changePulse() {
124551         //pattern != null
124552         var pulse = pattern[pulseIndex];
124553         if (pulse === '.') vibrate();
124554         ++pulseIndex;
124555         if (pulseIndex >= pattern.length) {
124556             if (terminateAfterPattern) {
124557                 setTimeout(stopVibrate, 1);
124558                 return;
124559             }
124560             pulseIndex = 0;
124561         }
124562     }
124563     
124564     function terminateVibrate() {
124565         terminateAfterPattern = true;
124566         terminateTimeout = null;
124567         if (pattern === null) {
124568             stopVibrate();        
124569         }
124570     }  
124571   
124572     function startVibrate(duration, _pattern) {
124573         if (!isInVibrateMode()) return;
124574         _clearTimeout();
124575         terminateAfterPattern = false;
124576         movementIndex = 0;
124577         
124578         if (_pattern) {
124579             pattern = _pattern;
124580             pulseIndex = 0;
124581             vibrateTimeout = setInterval(changePulse, MILLILSECONDS_OF_ONE_VIBRATION);
124582             if (duration) 
124583                 terminateAfterPattern = false;
124584             else 
124585                 terminateAfterPattern = true;
124586         } else {
124587             pattern = null;
124588             vibrateTimeout = setInterval(vibrate, MILLILSECONDS_OF_ONE_VIBRATION);
124589         }
124590         terminateTimeout = setTimeout(terminateVibrate, checkDuration(duration));        
124591         isVibrating = true;
124592     }
124593
124594     event.on("VibratingModeChanged", function (value) {
124595         if (value === false) {
124596             stopVibrate();
124597         }
124598     });
124599
124600     return {
124601         startVibrate: startVibrate,
124602         stopVibrate: stopVibrate
124603     };
124604 }()); //jslint style
124605
124606 var backlight = (function () {
124607     var timeout = null,
124608         isNotifying = false,
124609         node = jQuery("#" + constants.COMMON.VIEWPORT_CONTAINER);
124610         
124611     function _clearTimeout() {
124612         if (timeout) {
124613             clearTimeout(timeout); 
124614             timeout = null;
124615         }
124616     }
124617     
124618     function _switch(on) {
124619         node.css('opacity', on ? '':'0.4');
124620     }
124621     
124622     function switchOff() {
124623         if (!isNotifying) return;
124624         _clearTimeout();
124625         _switch(false);
124626         isNotifying = false;
124627     }
124628     
124629     function switchOn(duration) {
124630         if (isBacklightOn()) return;
124631         _clearTimeout();
124632         _switch(true);
124633         timeout = setTimeout(switchOff, checkDuration(duration));
124634         isNotifying = true;
124635     }
124636
124637     _switch(isBacklightOn());
124638     event.on("BacklightChanged", function (value) {
124639         _clearTimeout();
124640         isNotifying = false;
124641         _switch(value);
124642     });
124643
124644     return {
124645         switchOn  : switchOn,
124646         switchOff : switchOff
124647     };
124648 }()); //jslint style
124649
124650 var beeper = (function () {
124651     var isBeeping = false,
124652         timeout = null,
124653         beepFile = "beep.wav", //TODO: license issues
124654         errorHandler = null,
124655         _beeper = utils.createElement("audio", {"id": "notify-beeper"});
124656         
124657     document.getElementById("ui").appendChild(_beeper);
124658     _beeper.setAttribute("src", beepFile);
124659     _beeper.setAttribute("loop", "true");
124660     _beeper.load();
124661     
124662     function _clearTimeout() {
124663         if (timeout) {
124664             clearTimeout(timeout);
124665             timeout = false;
124666         }
124667     }
124668     
124669     function raiseError() {
124670         if (errorHandler) {
124671             setTimeout(function () {
124672                 errorHandler(new DeviceApiError(errorcode.UNKNOWN_ERR));
124673             }, 1);
124674         }
124675     }
124676     
124677     function stopBeep() {
124678         _clearTimeout();
124679         if (isBeeping) {
124680             try {
124681                 _beeper.pause();
124682             } catch (e) {}
124683             isBeeping = false;
124684         }
124685     }
124686     
124687     _beeper.addEventListener('error', function () {
124688         stopBeep();
124689         raiseError();
124690     });
124691    
124692     function startBeep(onSuccess, onError, duration) {
124693         errorHandler = onError;
124694         try {
124695             stopBeep();
124696             _beeper.currentTime = 0;
124697             _beeper.play();
124698             isBeeping = true;
124699             timeout = setTimeout(stopBeep, checkDuration(duration));
124700             setTimeout(function () {
124701                 onSuccess();
124702             }, 1);
124703         }catch (e) {
124704             raiseError();
124705         }
124706     }
124707     
124708     event.on("VolumeChanged", function (value) {
124709         value = value | 0;
124710         if (value < 0) value = 0;
124711         else if (value > 100) value = 100;       
124712         _beeper.volume = value / 100.0;
124713     });
124714     
124715     return {
124716         startBeep : startBeep,
124717         stopBeep  : stopBeep
124718     };
124719 }()); //jslint style
124720
124721 module.exports = _self = {
124722
124723     startNotify : function (onSuccess, onError, duration) {
124724         return wac2_utils.validateTypeMismatch(onSuccess, onError, "startNotify", function () {
124725             if (!isMute()) {
124726                 return pendingOperation(function () {
124727                     beeper.startBeep(onSuccess, onError, duration);
124728                 });
124729             } else if (isInVibrateMode()) {
124730                 return _self.startVibrate(onSuccess, onError, duration);
124731             } else {
124732                 return _self.lightOn(onSuccess, onError, duration);
124733             }
124734         });
124735     },
124736
124737     stopNotify : function () {
124738         beeper.stopBeep();
124739         vibrator.stopVibrate();
124740         backlight.switchOff();
124741     },
124742
124743     startVibrate : function (onSuccess, onError, duration, pattern) {       
124744         return wac2_utils.validateTypeMismatch(onSuccess, onError, "startVibrate", function () {
124745             if (pattern) {
124746                 pattern = String(pattern);
124747                 if (!pattern.match(/[\._]{1,10}/)) {
124748                     if (onError) {
124749                         setTimeout(function () {
124750                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
124751                         }, 1);
124752                     }
124753                     return undefined;
124754                 }   
124755             }
124756             
124757             if (!isInVibrateMode()) {
124758                 if (onError) {
124759                     setTimeout(function () {
124760                         onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
124761                     }, 1);
124762                 }
124763                 return undefined;          
124764             }
124765   
124766             setTimeout(function () {
124767                 onSuccess();
124768             }, 1);
124769             return pendingOperation(function () {
124770                 vibrator.startVibrate(duration, pattern);
124771             });
124772
124773         });
124774     },
124775     
124776     stopVibrate : function () {
124777         vibrator.stopVibrate();
124778     },
124779
124780     lightOn : function (onSuccess, onError, duration) {
124781         return wac2_utils.validateTypeMismatch(onSuccess, onError, "lightOn", function () {
124782             if (isBacklightOn()) {
124783                 if (onError) {
124784                     setTimeout(function () {
124785                         onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
124786                     }, 1);
124787                 }
124788                 return undefined;               
124789             }
124790         
124791             setTimeout(function () {
124792                 onSuccess();
124793             }, 1);
124794             return pendingOperation(function () {
124795                 backlight.switchOn(duration);
124796             });
124797         });
124798     },
124799
124800     lightOff : function () {
124801         backlight.switchOff();
124802     },
124803
124804     setWallpaper : function (onSuccess, onError, fileName) {
124805         //TODO: file name, existance, extension checking.
124806         return wac2_utils.validateTypeMismatch(onSuccess, onError, "setWallpaper", function () {
124807             return pendingOperation(function () {
124808                 notifications.openNotification("normal", "setWallpaper:" + fileName);
124809                 setTimeout(function () {
124810                     onSuccess();
124811                 }, 1);
124812             });
124813         });
124814     }
124815 };
124816
124817
124818 });
124819 define('ripple/platform/wac/2.0/devicestatus', function (require, exports, module) {
124820 /*
124821  *  Copyright 2011 Intel Corporation.
124822  *
124823  * Licensed under the Apache License, Version 2.0 (the "License");
124824  * you may not use this file except in compliance with the License.
124825  * You may obtain a copy of the License at
124826  *
124827  * http://www.apache.org/licenses/LICENSE-2.0
124828  *
124829  * Unless required by applicable law or agreed to in writing, software
124830  * distributed under the License is distributed on an "AS IS" BASIS,
124831  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124832  * See the License for the specific language governing permissions and
124833  * limitations under the License.
124834  */
124835
124836 var utils = require('ripple/utils'),
124837     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
124838     errorcode = require('ripple/platform/wac/2.0/errorcode'),
124839     _console = require('ripple/console'),
124840     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
124841     deviceSettings = require('ripple/deviceSettings'),    
124842     event = require('ripple/event'),    
124843     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
124844     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
124845     _getDeviceInfoAspect = true,
124846     _getNetworkInfoAspect = true,    
124847     _deviceInfoAspect = ["Battery", "Device", "Display", "MemoryUnit", "OperatingSystem", "WebRuntime"],    
124848     _networkInfoAspect = ["CellularHardware", "CellularNetwork", "WiFiHardware", "WiFiNetwork"],
124849     _aspectArray = [], 
124850     _propertyMap = {},
124851     _watches = {},
124852     _self;
124853
124854 function _asynchErrorCallback(errorCallback, errorCode) {
124855     if (errorCallback) {        
124856         setTimeout(function () {
124857             errorCallback(errorCode);
124858         }, 1);  
124859     }
124860 }
124861
124862 function _initialize() {
124863     var aspectName, index, i;
124864
124865     _aspectArray = _deviceInfoAspect.concat(_networkInfoAspect);
124866     for (index = 0; index < _aspectArray.length; index++) {
124867         aspectName = _aspectArray[index];
124868         _propertyMap[aspectName] = [];
124869         for (i in deviceSettings.retrieve(aspectName)) {
124870             _propertyMap[aspectName].push(i);
124871         }
124872     }     
124873 }
124874
124875 function _isPropertyFound(aspect, property) {
124876     if (_aspectArray.length === 0) {
124877         _initialize();
124878     }
124879
124880     if (_propertyMap[aspect]) {
124881         if (property) {
124882             return _propertyMap[aspect].some(function (prop) {
124883                 return prop === property;
124884             });
124885         }
124886         return true;
124887     }
124888     return false;
124889 }
124890
124891 function _isPropertyAllowed(aspect) {
124892     function hasAspect(asp) {
124893         return asp === aspect;
124894     }
124895
124896     if ((_deviceInfoAspect.some(hasAspect) && _getDeviceInfoAspect === false) ||
124897         (_networkInfoAspect.some(hasAspect) && _getNetworkInfoAspect === false)) {
124898         return false;
124899     }
124900
124901     return true;
124902 }
124903
124904 function _isPropertyValid(prop, errorCallback) {
124905     var _prop = Object(prop);
124906
124907     if (_prop && _prop.aspect && _prop.property) {
124908         if (_isPropertyFound(_prop.aspect, _prop.property) === false) {
124909             _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.NOT_FOUND_ERR));
124910             return false;
124911         }
124912         else if (_isPropertyAllowed(_prop.aspect) === false) {
124913             _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.SECURITY_ERR));
124914             return false;
124915         }
124916     } 
124917     else {
124918         _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.INVALID_VALUES_ERR));
124919         return false;
124920     }
124921     return true;
124922 }
124923
124924 module.exports = function () {
124925     return {  
124926         getComponents: function (aspect) {
124927             if (_isPropertyFound(aspect))
124928                 return ["_default"];
124929             return null;              
124930         },
124931
124932         isSupported: function (aspect, property) {
124933             return _isPropertyFound(aspect, property);
124934         },
124935
124936         getPropertyValue: function (successCallback, errorCallback, prop) {
124937             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "getPropertyValue", function () {                                  
124938                 if (_isPropertyValid(prop, errorCallback) !== true)
124939                     return undefined;
124940                 
124941                 var value = deviceSettings.retrieve(prop.aspect + "." + prop.property);
124942                 if (value !== undefined) {
124943                     successCallback(value, prop);
124944                 }
124945                 else {
124946                     _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.NOT_AVAILABLE_ERR)); 
124947                 }
124948                 
124949                 return null;    
124950             });        
124951         },
124952        
124953         watchPropertyChange: function (successCallback, errorCallback, prop, options) {  
124954             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "watchPropertyChange", function () {
124955                 if (_isPropertyValid(prop, errorCallback) !== true)
124956                     return undefined;
124957
124958                 var _options = Object(options),
124959                     eventType = deviceSettings.retrieve(prop.aspect)[prop.property].event,
124960                     watchObj = {
124961                         eventType: eventType,
124962                         onEvent: function (newValue) {
124963                             if (watchObj.timeStamp && 
124964                                 ((new Date()).getTime() - watchObj.timeStamp < options.minNotificationInterval)) {
124965                                 return undefined;
124966                             }                       
124967                             else if (watchObj.value &&
124968                                      (newValue > watchObj.value * (1 - _options.minChangePercent) && 
124969                                       newValue < watchObj.value * (1 + _options.minChangePercent))) {
124970                                 return undefined;
124971                             }
124972
124973                             if (watchObj.intervalId) {
124974                                 clearInterval(watchObj.intervalId);
124975                                 watchObj.intervalId = setInterval(function () {
124976                                     successCallback(deviceSettings.retrieve(prop.aspect + "." + prop.property), prop);
124977                                 }, _options.maxNotificationInterval);
124978                             }
124979                             successCallback(newValue, prop);
124980                             if (watchObj.timeStamp) {
124981                                 watchObj.timeStamp = (new Date()).getTime();
124982                             }
124983                             if (watchObj.value) {
124984                                 watchObj.value = newValue;
124985                             }
124986                         }                              
124987                     },
124988                     watchId = (new Date()).getTime() | 0;
124989
124990                 if (options && _options.minNotificationInterval && _options.maxNotificationInterval && 
124991                     (_options.minNotificationInterval < 0 || _options.maxNotificationInterval < 0 || 
124992                      _options.minNotificationInterval >= _options.maxNotificationInterval)) {
124993                     _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.INVALID_VALUES_ERR));
124994                     return undefined;
124995                 }
124996
124997                 if (options && _options.maxNotificationInterval) {
124998                     watchObj.intervalId = setInterval(function () {
124999                         successCallback(deviceSettings.retrieve(prop.aspect + "." + prop.property), prop);
125000                     }, _options.maxNotificationInterval);
125001                 }    
125002
125003                 if (options && _options.minNotificationInterval) {
125004                     watchObj.timeStamp = (new Date()).getTime();
125005                 }                    
125006
125007                 if (options && _options.minChangePercent) {
125008                     if (_options.minNotificationInterval || _options.maxNotificationInterval) {}
125009                     else {                
125010                         watchObj.value = deviceSettings.retrieve(prop.aspect + "." + prop.property);
125011                     }
125012                 }
125013                
125014                 _watches[watchId] = watchObj;
125015                 if (watchObj.eventType) {
125016                     event.on(watchObj.eventType, watchObj.onEvent);
125017                 }
125018
125019                 return watchId;
125020             });             
125021         },
125022
125023         clearPropertyChange: function (watchHandler) {
125024             var _handler = watchHandler | 0;
125025             
125026             if (_watches[_handler]) {
125027                 event.deleteEventHandler(_watches[_handler].eventType, _watches[_handler].onEvent);            
125028                 if (_watches[_handler].intervalId) {
125029                     clearInterval(_watches[_handler].intervalId);
125030                 }
125031                 delete(_watches[_handler]); 
125032             }
125033             return null;
125034         },
125035
125036         handleSubFeatures: function (subFeatures) {
125037             if (wac2_utils.isEmptyObject(subFeatures) ||
125038                 subFeatures["http://wacapps.net/api/devicestatus"] || 
125039                 (subFeatures["http://wacapps.net/api/devicestatus.deviceinfo"] &&
125040                  subFeatures["http://wacapps.net/api/devicestatus.networkinfo"])) {
125041                 return;
125042             }
125043             if (subFeatures["http://wacapps.net/api/devicestatus.deviceinfo"]) {
125044                 _getNetworkInfoAspect = false;
125045                 return;
125046             }
125047             if (subFeatures["http://wacapps.net/api/devicestatus.networkinfo"]) {
125048                 _getDeviceInfoAspect = false;
125049                 return;
125050             }
125051             _console.warn("WAC-2.0-Devicestatus-handleSubFeatures: something wrong");
125052         }
125053     };
125054 };
125055
125056
125057 });
125058 define('ripple/platform/wac/2.0/errorcode', function (require, exports, module) {
125059 /*
125060  *  Copyright 2011 Intel Corporation.
125061  *
125062  * Licensed under the Apache License, Version 2.0 (the "License"),
125063  * you may not use this file except in compliance with the License.
125064  * You may obtain a copy of the License at
125065  *
125066  * http://www.apache.org/licenses/LICENSE-2.0
125067  *
125068  * Unless required by applicable law or agreed to in writing, software
125069  * distributed under the License is distributed on an "AS IS" BASIS,
125070  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125071  * See the License for the specific language governing permissions and
125072  * limitations under the License.
125073  */
125074
125075 var _self = {
125076     message : []
125077 };
125078
125079 _self.__defineGetter__("UNKNOWN_ERR", function () {
125080     return 0;
125081 });
125082
125083 _self.__defineGetter__("INDEX_SIZE_ERR", function () {
125084     return 1;
125085 });
125086
125087 _self.__defineGetter__("DOMSTRING_SIZE_ERR", function () {
125088     return 2;
125089 });
125090
125091 _self.__defineGetter__("HIERARCHY_REQUEST_ERR", function () {
125092     return 3;
125093 });
125094
125095 _self.__defineGetter__("WRONG_DOCUMENT_ERR", function () {
125096     return 4;
125097 });
125098
125099 _self.__defineGetter__("INVALID_CHARACTER_ERR", function () {
125100     return 5;
125101 });
125102
125103 _self.__defineGetter__("NO_DATA_ALLOWED_ERR", function () {
125104     return 6;
125105 });
125106
125107 _self.__defineGetter__("NO_MODIFICATION_ALLOWED_ERR", function () {
125108     return 7;
125109 });
125110
125111 _self.__defineGetter__("NOT_FOUND_ERR", function () {
125112     return 8;
125113 });
125114
125115 _self.__defineGetter__("NOT_SUPPORTED_ERR", function () {
125116     return 9;
125117 });
125118
125119 _self.__defineGetter__("INUSE_ATTRIBUTE_ERR", function () {
125120     return 10;
125121 });
125122
125123 _self.__defineGetter__("INVALID_STATE_ERR", function () {
125124     return 11;
125125 });
125126
125127 _self.__defineGetter__("SYNTAX_ERR", function () {
125128     return 12;
125129 });
125130
125131 _self.__defineGetter__("INVALID_MODIFICATION_ERR", function () {
125132     return 13;
125133 });
125134
125135 _self.__defineGetter__("NAMESPACE_ERR", function () {
125136     return 14;
125137 });
125138
125139 _self.__defineGetter__("INVALID_ACCESS_ERR", function () {
125140     return 15;
125141 });
125142
125143 _self.__defineGetter__("VALIDATION_ERR", function () {
125144     return 16;
125145 });
125146
125147 _self.__defineGetter__("TYPE_MISMATCH_ERR", function () {
125148     return 17;
125149 });
125150
125151 _self.__defineGetter__("SECURITY_ERR", function () {
125152     return 18;
125153 });
125154
125155 _self.__defineGetter__("NETWORK_ERR", function () {
125156     return 19;
125157 });
125158
125159 _self.__defineGetter__("ABORT_ERR", function () {
125160     return 20;
125161 });
125162
125163 _self.__defineGetter__("TIMEOUT_ERR", function () {
125164     return 21;
125165 });
125166
125167 _self.__defineGetter__("INVALID_VALUES_ERR", function () {
125168     return 22;
125169 });
125170
125171 _self.__defineGetter__("IO_ERR", function () {
125172     return 100;
125173 });
125174
125175 _self.__defineGetter__("NOT_AVAILABLE_ERR", function () {
125176     return 101;
125177 });
125178
125179 function _setMessage(_self) {
125180     var c, g;
125181     for (c in _self) {
125182         g = _self.__lookupGetter__(c);
125183         if (g) {
125184             _self.message[g()] = c;
125185         }
125186     }
125187 }
125188
125189 _setMessage(_self);
125190
125191 module.exports = _self;
125192
125193
125194 });
125195 define('ripple/platform/wac/2.0/filesystem', function (require, exports, module) {
125196 /*
125197  *  Copyright 2011 Intel Corporation.
125198  *
125199  * Licensed under the Apache License, Version 2.0 (the "License");
125200  * you may not use this file except in compliance with the License.
125201  * You may obtain a copy of the License at
125202  *
125203  * http://www.apache.org/licenses/LICENSE-2.0
125204  *
125205  * Unless required by applicable law or agreed to in writing, software
125206  * distributed under the License is distributed on an "AS IS" BASIS,
125207  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125208  * See the License for the specific language governing permissions and
125209  * limitations under the License.
125210  */
125211
125212 var errorcode = require('ripple/platform/wac/2.0/errorcode'),
125213     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
125214     utils = require('ripple/utils'),
125215     dbfs  = require('ripple/platform/wac/2.0/dbfs'),
125216     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
125217     _console = require('ripple/console'),
125218     _maxPathLength = 256,
125219     _virtualRoots = ["documents", "images", "music", "videos", "downloads", "wgt-package", "wgt-private", "wgt-private-tmp", "removable", "attachments"],
125220     _realRoots = dbfs.roots,
125221     _r2vmap = {},
125222     _v2rmap = {},
125223     _initialized = false,
125224     _readOnly  = false,
125225     _writeOnly = false,
125226     _defaultMode = "rw",
125227     File, 
125228     FileStream;
125229
125230 function _isValidChar(c) {
125231     return  (c >= '0' && c <= '9') || 
125232         (c >= 'a' && c <= 'z') || 
125233         (c >= 'A' && c <= 'Z') || 
125234         (c === ' ') || 
125235         (c === '_') ||
125236         (c === '-') ||
125237         (c === '.');
125238 }
125239
125240 function _isValidFileName(name) {
125241     var _valid = true,
125242         _c;
125243
125244     if (name === '' || name === '.' || name === '..' || (name.length > _maxPathLength)) {
125245         _valid = false;
125246     } else {
125247         for (_c = 0; _c < name.length; _c++) {
125248             if (!_isValidChar(name[_c])) {
125249                 _valid = false;
125250                 break;
125251             }
125252         }
125253     }
125254     
125255     return _valid;
125256 }
125257
125258 function _initialize() {
125259     var _i;
125260
125261     dbfs.initialize();
125262     
125263     // set up the map between real path and virtual path
125264     for (_i = 0; _i < _virtualRoots.length; _i++) {
125265         _r2vmap[_realRoots[_i]] = _virtualRoots[_i];
125266     }
125267
125268     utils.forEach(_r2vmap, function (value, key) {
125269         _v2rmap[value] = key;
125270     });
125271 }
125272
125273 function _resolveSync(srcLocation, onSuccess, onError, accessMode) {
125274     var _parts = srcLocation.replace(/\/$/, '').split("/"),
125275         _header, _fullPath,
125276         _i;
125277
125278     // TODO: Initialize at bootstrap and emulatorBridge.link 
125279     if (!_initialized) {
125280         _initialize();
125281         _initialized = true;
125282     }
125283
125284     for (_i = 0; _i < _parts.length; _i++) {
125285         if (!_isValidFileName(_parts[_i])) {
125286             if (onError) {
125287                 onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
125288             }
125289             return;
125290         }
125291     }
125292
125293     _header = _v2rmap[_parts[0]];
125294     if (_header === undefined) {
125295         if (onError) {
125296             onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
125297         }
125298         return;
125299     }
125300
125301     if (_parts.length === 1) {
125302         _fullPath = _header;
125303     } else {
125304         _fullPath = _header + "/" + _parts.splice(1, _parts.length - 1).join("/");
125305     }
125306
125307     dbfs.stat(_fullPath, 
125308             function (entry) {
125309                 onSuccess(new File(entry, accessMode));
125310             }, 
125311             function () {
125312                 if (onError) {
125313                     onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
125314                 }    
125315             });
125316 }
125317
125318 function _resolveAsync(onSuccess, onError, srcLocation, accessMode) {
125319     _resolveSync(srcLocation,
125320                 function (file) {
125321                     setTimeout(function () {
125322                         onSuccess(file);
125323                     }, 1);
125324                 },
125325                 function (e) {
125326                     setTimeout(function () {
125327                         onError(e);
125328                     }, 1);
125329                 },
125330                 accessMode);
125331 }
125332
125333 File = function (entry, mode) {
125334     var _entry = entry,
125335         _mode = mode,
125336         _parent,
125337         _self;
125338
125339     function _r2v(rpath) {
125340         var i, v, r, regExp;
125341
125342         for (i = 0; i < _virtualRoots.length; i++) {
125343             v = _virtualRoots[i];
125344             r = _v2rmap[v];
125345             if (rpath.match("^" + r)) {
125346                 regExp = new RegExp("^" + r);
125347                 return rpath.replace(regExp, v);
125348             }
125349         }
125350
125351         return ""; 
125352     }
125353
125354     function _v2r(vpath) {
125355         var i, v, r, regExp;
125356
125357         for (i = 0; i < _virtualRoots.length; i++) {
125358             v = _virtualRoots[i];
125359             r = _v2rmap[v];
125360             if (vpath.match("^" + v)) {
125361                 regExp = new RegExp("^" + v);
125362                 return vpath.replace(regExp, r);
125363             }
125364         }
125365
125366         return ""; 
125367     }
125368
125369     function _copyMoveInternal(onSuccess, onError, src, dst, overwrite, func) {
125370         var _srcName = String(src),
125371             _dstName = String(dst),
125372             _src = null,
125373             _dst = null,
125374             _error = false,
125375             _dstParent = null,
125376             _dstParts  = _dstName.split("/"),
125377             _dstParentName = _dstParts.splice(0, _dstParts.length - 1).join("/");
125378
125379         if (!_entry.isDirectory) {
125380             if (onError) {
125381                 setTimeout(function () {
125382                     onError(new DeviceApiError(errorcode.IO_ERR));
125383                 }, 1);
125384             }
125385             return undefined;
125386         }
125387
125388         _resolveSync(_srcName, 
125389                 function (file) {
125390                     _src = file;
125391                 },
125392                 function (e) {
125393                     setTimeout(function () {
125394                         onError(e);
125395                     }, 1);
125396                 },
125397                 _mode);
125398
125399         if (_src) {
125400             if (_src.parent.fullPath === _self.fullPath) {
125401                 if (!_readOnly && _mode !== "r") {
125402                     _resolveSync(_dstParentName, 
125403                             function (file) {
125404                                 _dstParent = file;
125405                             },
125406                             function (e) {
125407                                 setTimeout(function () {
125408                                     onError(e);
125409                                 }, 1);
125410                             },
125411                             _mode);
125412
125413                     if (_dstParent === null) {
125414                         return undefined;
125415                     }
125416
125417                     _resolveSync(_dstName, 
125418                             function (file) {
125419                                 _dst = file;
125420                             },
125421                             function (e) {
125422                                 if (e.code !== errorcode.NOT_FOUND_ERR) {
125423                                     setTimeout(function () {
125424                                         onError(e);
125425                                     }, 1);
125426                                     _error = true;
125427                                 } 
125428                             },
125429                             _mode);
125430
125431                     if (_error) {
125432                         return undefined;
125433                     }
125434
125435                     if (_src.isFile) {
125436                         if (_dst === null) {
125437                             func(_v2r(_srcName), _v2r(_dstName),
125438                                     function () {
125439                                         setTimeout(function () {
125440                                             onSuccess();
125441                                         }, 1);
125442                                     },
125443                                     function () {});
125444                             return null;
125445                         } else {
125446                             if (_dst.isFile && Boolean(overwrite) && (_srcName !== _dstName)) {
125447                                 func(_v2r(_srcName), _v2r(_dstName),
125448                                         function () {
125449                                             setTimeout(function () {
125450                                                 onSuccess();
125451                                             }, 1);
125452                                         },
125453                                         function () {});
125454                                 return null;
125455                             } else {
125456                                 setTimeout(function () {
125457                                     onError(new DeviceApiError(errorcode.IO_ERR));
125458                                 }, 1);
125459                             }
125460                         }
125461                     } else {
125462                         if (_dst === null) {
125463                             func(_v2r(_srcName), _v2r(_dstName),
125464                                 function () {
125465                                     setTimeout(function () {
125466                                         onSuccess();
125467                                     }, 1);
125468                                 },
125469                                 function () {});
125470                             return null;
125471                         } else {
125472                             setTimeout(function () {
125473                                 onError(new DeviceApiError(errorcode.IO_ERR));
125474                             }, 1);
125475                         } 
125476                     }
125477                 } else {
125478                     if (onError) {
125479                         setTimeout(function () {
125480                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
125481                         }, 1);
125482                     }
125483                 }
125484             } else {
125485                 if (onError) {
125486                     setTimeout(function () {
125487                         onError(new DeviceApiError(errorcode.IO_ERR));
125488                     }, 1);
125489                 }
125490             }
125491         }
125492
125493         return undefined;
125494     }
125495
125496     _self = {
125497         toURI: function () {
125498             return "file://" + _entry.fullPath;
125499         },
125500         listFiles: function (onSuccess, onError, filter) {
125501             var _filter = Object(filter),
125502                 _filterName = _filter.name,
125503                 _startModified = _filter.startModified,
125504                 _endModified   = _filter.endModified;
125505
125506             function _matchName(fileName) {
125507                 var _matched = true, 
125508                     _name1 = String(_filterName).toLowerCase(),
125509                     _name2 = fileName.toLowerCase(),
125510                     _pattern;
125511
125512                 if (_filterName !== undefined && _filterName !== null) {
125513                     if (!_name1.match("\\\\%")) {
125514                         if (_name1.match("%")) {
125515                             _pattern = new RegExp("^" + _name1.replace(/%/g, ".*") + "$");
125516                             _matched = _name2.match(_pattern) ? true : false;
125517                         } else {
125518                             _matched = (_name1 === _name2);
125519                         }
125520                     } else {
125521                         // % is not allowed as a part of file name
125522                         _matched = false;
125523                     }
125524                 }
125525                 
125526                 return _matched;
125527             }
125528
125529             function _matchDate(date) {
125530                 var _matched = true;
125531
125532                 if (_startModified !== undefined && _startModified !== null) {
125533                     _matched = (date.getTime() >= _startModified.getTime());
125534                 }
125535
125536                 if (_matched && (_endModified !== undefined && _endModified !== null)) {
125537                     _matched = (date.getTime() <= _endModified.getTime());
125538                 }
125539
125540                 return _matched;
125541             }
125542
125543             function _matchFilter(entry) {
125544                 return _matchName(entry.name) && _matchDate(entry.lastModifiedDate);
125545             } 
125546
125547             function _listFiles() {
125548                 var _files = [];
125549
125550                 if ((_startModified !== undefined && !wac2_utils.isValidDate(_startModified)) ||
125551                     (_endModified !== undefined && !wac2_utils.isValidDate(_endModified))) {
125552                     if (onError) {
125553                         setTimeout(function () {
125554                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
125555                         }, 1);
125556                     }
125557                     return undefined;
125558                 }
125559
125560                 if (!_entry.isDirectory) {
125561                     if (onError) {
125562                         setTimeout(function () {
125563                             onError(new DeviceApiError(errorcode.IO_ERR));
125564                         }, 1);
125565                     }
125566                     return undefined;
125567                 }
125568
125569                 utils.forEach(_entry.children, function (child) {
125570                     if (_matchFilter(child)) {
125571                         _files.push(new File(child, _mode));
125572                     }
125573                 });
125574
125575                 setTimeout(function () {
125576                     onSuccess(_files);
125577                 }, 1);
125578
125579                 return null;
125580             }
125581
125582             return wac2_utils.validateTypeMismatch(onSuccess, onError, "listFiles", _listFiles);
125583         },
125584         openStream: function (onSuccess, onError, mode, encoding) {
125585             function _openStream() {
125586                 var  _openMode = String(mode),
125587                     _encoding = encoding ? String(encoding) : "UTF-8";
125588
125589                 if (_openMode !== "r" && _openMode !== "w" && _openMode !== "a") {
125590                     if (onError) {
125591                         setTimeout(function () {
125592                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
125593                         }, 1);
125594                     }
125595                     return undefined;
125596                 }
125597                 if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
125598                     if (onError) {
125599                         setTimeout(function () {
125600                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
125601                         }, 1);
125602                     }
125603                     return undefined;
125604                 }
125605                 
125606                 if (((_readOnly || _mode === "r") && (_openMode === "w" || _openMode === "a")) ||
125607                     (_writeOnly && _openMode === "r")) {
125608                     if (onError) {
125609                         setTimeout(function () {
125610                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
125611                         }, 1);
125612                     }
125613                     return undefined;
125614                 }
125615                  
125616                 setTimeout(function () {
125617                     onSuccess(new FileStream(_entry, _openMode, _encoding));
125618                 }, 1);
125619
125620                 return null;
125621             }
125622
125623             return wac2_utils.validateTypeMismatch(onSuccess, onError, "openStream", _openStream);
125624         },
125625         readAsText: function (onSuccess, onError, encoding) {
125626             function _readAsText() {
125627                 var _encoding = encoding ? String(encoding) : "UTF-8";
125628                 if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
125629                     if (onError) {
125630                         setTimeout(function () {
125631                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
125632                         }, 1);
125633                     }
125634                     return undefined;
125635                 }
125636
125637                 if (_writeOnly) {
125638                     if (onError) {
125639                         setTimeout(function () {
125640                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
125641                         }, 1);
125642                     }
125643                     return undefined;
125644                 }
125645
125646                 if (_self.isFile) {
125647                     dbfs.read(_entry.fullPath, 
125648                             function (data) {
125649                                 setTimeout(function () {
125650                                     onSuccess(data);
125651                                 }, 1);
125652                             },
125653                             function () {});
125654                     return null;
125655                 } else {
125656                     if (onError) {
125657                         setTimeout(function () {
125658                             onError(new DeviceApiError(errorcode.IO_ERR));
125659                         }, 1);
125660                     }
125661                 }
125662
125663                 return undefined;
125664             }
125665
125666             return wac2_utils.validateTypeMismatch(onSuccess, onError, "readAsText", _readAsText);
125667         },
125668         copyTo: function (onSuccess, onError, src, dst, overwrite) {
125669             function _copyTo() {
125670                 return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.cp);
125671             }
125672             
125673             return wac2_utils.validateTypeMismatch(onSuccess, onError, "copyTo", _copyTo);
125674         },
125675         moveTo: function (onSuccess, onError, src, dst, overwrite) {
125676             function _moveTo() {
125677                 return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.mv);
125678             }
125679
125680             return wac2_utils.validateTypeMismatch(onSuccess, onError, "moveTo", _moveTo);
125681         },
125682         createDirectory: function (dirPath) {
125683             var _path  = String(dirPath),
125684                 _parts = _path.replace(/\/$/, "").split("/"),
125685                 _dir   = null,
125686                 _exist = null,
125687                 _current = _entry.fullPath,
125688                 _i;
125689
125690             function onSuccess(entry) {
125691                 _dir = entry;
125692             }
125693
125694             for (_i = 0; _i < _parts.length; _i++) {
125695                 if (!_isValidFileName(_parts[_i])) {
125696                     throw new DeviceApiError(errorcode.INVALID_VALUES_ERR);
125697                 }
125698             }
125699       
125700             if (!entry.isDirectory) {
125701                 throw new DeviceApiError(errorcode.IO_ERR);
125702             }
125703
125704             _exist = _parts.reduce(function (obj, token) {
125705                 return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
125706             }, _entry);
125707
125708             if (_exist) {
125709                 throw new DeviceApiError(errorcode.IO_ERR);
125710             }
125711
125712             if (_readOnly || _mode === "r") {
125713                 throw new DeviceApiError(errorcode.SECURITY_ERR);
125714             }
125715
125716             for (_i = 0; _i < _parts.length; _i++) {
125717                 _current = _current + "/" + _parts[_i];
125718                 dbfs.mkdir(_current, onSuccess);
125719             }
125720             
125721             return new File(_dir, _mode);
125722         },
125723         createFile: function (filePath) {
125724             var _name = String(filePath),
125725                 _file = null;
125726
125727             if (!_isValidFileName(_name)) {
125728                 throw new DeviceApiError(errorcode.INVALID_VALUES_ERR);
125729             }
125730
125731             if (!entry.isDirectory || (_entry.children && _entry.children[_name])) {
125732                 throw new DeviceApiError(errorcode.IO_ERR);
125733             }
125734
125735             if (_readOnly || _mode === "r") {
125736                 throw new DeviceApiError(errorcode.SECURITY_ERR);
125737             }
125738
125739             dbfs.touch(_entry.fullPath + "/" + _name,
125740                         function (entry) {
125741                             _file = new File(entry, _mode);
125742                         },
125743                         function () {});
125744             
125745             return _file;
125746         },
125747         resolve: function (filePath) {
125748             var _fullPath = _self.fullPath + "/" + String(filePath),
125749                 _file = null;
125750  
125751             if (!_entry.isDirectory) {
125752                 throw new DeviceApiError(errorcode.IO_ERR); 
125753             }
125754
125755             _resolveSync(_fullPath,
125756                     function (file) {
125757                         _file = file;
125758                     },
125759                     function (e) {
125760                         throw (e);
125761                     },
125762                     _mode);
125763
125764             return _file;
125765         }, 
125766         deleteDirectory: function (onSuccess, onError, directory, recursive) {
125767             function _deleteDirectory() {
125768                 var _dir = null,
125769                     _dirName = String(directory);
125770                 _resolveSync(_dirName, 
125771                         function (file) {
125772                             _dir = file;
125773                         },
125774                         function (e) {
125775                             setTimeout(function () {
125776                                 onError(e);
125777                             }, 1);
125778                         },
125779                         _mode);
125780
125781                 if (_dir) {
125782                     if (_dir.isDirectory && 
125783                         _dir.parent.fullPath === _self.fullPath &&
125784                         (!recursive && _dir.length === 0)) {
125785                         if (!_readOnly && _mode !== "r") {
125786                             dbfs.rmdir(_v2r(_dirName),
125787                                     function () {
125788                                         setTimeout(function () {
125789                                             onSuccess();
125790                                         }, 1);
125791                                     },
125792                                     function () {});
125793                             return null;
125794                         } else {
125795                             if (onError) {
125796                                 setTimeout(function () {
125797                                     onError(new DeviceApiError(errorcode.SECURITY_ERR));
125798                                 }, 1);
125799                             }
125800                         }
125801                     } else {
125802                         if (onError) {
125803                             setTimeout(function () {
125804                                 onError(new DeviceApiError(errorcode.IO_ERR));
125805                             }, 1);
125806                         }
125807                     }
125808                 }
125809
125810                 return undefined; 
125811             }
125812
125813             return wac2_utils.validateTypeMismatch(onSuccess, onError, "deleteDirectory", _deleteDirectory);
125814         },
125815         deleteFile: function (onSuccess, onError, fileName) {
125816             function _deleteFile() {
125817                 var _file = null;
125818                 _resolveSync(String(fileName),
125819                         function (file) {
125820                             _file = file;
125821                         },
125822                         function (e) {
125823                             if (onError) {
125824                                 setTimeout(function () {
125825                                     onError(e);
125826                                 }, 1);
125827                             }
125828                         },
125829                         _mode);
125830
125831                 if (_file) {
125832                     if (_file.isFile && _file.parent.fullPath === _self.fullPath) {
125833                         if (!_readOnly && _mode !== "r") {
125834                             dbfs.rm(_v2r(fileName),
125835                                     function () {
125836                                         setTimeout(function () {
125837                                             onSuccess();
125838                                         }, 1);
125839                                     },
125840                                     function () {});
125841                             return null;
125842                         } else {
125843                             if (onError) {
125844                                 setTimeout(function () {
125845                                     onError(new DeviceApiError(errorcode.SECURITY_ERR));
125846                                 }, 1);
125847                             }
125848                         }
125849                     } else {
125850                         if (onError) {
125851                             setTimeout(function () {
125852                                 onError(new DeviceApiError(errorcode.IO_ERR));
125853                             }, 1);
125854                         }
125855                     }
125856                 }
125857
125858                 return undefined; 
125859             }
125860
125861             return wac2_utils.validateTypeMismatch(onSuccess, onError, "deleteFile", _deleteFile);
125862         }
125863     };
125864
125865     _self.__defineGetter__("parent", function () {
125866         var _parts = _self.fullPath.split("/");
125867
125868         if (_parent === undefined) {
125869             if (_parts.length === 1) {
125870                 // virtual root's parent is null
125871                 _parent = null;
125872             } else {
125873                 _resolveSync(_parts.splice(0, _parts.length - 1).join("/"), 
125874                         function (file) {
125875                             _parent = file;
125876                         },
125877                         function () {},
125878                         _mode);
125879             }
125880             return _parent;
125881         } else { 
125882             return _parent;
125883         }
125884     });
125885
125886     _self.__defineGetter__("readOnly", function () {
125887         return false;
125888     });
125889
125890     _self.__defineGetter__("isFile", function () {
125891         return !_entry.isDirectory;
125892     });
125893
125894     _self.__defineGetter__("isDirectory", function () {
125895         return _entry.isDirectory;
125896     });
125897
125898     _self.__defineGetter__("created", function () {
125899         return undefined;
125900     });
125901
125902     _self.__defineGetter__("modified", function () {
125903         if (_entry.isDirectory) {
125904             return undefined;
125905         } else {
125906             return _entry.lastModifiedDate;
125907         }
125908     });
125909
125910     _self.__defineGetter__("path", function () {
125911         var _parts = _self.fullPath.split("/");
125912
125913         if (_parts.length === 1) {
125914             // virtual root
125915             return _parts.join("");
125916         } else {
125917             return _parts.splice(0, _parts.length - 1).join("/") + "/";
125918         }
125919     });
125920
125921     _self.__defineGetter__("name", function () {
125922         return _entry.name;
125923     });
125924
125925     _self.__defineGetter__("fullPath", function () {
125926         return _r2v(_entry.fullPath);
125927     });
125928
125929     _self.__defineGetter__("fileSize", function () {
125930         if (_entry.isDirectory) {
125931             return undefined;
125932         } else {
125933             return _entry.data.length;
125934         }
125935     });
125936
125937     _self.__defineGetter__("length", function () {
125938         var _l = 0;
125939         if (_entry.isDirectory) {
125940             utils.forEach(_entry.children, function () {
125941                 _l++;
125942             });
125943             return _l;
125944         } else {
125945             return undefined;
125946         }
125947     });
125948
125949     return _self;
125950 };
125951
125952 FileStream = function (entry, mode, encoding) {
125953     var _entry = entry,
125954         _data = entry.data,
125955         _mode = mode,
125956         _position = (_mode === "a" ? _data.length : 0),
125957         _self;
125958
125959     _self = {
125960         close: function () {
125961             var _element;
125962             if (mode === "a" || mode === "w") {
125963                 dbfs.write(_entry.fullPath, _data, function () {}, function () {});
125964             }
125965             for (_element in _self) {
125966                 delete _self[_element];
125967             }
125968         },
125969         read: function (charCount) {
125970             var _count  = charCount | 0,
125971                 _substr = _data.substring(_position, _position + _count);
125972
125973             if (_position + _count > _data.length) {
125974                 _position = _data.length;
125975             } else {
125976                 _position += _count;
125977             }
125978
125979             return _substr; 
125980         },
125981         readBytes: function (byteCount) {
125982             var _substr = _self.read(byteCount),
125983                 _bytes = [],
125984                 _i;
125985
125986             for (_i = 0; _i < _substr.length; _i++) {
125987                 _bytes.push(_substr.charCodeAt(_i));
125988             }
125989
125990             return _bytes;
125991         },
125992         readBase64: function (byteCount) {
125993             var _substr = _self.read(byteCount);
125994
125995             return window.atob(_substr);
125996         },
125997         write: function (stringData) {
125998             var _stringData = String(stringData),
125999                 _substr = _data.substring(0, _position);
126000
126001             _data = _substr.concat(_stringData);
126002             _position = _data.length;
126003         },
126004         writeBytes: function (byteData) {
126005             _self.write(String.fromCharCode.apply(String, byteData));
126006         },
126007         writeBase64: function (base64Data) {
126008             _self.write(window.btoa(String(base64Data)));
126009         }
126010     };
126011
126012     _self.__defineGetter__("eof", function () {
126013         return _position === _data.length;
126014     });
126015
126016     _self.__defineGetter__("position", function () {
126017         return _position;
126018     });
126019
126020     _self.__defineSetter__("position", function (value) {
126021         var _value = value | 0;
126022
126023         if (_value >= 0 && _value <= _data.length) {
126024             _position = _value;
126025         } else {
126026             throw new DeviceApiError(errorcode.INVALID_VALUES_ERR);
126027         }
126028     });
126029
126030     _self.__defineGetter__("bytesAvailable", function () {
126031         return (_data.length - _position) || -1;
126032     });
126033
126034     return _self;
126035 };
126036
126037 module.exports = function () {
126038     return {
126039         maxPathLength: _maxPathLength,
126040         resolve: function (onSuccess, onError, srcLocation, accessMode) {
126041             function _resolve() {
126042                 var _mode = accessMode ? String(accessMode) : _defaultMode;
126043
126044                 if (_mode === "r" || _mode === "rw") {
126045                     _resolveAsync(onSuccess, onError, String(srcLocation), _mode);
126046                     return null;
126047                 } else {
126048                     if (onError) {
126049                         setTimeout(function () {
126050                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
126051                         }, 1);
126052                     }
126053                 }
126054                 return undefined;
126055             }
126056
126057             return wac2_utils.validateTypeMismatch(onSuccess, onError, "resolve", _resolve);
126058         },
126059         handleSubFeatures: function (subFeatures) {
126060             if (wac2_utils.isEmptyObject(subFeatures) ||
126061                 subFeatures["http://wacapps.net/api/filesystem"] ||
126062                 (subFeatures["http://wacapps.net/api/filesystem.read"] &&
126063                 subFeatures["http://wacapps.net/api/filesystem.write"])) {
126064                 return;
126065             }
126066             if (subFeatures["http://wacapps.net/api/filesystem.read"]) {
126067                 _readOnly = true;
126068                 return;
126069             }
126070             if (subFeatures["http://wacapps.net/api/filesystem.write"]) {
126071                 _writeOnly = true;
126072                 return;
126073             }
126074             _console.warn("WAC-2.0-Filesystem: something wrong in handleSubFeatures");
126075         }
126076     }; 
126077 };
126078
126079
126080 });
126081 define('ripple/platform/wac/2.0/geolocation', function (require, exports, module) {
126082 /*
126083  *  Copyright 2011 Intel Corporation.
126084  *
126085  * Licensed under the Apache License, Version 2.0 (the "License");
126086  * you may not use this file except in compliance with the License.
126087  * You may obtain a copy of the License at
126088  *
126089  * http://www.apache.org/licenses/LICENSE-2.0
126090  *
126091  * Unless required by applicable law or agreed to in writing, software
126092  * distributed under the License is distributed on an "AS IS" BASIS,
126093  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126094  * See the License for the specific language governing permissions and
126095  * limitations under the License.
126096  */
126097
126098 var geo = require('ripple/geo'),
126099     Position = require('ripple/platform/w3c/1.0/Position'),
126100     PositionError = require('ripple/platform/w3c/1.0/PositionError'),
126101     _lastPosition = null,
126102     _watches = {},
126103     _defaultInterval = 100,
126104     _defaultDelay = 50,
126105     _self;
126106
126107 function _createPosition() {
126108     var position = new Position(),
126109         positionInfo = geo.getPositionInfo();
126110
126111     position.coords.latitude = positionInfo.latitude;
126112     position.coords.longitude = positionInfo.longitude;
126113     position.coords.altitude = positionInfo.altitude;
126114     position.coords.altitudeAccuracy = positionInfo.altitudeAccuracy;
126115     position.coords.accuracy = positionInfo.accuracy;
126116     position.coords.heading = positionInfo.heading;
126117     position.coords.speed = positionInfo.speed;
126118     position.timestamp = positionInfo.timeStamp.getTime();
126119
126120     return position;
126121 }
126122
126123 function _isValid(onSuccess, onError, options, argLength) {
126124     if (argLength < 1 || argLength > 3)
126125         return false;
126126
126127     if (typeof onSuccess !== "function")   // imply onSuccess == null
126128         return false;
126129
126130     if (onError && (typeof onError !== "function"))
126131         return false;
126132
126133     if ((options !== undefined) &&
126134         ((typeof options !== "object") ||
126135         (options.enableHighAccuracy !== undefined) && (typeof options.enableHighAccuracy !== "boolean") ||
126136         (options.timeout            !== undefined) && (typeof options.timeout            !== "number") ||
126137         (options.maximumAge         !== undefined) && (typeof options.maximumAge         !== "number")))
126138         return false;
126139
126140     return true;
126141 }
126142
126143 function _processOptions(options) {
126144     var validOptions = {
126145         enableHighAccuracy: false,
126146         timeout: 0,
126147         maximumAge: 0
126148     };
126149
126150     if (options !== undefined &&
126151         options.maximumAge !== undefined &&
126152         options.maximumAge === Math.floor(options.maximumAge) &&
126153         options.maximumAge >= 0) {
126154         validOptions.maximumAge = options.maximumAge | 0;
126155     } else {
126156         validOptions.maximumAge = 0;
126157     }
126158
126159     if (options !== undefined &&
126160         options.timeout !== undefined &&
126161         options.timeout === Math.floor(options.timeout)) {
126162         validOptions.timeout = (options.timeout >= 0) ? (options.timeout | 0) : 0;
126163     } else {
126164         validOptions.timeout = Infinity;
126165     }
126166
126167     if (options !== undefined && options.enableHighAccuracy !== undefined) {
126168         validOptions.enableHighAccuracy = options.enableHighAccuracy;
126169     } else {
126170         validOptions.enableHighAccuracy = false;
126171     }
126172
126173     validOptions.delay = geo.delay * 1000 || _defaultDelay;
126174
126175     return validOptions;
126176 }
126177
126178 function _errorOccur(code, onError) {
126179     if (!onError)
126180         return;
126181
126182     var error = new PositionError();
126183
126184     error.code = code;
126185     switch (code) {
126186     case PositionError.POSITION_UNAVAILABLE:
126187         error.message = "Position unavailable";
126188         break;
126189
126190     case PositionError.TIMEOUT:
126191         error.message = "Position timed out";
126192         break;
126193     }
126194
126195     onError(error);
126196 }
126197
126198 function _execute(data) {
126199     return function () {
126200         if (_lastPosition !== null &&
126201             ((new Date()).getTime() - _lastPosition.timestamp <= data.maximumAge)) {
126202             window.setTimeout(function () {
126203                 data.onSuccess(_lastPosition);
126204             }, 1);
126205         } else if (data.timeout === 0) {
126206             _errorOccur(PositionError.TIMEOUT, data.onError);
126207         } else {
126208             window.setTimeout(function () {
126209                 if (data.delay <= data.timeout) {
126210                     _lastPosition = _createPosition();
126211
126212                     if (_lastPosition !== null) {
126213                         data.onSuccess(_lastPosition);
126214                     } else {
126215                         _errorOccur(PositionError.POSITION_UNAVAILABLE, data.onError);
126216                     }
126217                 } else {
126218                     _errorOccur(PositionError.TIMEOUT, data.onError);
126219                 }
126220             }, Math.min(data.delay, data.timeout));
126221         }
126222     };
126223 }
126224
126225 function _interval(k, n) { 
126226     return k * Math.floor((n + k - 1) / k) || k;
126227 }
126228
126229 _self = {
126230     getCurrentPosition: function (onSuccess, onError, options) {
126231         if (!_isValid(onSuccess, onError, options, arguments.length))
126232             return;
126233
126234         var validData = _processOptions(options);
126235
126236         validData.onSuccess = onSuccess;
126237         validData.onError   = onError;
126238
126239         _execute(validData)();
126240     },
126241
126242     watchPosition: function (geolocationSuccess, geolocationError, geolocationOptions) {
126243         if (!_isValid(geolocationSuccess, geolocationError, geolocationOptions, arguments.length))
126244             return undefined;
126245
126246         var validData = _processOptions(geolocationOptions),
126247             watchId = (new Date()).getTime() | 0,
126248             watchObj = {
126249                 onSuccess:          geolocationSuccess,
126250                 onError:            geolocationError,
126251                 enableHighAccuracy: validData.enableHighAccuracy,
126252                 timeout:            validData.timeout,
126253                 maximumAge:         validData.maximumAge,
126254                 delay:              validData.delay,
126255                 interval:           _interval(validData.maximumAge || _defaultInterval,
126256                                         Math.min(validData.delay, validData.timeout)),
126257             };
126258
126259         _watches[watchId] = watchObj;
126260
126261         _watches[watchId].intervalId = window.setInterval(_execute(_watches[watchId]),
126262             _watches[watchId].interval);
126263
126264         return watchId;
126265     },
126266
126267     clearWatch: function (watchId) {
126268         if (arguments.length !== 1)
126269             return undefined;
126270
126271         var id = watchId | 0;
126272
126273         if (_watches[id]) {
126274             window.clearInterval(_watches[id].intervalId);
126275             delete _watches[id];
126276
126277             return null;
126278         }
126279
126280         return undefined;
126281     }
126282 };
126283
126284 module.exports = _self;
126285
126286 });
126287 define('ripple/platform/wac/2.0/messagefilter', function (require, exports, module) {
126288 /*
126289  *  Copyright 2011 Intel Corporation.
126290  *
126291  * Licensed under the Apache License, Version 2.0 (the "License");
126292  * you may not use this file except in compliance with the License.
126293  * You may obtain a copy of the License at
126294  *
126295  * http://www.apache.org/licenses/LICENSE-2.0
126296  *
126297  * Unless required by applicable law or agreed to in writing, software
126298  * distributed under the License is distributed on an "AS IS" BASIS,
126299  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126300  * See the License for the specific language governing permissions and
126301  * limitations under the License.
126302  */
126303
126304 var _self;
126305
126306 _self = function (criteria) {
126307     var pattern,
126308         messageFilter;
126309
126310     messageFilter = {
126311         match: function (target) {
126312             var result = false, index;
126313
126314             if (Object.prototype.toString.call(criteria) === "[object Array]") {
126315                 for (index in criteria) {
126316                     if (_self(criteria[index]).match(target))
126317                         return true;
126318                 }
126319                 return false;
126320             }
126321
126322             switch (Object.prototype.toString.call(target)) {
126323             case "[object Number]":
126324                 result = (criteria === target);
126325                 break;
126326
126327             case "[object String]":
126328                 result = pattern.test(target);
126329                 break;
126330
126331             case "[object Array]":
126332                 for (index in target) {
126333                     if (messageFilter.match(target[index]))
126334                         return true;
126335                 }
126336                 break;
126337             }
126338
126339             return result;
126340         }
126341     };
126342
126343     if (typeof criteria === "string")
126344         pattern = new RegExp(criteria.replace(/(^|[^\\])%+/g, "$1.*").replace(/\\%/g, "%").replace(/.*/, "^$&$"), "i");
126345
126346     return messageFilter;
126347 };
126348
126349 module.exports = _self;
126350
126351 });
126352 define('ripple/platform/wac/2.0/messaging', function (require, exports, module) {
126353 /*
126354  *  Copyright 2011 Intel Corporation.
126355  *
126356  * Licensed under the Apache License, Version 2.0 (the "License");
126357  * you may not use this file except in compliance with the License.
126358  * You may obtain a copy of the License at
126359  *
126360  * http://www.apache.org/licenses/LICENSE-2.0
126361  *
126362  * Unless required by applicable law or agreed to in writing, software
126363  * distributed under the License is distributed on an "AS IS" BASIS,
126364  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126365  * See the License for the specific language governing permissions and
126366  * limitations under the License.
126367  */
126368
126369 var utils = require('ripple/utils'),
126370     event = require('ripple/event'),
126371     db = require('ripple/db'),
126372     exception = require('ripple/exception'),
126373     errorcode = require('ripple/platform/wac/2.0/errorcode'),
126374     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
126375     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
126376     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
126377     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
126378     TypeCoerce = require('ripple/platform/wac/2.0/typecoerce'),
126379     Filter = require('ripple/platform/wac/2.0/messagefilter'),
126380     FileSystem = require('ripple/platform/wac/2.0/filesystem'),
126381     MessageSendCallback,
126382     Message,
126383     MessageFilter,
126384     Recipients,
126385     _KEY = "wac2-pim-messaging",
126386     _PENDING_TIME = 600,
126387     _messages = {},
126388     _subscriber = {
126389         onSMS: {},
126390         onMMS: {},
126391         onEmail: {}
126392     },
126393     _sentStatus = {},
126394     _security = {
126395         "http://wacapps.net/api/messaging": [],
126396         "http://wacapps.net/api/messaging.send": ["sendMessage"],
126397         "http://wacapps.net/api/messaging.find": ["findMessages"],
126398         "http://wacapps.net/api/messaging.subscribe": ["onSMS", "onMMS", "onEmail"],
126399         "http://wacapps.net/api/messaging.write": ["update"],
126400         all: true
126401     },
126402     _fileSystem,
126403     _initialized = false,
126404     _self;
126405
126406 function _initialize() {
126407     _get();
126408     if (!_fileSystem) {
126409         _fileSystem = new FileSystem();
126410     }
126411     _initialized = true;
126412 }
126413
126414 function _get() {
126415     _messages = db.retrieveObject(_KEY) || {1: [], 2: [], 3: [], 4: []};
126416     utils.forEach(_messages, function (folder) {
126417         utils.forEach(folder, function (messageItem) {
126418             if (messageItem.timestamp)
126419                 messageItem.timestamp = new Date(messageItem.timestamp);
126420         });
126421     });
126422 }
126423
126424 function _save() {
126425     db.saveObject(_KEY, _messages);
126426 }
126427
126428 function _updateDB(message, duplicate) {
126429     _get();
126430     _messages[message.folder].push(message);
126431     if (duplicate)
126432         _messages[duplicate.folder].push(duplicate);
126433     _save();
126434 }
126435
126436 function _processAttachments(message) {
126437     var attachmentsFileName = [],
126438         attachmentsContent = [];
126439
126440     function _generateAttachmentFileName(attachment) {
126441         var lastDot = attachment.filename.lastIndexOf(".");
126442         return attachment.filename.substring(0, lastDot) + "_" + Math.uuid(8, 16) + attachment.filename.substring(lastDot);
126443     }
126444
126445     function _onResolveSuccess(file) {
126446         var fileAttachment = file.createFile(attachmentsFileName[0]);
126447
126448         fileAttachment.openStream(
126449             function (fs) {
126450                 fs.write(attachmentsContent[0]);
126451                 fs.close();
126452             }, null, "w");
126453     }
126454
126455     function _onResolveError() {
126456     }
126457
126458     if (message.attachments.length === 0)
126459         return;
126460
126461     attachmentsFileName.push(_generateAttachmentFileName(message.attachments[0]));
126462     attachmentsContent.push(message.attachments[0].content);
126463
126464     _fileSystem.resolve(_onResolveSuccess, _onResolveError, "attachments", "rw");
126465
126466     message.attachments = utils.copy(attachmentsFileName);
126467 }
126468
126469 function _errorOccurred(onError, code) {
126470     if (!onError)
126471         return;
126472
126473     setTimeout(function () {
126474         onError(new DeviceApiError(code));
126475     }, 1);
126476 }
126477
126478 function _pendingOperate(operate, scope) {
126479     var i, argumentVector = [];
126480
126481     for (i = 0; i < arguments.length - 2; i++)
126482         argumentVector[i] = arguments[i + 2];
126483
126484     return function () {
126485         var pendingObj, pendingOperation;
126486
126487         pendingObj = new PendingObject();
126488         pendingObj.pendingID = window.setTimeout(function () {
126489             pendingObj.setCancelFlag(false);
126490             if (operate)
126491                 operate.apply(scope, argumentVector);
126492         }, _PENDING_TIME);
126493
126494         pendingOperation = new PendingOperation(pendingObj);
126495
126496         return pendingOperation;
126497     };
126498 }
126499
126500 function _onMessage(onMessage, messageHandler) {
126501     if (!messageHandler)
126502         exception.raise(exception.types.Argument,
126503             onMessage + " invalid messageHandler parameter",
126504             new DeviceApiError(errorcode.INVALID_VALUES_ERR));
126505
126506     utils.validateArgumentType(messageHandler, "function", null,
126507         "messageHandler invalid function parameter",
126508         new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
126509
126510     if (!_security.all && !_security[onMessage])
126511         exception.raise(exception.types.Argument,
126512             onMessage + " access denied", new DeviceApiError(errorcode.SECURITY_ERR));
126513
126514     var idSubscribe = (new Date()).getTime() | 0;
126515     _subscriber[onMessage][idSubscribe] = messageHandler;
126516
126517     return idSubscribe;
126518 }
126519
126520 function _validateRecipients(message) {
126521     var i;
126522
126523     for (i = 0; i < message.to.length;) {
126524         message.to[i] = message.to[i].replace(/^\s*(\S*)\s*$/, '$1');
126525         if (message.to[i] === "")
126526             message.to.splice(i, 1);
126527         else
126528             i++;
126529     }
126530     for (i = 0; i < message.cc.length;) {
126531         message.cc[i] = message.cc[i].replace(/^\s*(\S*)\s*$/, '$1');
126532         if (message.cc[i] === "")
126533             message.cc.splice(i, 1);
126534         else
126535             i++;
126536     }
126537     for (i = 0; i < message.bcc.length;) {
126538         message.bcc[i] = message.bcc[i].replace(/^\s*(\S*)\s*$/, '$1');
126539         if (message.bcc[i] === "")
126540             message.bcc.splice(i, 1);
126541         else
126542             i++;
126543     }
126544     if (message.to.length + message.cc.length + message.bcc.length === 0)
126545         exception.raise(exception.types.Argument,
126546             "sendMessage invalid message.to parameter",
126547             new DeviceApiError(errorcode.INVALID_VALUES_ERR));
126548 }
126549
126550 function _isValid(onSuccess, onError, message) {
126551     if (onSuccess &&
126552         typeof onSuccess !== "function" &&
126553         typeof onSuccess !== "object") {
126554         exception.raise(exception.types.Argument,
126555             "sendMessage invalid successCallback parameter",
126556             new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
126557     }
126558
126559     if (onError) {
126560         utils.validateArgumentType(onError, "function", null,
126561             "sendMessage invalid errorCallback parameter",
126562             new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
126563     }
126564
126565     if (!onSuccess) {
126566         _errorOccurred(onError, errorcode.INVALID_VALUES_ERR);
126567         return false;
126568     }
126569
126570     if (message) {
126571         utils.validateArgumentType(message, "object", null,
126572             "sendMessage invalid message parameter",
126573             new DeviceApiError(errorcode.INVALID_VALUES_ERR));
126574     } else {
126575         _errorOccurred(onError, errorcode.INVALID_VALUES_ERR);
126576         return false;
126577     }
126578
126579     if (message.type !== _self().TYPE_SMS &&
126580         message.type !== _self().TYPE_MMS &&
126581         message.type !== _self().TYPE_EMAIL)
126582         exception.raise(exception.types.Argument,
126583             "sendMessage invalid message.type parameter",
126584             new DeviceApiError(errorcode.INVALID_VALUES_ERR));
126585
126586     if (!_security.all && !_security.sendMessage) {
126587         _errorOccurred(onError, errorcode.SECURITY_ERR);
126588         return false;
126589     }
126590
126591     TypeCoerce(Message(0)).cast(message);
126592     _validateRecipients(message);
126593
126594     return true;
126595 }
126596
126597 function _getEachSentStatus(onMessageSentSuccess, onMessageSentError, message,
126598                             sucRecipients, failRecipients, recType) {
126599     utils.forEach(message[recType], function (recipient) {
126600         if (_sentStatus[recipient]) {
126601             sucRecipients[recType].push(recipient);
126602             if (onMessageSentSuccess) {
126603                 onMessageSentSuccess(recipient);
126604             }
126605         } else {
126606             failRecipients[recType].push(recipient);
126607             if (onMessageSentError) {
126608                 onMessageSentError(new DeviceApiError(errorcode.UNKNOWN_ERR), recipient);
126609             }
126610         }
126611     });
126612 }
126613
126614 function _getSentStatus(onSuccess, onError, message, onMessageSentSuccess, onMessageSentError) {
126615     var allSentSuccess,
126616         sucRecipients = new Recipients(),
126617         failRecipients = new Recipients(),
126618         duplicate;
126619
126620     _getEachSentStatus(onMessageSentSuccess, onMessageSentError,
126621         message, sucRecipients, failRecipients, "to");
126622
126623     if (message.type === _self().TYPE_EMAIL) {
126624         _getEachSentStatus(onMessageSentSuccess, onMessageSentError,
126625             message, sucRecipients, failRecipients, "cc");
126626         _getEachSentStatus(onMessageSentSuccess, onMessageSentError,
126627             message, sucRecipients, failRecipients, "bcc");
126628     }
126629
126630     allSentSuccess = (failRecipients.total() === 0);
126631
126632     if (allSentSuccess) {
126633         message.folder = _self().FOLDER_SENTBOX;
126634     } else if (sucRecipients.total() === 0) {
126635         message.folder = _self().FOLDER_DRAFTS;
126636     } else {
126637         duplicate = utils.copy(message);
126638
126639         message.to = sucRecipients.to;
126640         message.cc = sucRecipients.cc;
126641         message.bcc = sucRecipients.bcc;
126642         message.folder = _self().FOLDER_SENTBOX;
126643
126644         duplicate.to = failRecipients.to;
126645         duplicate.cc = failRecipients.cc;
126646         duplicate.bcc = failRecipients.bcc;
126647         duplicate.folder = _self().FOLDER_DRAFTS;
126648     }
126649
126650     _updateDB(message, duplicate);
126651
126652     if (allSentSuccess) {
126653         onSuccess();
126654     } else if (onError) {
126655         onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
126656     }
126657 }
126658
126659 _self = function () {
126660     var messaging = {
126661         createMessage: function (type) {
126662             type = type | 0;
126663
126664             if (type < _self().TYPE_SMS || type > _self().TYPE_EMAIL)
126665                 exception.raise(exception.types.Argument,
126666                 "type invalid value", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
126667
126668             var msg = new Message(type);
126669
126670             return msg;
126671         },
126672
126673         sendMessage: function (successCallback, errorCallback, message) {
126674             var ret;
126675
126676             function _sendMessage() {
126677                 event.trigger("OutsideMessageReceived", [message]);
126678
126679                 return _pendingOperate(_getSentStatus, undefined,
126680                     successCallback, errorCallback, message)();
126681             }
126682
126683             function _sendEachMessage() {
126684                 utils.forEach(successCallback, function (value, key) {
126685                     utils.validateArgumentType(value, "function", null,
126686                         "sendMessage invalid successCallback." + key + " parameter",
126687                         new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
126688                 });
126689
126690                 event.trigger("OutsideMessageReceived", [message]);
126691
126692                 return _pendingOperate(_getSentStatus, undefined,
126693                     successCallback.onsuccess, errorCallback, message,
126694                     successCallback.onmessagesendsuccess, successCallback.onmessagesenderror)();
126695             }
126696
126697             if (!_isValid(successCallback, errorCallback, message))
126698                 return null;
126699
126700             switch (typeof successCallback) {
126701             case "function":
126702                 ret = _sendMessage();
126703                 break;
126704
126705             case "object":
126706                 ret = _sendEachMessage();
126707                 break;
126708             }
126709
126710             return ret;
126711         },
126712
126713         findMessages: function (successCallback, errorCallback, filter) {
126714             function _findMessages() {
126715                 var message, result = [];
126716
126717                 if (!_security.all && !_security.findMessages)
126718                     return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
126719
126720                 utils.forEach(_messages, function (folder) {
126721                     utils.forEach(folder, function (messageItem) {
126722                         if ((filter                 === undefined || filter === null) ||
126723                             (filter.id              === undefined || Filter(filter.id).match(messageItem.id)) &&
126724                             (filter.type            === undefined || Filter(filter.type).match(messageItem.type)) &&
126725                             (filter.folder          === undefined || Filter(filter.folder).match(messageItem.folder)) &&
126726                             (filter.startTimestamp  === undefined || (messageItem.timestamp >= filter.startTimestamp)) &&
126727                             (filter.endTimestamp    === undefined || (messageItem.timestamp <= filter.endTimestamp)) &&
126728                             (filter.from            === undefined || Filter(filter.from).match(messageItem.from)) &&
126729                             (filter.to              === undefined || Filter(filter.to).match(messageItem.to)) &&
126730                             (filter.cc              === undefined || Filter(filter.cc).match(messageItem.cc)) &&
126731                             (filter.bcc             === undefined || Filter(filter.bcc).match(messageItem.bcc)) &&
126732                             (filter.body            === undefined || Filter(filter.body).match(messageItem.body)) &&
126733                             (filter.isRead          === undefined || (messageItem.isRead === filter.isRead)) &&
126734                             (filter.messagePriority === undefined || (messageItem.priority === filter.messagePriority)) &&
126735                             (filter.subject         === undefined || Filter(filter.subject).match(messageItem.subject))) {
126736                             message = utils.copy(messageItem);
126737                             result.push(message);
126738                         }
126739                     });
126740                 });
126741                 successCallback(result);
126742             }
126743             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "findMessages", _pendingOperate(_findMessages));
126744         },
126745
126746         onSMS: function (messageHandler) {
126747             return _onMessage("onSMS", messageHandler);
126748         },
126749
126750         onMMS: function (messageHandler) {
126751             return _onMessage("onMMS", messageHandler);
126752         },
126753
126754         onEmail: function (messageHandler) {
126755             return _onMessage("onEmail", messageHandler);
126756         },
126757
126758         unsubscribe: function (subscriptionHandler) {
126759             var onMessage, idSubscribe;
126760
126761             utils.validateArgumentType(subscriptionHandler, "integer",
126762                 null, "subscriptionHandler invalid function parameter",
126763                 new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
126764
126765             for (onMessage in _subscriber) {
126766                 for (idSubscribe in _subscriber[onMessage]) {
126767                     if (idSubscribe == subscriptionHandler) {
126768                         delete _subscriber[onMessage][idSubscribe];
126769                         return;
126770                     }
126771                 }
126772             }
126773         },
126774
126775         handleSubFeatures: function (subFeatures) {
126776             for (var subFeature in subFeatures) {
126777                 if (_security[subFeature].length === 0) {
126778                     _security.all = true;
126779                     return;
126780                 }
126781                 _security.all = false;
126782                 utils.forEach(_security[subFeature], function (method) {
126783                     _security[method] = true;
126784                 });
126785             }
126786         }
126787     };
126788
126789     messaging.__defineGetter__("TYPE_SMS", function () {
126790         return 1;
126791     });
126792
126793     messaging.__defineGetter__("TYPE_MMS", function () {
126794         return 2;
126795     });
126796
126797     messaging.__defineGetter__("TYPE_EMAIL", function () {
126798         return 3;
126799     });
126800
126801     messaging.__defineGetter__("FOLDER_INBOX", function () {
126802         return 1;
126803     });
126804
126805     messaging.__defineGetter__("FOLDER_OUTBOX", function () {
126806         return 2;
126807     });
126808
126809     messaging.__defineGetter__("FOLDER_DRAFTS", function () {
126810         return 3;
126811     });
126812
126813     messaging.__defineGetter__("FOLDER_SENTBOX", function () {
126814         return 4;
126815     });
126816
126817     if (!_initialized)
126818         _initialize();
126819
126820     return messaging;
126821 };
126822
126823 MessageSendCallback = {
126824     onsuccess: function () {},
126825     onmessagesendsuccess: function (recipient) {},
126826     onmessagesenderror: function (error, recipient) {}
126827 };
126828
126829 Message = function (type) {
126830     this.id = Math.uuid(null, 16);
126831     this.type = type;
126832     this.folder = 0;
126833     this.timestamp = new Date();
126834     this.from = "";
126835     this.to = [""];
126836     this.cc = [""];
126837     this.bcc = [""];
126838     this.body = "";
126839     this.isRead = false;
126840     this.priority = false;
126841     this.subject = "";
126842     this.attachments = [""];
126843
126844     this.update = function (successCallback, errorCallback) {
126845         function _update() {
126846             var isFound = false;
126847
126848             if (!_security.all && !_security.update)
126849                 return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
126850
126851             TypeCoerce(new Message(0)).cast(this);
126852             _get();
126853             utils.forEach(_messages[this.folder], function (messageItem) {
126854                 if (messageItem.id === this.id) {
126855                     !this.isRead || (messageItem.isRead = this.isRead);
126856                     if (this.folder === _self().FOLDER_DRAFTS) {
126857                         !this.type        || (messageItem.type        = this.type);
126858                         !this.to          || (messageItem.to          = utils.copy(this.to));
126859                         !this.cc          || (messageItem.cc          = utils.copy(this.cc));
126860                         !this.bcc         || (messageItem.bcc         = utils.copy(this.bcc));
126861                         !this.body        || (messageItem.body        = this.body);
126862                         !this.priority    || (messageItem.priority    = this.priority);
126863                         !this.subject     || (messageItem.subject     = this.subject);
126864                         !this.attachments || (messageItem.attachments = utils.copy(this.attachments));
126865                     }
126866                     isFound = true;
126867                 }
126868             });
126869
126870             if (isFound) {
126871                 _save();
126872                 successCallback();
126873             } else {
126874                 _errorOccurred(errorCallback, errorcode.NOT_FOUND_ERR);
126875             }
126876         }
126877         return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "update", _pendingOperate(_update, this));
126878     };
126879 };
126880
126881 MessageFilter = {
126882     id: "",
126883     type: [0],
126884     folder: [0],
126885     startTimestamp: new Date(),
126886     endTimestamp: new Date(),
126887     from: "",
126888     to: [""],
126889     cc: [""],
126890     bcc: [""],
126891     body: "",
126892     isRead: false,
126893     messagePriority: false,
126894     subject: ""
126895 };
126896
126897 Recipients = function () {
126898     this.to  = [];
126899     this.cc  = [];
126900     this.bcc = [];
126901
126902     this.total = function () {
126903         return (this.to.length + this.cc.length + this.bcc.length);
126904     };
126905 };
126906
126907 event.on("MessageReceived", function (message) {
126908     var onMessage;
126909
126910     switch (message.type) {
126911     case "sms":
126912         message.type = _self().TYPE_SMS;
126913         onMessage = "onSMS";
126914         break;
126915
126916     case "mms":
126917         message.type = _self().TYPE_MMS;
126918         onMessage = "onMMS";
126919         break;
126920
126921     case "email":
126922         message.type = _self().TYPE_EMAIL;
126923         onMessage = "onEmail";
126924         break;
126925
126926     default:
126927         break;
126928     }
126929
126930     message.folder = _self().FOLDER_INBOX;
126931     _processAttachments(message);
126932     _updateDB(message);
126933     utils.forEach(_subscriber[onMessage], function (subscriberCallback) {
126934         subscriberCallback(message);
126935     });
126936 });
126937
126938 event.on("MessageSent", function (sentStatus) {
126939     _sentStatus = sentStatus;
126940 });
126941
126942 module.exports = _self;
126943
126944 });
126945 define('ripple/platform/wac/2.0/orientation', function (require, exports, module) {
126946 /*
126947  *  Copyright 2011 Intel Corporation.
126948  *
126949  * Licensed under the Apache License, Version 2.0 (the "License");
126950  * you may not use this file except in compliance with the License.
126951  * You may obtain a copy of the License at
126952  *
126953  * http://www.apache.org/licenses/LICENSE-2.0
126954  *
126955  * Unless required by applicable law or agreed to in writing, software
126956  * distributed under the License is distributed on an "AS IS" BASIS,
126957  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126958  * See the License for the specific language governing permissions and
126959  * limitations under the License.
126960  */
126961
126962 var utils = require('ripple/utils'),
126963     event = require('ripple/event'),
126964     Rotation = function (alpha, beta, gamma) {
126965         return {
126966             alpha: alpha || 0,
126967             beta:  beta  || 0,
126968             gamma: gamma || 0
126969         };
126970     },
126971     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
126972     _rotationInfo = new Rotation(),
126973     _defaultInterval = 100,
126974     _watches = {},
126975     _self;
126976
126977 module.exports = _self = {
126978     getCurrentOrientation: function (onSuccess, onError) {
126979         function _getCurrentOrientation() {
126980             setTimeout(function () {
126981                 onSuccess(utils.copy(_rotationInfo));
126982             }, 1);
126983             return null;
126984         }
126985
126986         return wac2_utils.validateTypeMismatch(onSuccess, onError, "getCurrentOrientation", _getCurrentOrientation);
126987     },
126988
126989     watchOrientation: function (orientationSuccess, orientationError, options) {
126990         function _watchOrientation() {
126991             var watchId = (new Date()).getTime() | 0,
126992                 watchObj = {},
126993                 opt = Object(options),
126994                 minNotificationInterval = opt.minNotificationInterval | 0,
126995                 orientationInterval = _defaultInterval;
126996
126997             if (minNotificationInterval > 0) {
126998                 orientationInterval = minNotificationInterval;
126999             }
127000
127001             watchObj = {
127002                 onSuccess: orientationSuccess,
127003                 onError: orientationError,
127004                 interval: orientationInterval
127005             };
127006
127007             _watches[watchId] = watchObj;
127008
127009             _watches[watchId].intervalId = setInterval(function () {
127010                 _self.getCurrentOrientation(_watches[watchId].onSuccess, _watches[watchId].onError);
127011             }, _watches[watchId].interval);
127012
127013             return watchId;
127014         }
127015
127016         return wac2_utils.validateTypeMismatch(orientationSuccess, orientationError, "watchOrientation", _watchOrientation);
127017     },
127018
127019     clearWatch: function (watchId) {
127020
127021         var id = watchId | 0;
127022         if (_watches[id]) {
127023             clearInterval(_watches[id].intervalId);
127024             delete(_watches[id]);
127025             return null;
127026         }
127027
127028         return undefined;
127029     }
127030 };
127031
127032 event.on("AccelerometerInfoChangedEvent", function (orientationInfo) {
127033     _rotationInfo.alpha = orientationInfo.orientation.alpha;
127034     _rotationInfo.beta  = orientationInfo.orientation.beta;
127035     _rotationInfo.gamma = orientationInfo.orientation.gamma;
127036 });
127037
127038
127039 });
127040 define('ripple/platform/wac/2.0/pendingObject', function (require, exports, module) {
127041 /*
127042  *  Copyright 2011 Intel Corporation.
127043  *
127044  * Licensed under the Apache License, Version 2.0 (the "License");
127045  * you may not use this file except in compliance with the License.
127046  * You may obtain a copy of the License at
127047  *
127048  * http://www.apache.org/licenses/LICENSE-2.0
127049  *
127050  * Unless required by applicable law or agreed to in writing, software
127051  * distributed under the License is distributed on an "AS IS" BASIS,
127052  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127053  * See the License for the specific language governing permissions and
127054  * limitations under the License.
127055  */
127056
127057 module.exports = function (pendingObj) {
127058     var cancelFlag = true;
127059     this.setCancelFlag = function (flag) {
127060         cancelFlag = flag;
127061     };
127062     this.getCancelFlag = function () {
127063         return cancelFlag;
127064     };
127065     this.userCancel = null;
127066     this.pendingID = null;
127067 };
127068
127069 });
127070 define('ripple/platform/wac/2.0/pendingoperation', function (require, exports, module) {
127071 /*
127072  *  Copyright 2011 Intel Corporation.
127073  *
127074  * Licensed under the Apache License, Version 2.0 (the "License");
127075  * you may not use this file except in compliance with the License.
127076  * You may obtain a copy of the License at
127077  *
127078  * http://www.apache.org/licenses/LICENSE-2.0
127079  *
127080  * Unless required by applicable law or agreed to in writing, software
127081  * distributed under the License is distributed on an "AS IS" BASIS,
127082  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127083  * See the License for the specific language governing permissions and
127084  * limitations under the License.
127085  */
127086
127087 module.exports = function (pendingObj) {
127088     var pending = true;
127089     this.cancel = function () {
127090         if (pending === true) {
127091             if (typeof (pendingObj.getCancelFlag) === "function" && pendingObj.getCancelFlag() === false) {
127092                 pending = false;
127093                 // this clearTimeout is for the case when a 3rd party is invoked to do the task, and it's finished sooner than the intended timeout. therefore, the 3rd party set CancelFlag false, and this cancel is called before timeout
127094                 clearTimeout(pendingObj.pendingID);
127095                 return false;
127096             }
127097             if (typeof (pendingObj.userCancel) === "function") {
127098                 pendingObj.userCancel();
127099             }
127100             clearTimeout(pendingObj.pendingID);
127101             pending = false;
127102             return true;
127103         } else {
127104             return false;
127105         }
127106     };
127107 };
127108
127109
127110 });
127111 define('ripple/platform/wac/2.0/spec/config', function (require, exports, module) {
127112 /*
127113  *  Copyright 2011 Research In Motion Limited.
127114  *
127115  * Licensed under the Apache License, Version 2.0 (the "License");
127116  * you may not use this file except in compliance with the License.
127117  * You may obtain a copy of the License at
127118  *
127119  * http://www.apache.org/licenses/LICENSE-2.0
127120  *
127121  * Unless required by applicable law or agreed to in writing, software
127122  * distributed under the License is distributed on an "AS IS" BASIS,
127123  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127124  * See the License for the specific language governing permissions and
127125  * limitations under the License.
127126  */
127127 var platform = require('ripple/platform'),
127128     utils = require('ripple/utils'),
127129     db = require('ripple/db'),
127130     constants = require('ripple/constants');
127131
127132 module.exports = {
127133     fileName: "config.xml",
127134     validateVersion: function (configValidationObject) {
127135         var valid = true;
127136         // no xmlns:JIL in wac 2.0 spec
127137         valid = !!configValidationObject.widget.validationResult[0].attributes.xmlns.valid;
127138
127139         return valid;
127140     },
127141     extractInfo: function (configValidationObject) {
127142         if (!configValidationObject) {
127143             return null;
127144         }
127145
127146         var widgetInfo = {},
127147             configFeatures,
127148             configPreferences,
127149             preferenceName,
127150             platform;
127151
127152         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
127153         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
127154         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
127155         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
127156
127157         widgetInfo.features = {};
127158
127159         configFeatures = configValidationObject.widget.children.feature.validationResult;
127160         utils.forEach(configFeatures, function (f) {
127161             if (f.valid === true) {
127162                 var feature = {id: f.attributes.name.value,
127163                          required: f.attributes.required.valid};
127164                 widgetInfo.features[feature.id] = feature;
127165             }
127166         });
127167
127168         widgetInfo.preferences = {};
127169
127170         configPreferences = configValidationObject.widget.children.preference.validationResult;
127171
127172         platform = require('ripple/platform');
127173         utils.forEach(configPreferences, function (preference) {
127174             preferenceName = preference.attributes.name.value;
127175             if (preferenceName) {
127176                 widgetInfo.preferences[preferenceName] = {
127177                     "key": preferenceName,
127178                     "value": preference.attributes.value.value || "",
127179                     "readonly": preference.attributes.readonly.value === "true"
127180                 };
127181
127182                 db.save(preferenceName,
127183                         widgetInfo.preferences[preferenceName].value,
127184                         platform.getPersistencePrefix(widgetInfo.id));
127185             }
127186         });
127187
127188         return widgetInfo;
127189     },
127190     schema: {
127191         rootElement: "widget",
127192         widget: {
127193             nodeName: "widget",
127194             required: true,
127195             occurrence: 1,
127196             helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in configuration document and may have following child elments: name,description,icon,author,license,content,feature and preference. \"widget\" element MAY have following attributes: id,version,height,width, defaultlocale, xml:lang and dir",
127197             attributes: {
127198                 xmlns: {
127199                     attributeName: "xmlns",
127200                     required: true,
127201                     type: "list",
127202                     listValues: ["http://www.w3.org/ns/widgets"]
127203                 },
127204                 "xml:lang": {
127205                     attributeName: "xml:lang",
127206                     required: false,
127207                     type: "iso-language"
127208                 },
127209                 dir: {
127210                     attributeName: "dir",
127211                     required: false,
127212                     type: "list",
127213                     listValues: ["ltr", "rtl", "lro", "rlo"]
127214                 },
127215                 id: {
127216                     attributeName: "id",
127217                     required: false,
127218                     type: "string"
127219                 },
127220                 version: {
127221                     attributeName: "version",
127222                     required: false,
127223                     type: "string"
127224                 },
127225                 height: {
127226                     attributeName: "height",
127227                     required: false,
127228                     type: "integer"
127229                 },
127230                 width: {
127231                     attributeName: "width",
127232                     required: false,
127233                     type: "integer"
127234                 },
127235                 viewmodes: {
127236                     attributeName: "viewmodes",
127237                     required: false,
127238                     type: "list",
127239                     listValues: ["windowed", "floating", "fullscreen", "maximized", "minimized"]
127240                 },
127241                 defaultlocale: {
127242                     attributeName: "defaultlocale",
127243                     required: false,
127244                     type: "iso-language"
127245                 },
127246             },
127247             children: {
127248                 name: {
127249                     nodeName: "name",
127250                     required: false,
127251                     occurrence: 0,
127252                     type: "string",
127253                     attributes: {
127254                         "xml:lang": {
127255                             attributeName: "xml:lang",
127256                             required: false,
127257                             type: "iso-language",
127258                             unique: true
127259                         },
127260                         dir: {
127261                             attributeName: "dir",
127262                             required: false,
127263                             type: "list",
127264                             listValues: ["ltr", "rtl", "lro", "rlo"]
127265                         },
127266                         "short": {
127267                             attributeName: "short",
127268                             required: false,
127269                             type: "string"
127270                         }
127271                     },
127272                     children: {
127273                         span: {
127274                             nodeName: "span",
127275                             required: false,
127276                             type: "string",
127277                             attributes: {
127278                                 "xml:lang": {
127279                                     attributeName: "xml:lang",
127280                                     required: false,
127281                                     type: "iso-language",
127282                                     unique: true
127283                                 },
127284                                 dir: {
127285                                     attributeName: "dir",
127286                                     required: false,
127287                                     type: "list",
127288                                     listValues: ["ltr", "rtl", "lro", "rlo"]
127289                                 }
127290                             }
127291                         }
127292                     }
127293                 },
127294                 description: {
127295                     nodeName: "description",
127296                     required: false,
127297                     occurrence: 0,
127298                     type: "string",
127299                     attributes: {
127300                         "xml:lang": {
127301                             attributeName: "xml:lang",
127302                             required: false,
127303                             type: "iso-language",
127304                             unique: true
127305                         },
127306                         dir: {
127307                             attributeName: "dir",
127308                             required: false,
127309                             type: "list",
127310                             listValues: ["ltr", "rtl", "lro", "rlo"]
127311                         }
127312                     },
127313                     children: {
127314                         span: {
127315                             nodeName: "span",
127316                             required: false,
127317                             type: "string",
127318                             attributes: {
127319                                 "xml:lang": {
127320                                     attributeName: "xml:lang",
127321                                     required: false,
127322                                     type: "iso-language",
127323                                     unique: true
127324                                 },
127325                                 dir: {
127326                                     attributeName: "dir",
127327                                     required: false,
127328                                     type: "list",
127329                                     listValues: ["ltr", "rtl", "lro", "rlo"]
127330                                 }
127331                             }
127332                         }
127333                     }
127334                 },
127335                 author: {
127336                     nodeName: "author",
127337                     required: false,
127338                     occurrence: 0,
127339                     type: "string",
127340                     attributes: {
127341                         "xml:lang": {
127342                             attributeName: "xml:lang",
127343                             required: false,
127344                             type: "iso-language",
127345                         },
127346                         dir: {
127347                             attributeName: "dir",
127348                             required: false,
127349                             type: "list",
127350                             listValues: ["ltr", "rtl", "lro", "rlo"]
127351                         },
127352                         href: {
127353                             attributeName: "href",
127354                             required: false,
127355                             type: "regex",
127356                             regex: constants.REGEX.URL
127357                         },
127358                         email: {
127359                             attributeName: "email",
127360                             required: false,
127361                             type: "regex",
127362                             regex: constants.REGEX.EMAIL
127363                         }
127364                     },
127365                     children: {
127366                         span: {
127367                             nodeName: "span",
127368                             required: false,
127369                             type: "string",
127370                             attributes: {
127371                                 "xml:lang": {
127372                                     attributeName: "xml:lang",
127373                                     required: false,
127374                                     type: "iso-language",
127375                                     unique: true
127376                                 },
127377                                 dir: {
127378                                     attributeName: "dir",
127379                                     required: false,
127380                                     type: "list",
127381                                     listValues: ["ltr", "rtl", "lro", "rlo"]
127382                                 }
127383                             }
127384                         }
127385                     }
127386                 },
127387                 license: {
127388                     nodeName: "license",
127389                     required: false,
127390                     occurrence: 0,
127391                     type: "string",
127392                     attributes: {
127393                         "xml:lang": {
127394                             attributeName: "xml:lang",
127395                             required: false,
127396                             type: "iso-language",
127397                         },
127398                         dir: {
127399                             attributeName: "dir",
127400                             required: false,
127401                             type: "list",
127402                             listValues: ["ltr", "rtl", "lro", "rlo"]
127403                         },
127404                         href: {
127405                             attributeName: "href",
127406                             type: "regex",
127407                             required: false,
127408                             regex: constants.REGEX.URL
127409                         }
127410                     },
127411                     children: {
127412                         span: {
127413                             nodeName: "span",
127414                             required: false,
127415                             type: "string",
127416                             attributes: {
127417                                 "xml:lang": {
127418                                     attributeName: "xml:lang",
127419                                     required: false,
127420                                     type: "iso-language",
127421                                     unique: true
127422                                 },
127423                                 dir: {
127424                                     attributeName: "dir",
127425                                     required: false,
127426                                     type: "list",
127427                                     listValues: ["ltr", "rtl", "lro", "rlo"]
127428                                 }
127429                             }
127430                         }
127431                     }
127432                 },
127433                 icon: {
127434                     nodeName: "icon",
127435                     required: false,
127436                     occurrence: 0,
127437                     attributes: {
127438                         "xml:lang": {
127439                             attributeName: "xml:lang",
127440                             required: false,
127441                             type: "iso-language",
127442                         },
127443                         dir: {
127444                             attributeName: "dir",
127445                             required: false,
127446                             type: "list",
127447                             listValues: ["ltr", "rtl", "lro", "rlo"]
127448                         },
127449                         src: {
127450                             attributeName: "src",
127451                             required: true,
127452                             type: "string"
127453                         },
127454                         width: {
127455                             attributeName: "width",
127456                             required: false,
127457                             type: "integer"
127458                         },
127459                         height: {
127460                             attributeName: "height",
127461                             required: false,
127462                             type: "integer"
127463                         }
127464                     }
127465                 },
127466                 content: {
127467                     nodeName: "content",
127468                     required: false,
127469                     occurrence: 1,
127470                     attributes: {
127471                         "xml:lang": {
127472                             attributeName: "xml:lang",
127473                             required: false,
127474                             type: "iso-language",
127475                             unique: true
127476                         },
127477                         dir: {
127478                             attributeName: "dir",
127479                             required: false,
127480                             type: "list",
127481                             listValues: ["ltr", "rtl", "lro", "rlo"]
127482                         },
127483                         src: {
127484                             attributeName: "src",
127485                             required: true,
127486                             type: "string"
127487                         },
127488                         encoding: {
127489                             attributeName: "encoding",
127490                             required: false,
127491                             type: "string"
127492                         },
127493                         type: {
127494                             attributeName: "type",
127495                             required: false,
127496                             type: "string"
127497                         }
127498                     }
127499                 },
127500                 feature: {
127501                     nodeName: "feature",
127502                     required: false,
127503                     occurrence: 0,
127504                     attributes: {
127505                         "xml:lang": {
127506                             attributeName: "xml:lang",
127507                             required: false,
127508                             type: "iso-language",
127509                         },
127510                         dir: {
127511                             attributeName: "dir",
127512                             required: false,
127513                             type: "list",
127514                             listValues: ["ltr", "rtl", "lro", "rlo"]
127515                         },
127516                         name: {
127517                             attributeName: "name",
127518                             required: true,
127519                             type: "list",
127520                             listValues: ["http://www.w3.org/TR/geolocation-API/",
127521                                             "http://wacapps.net/api/deviceapis", "http://wacapps.net/api/accelerometer",
127522                                             "http://wacapps.net/api/orientation", "http://wacapps.net/api/camera",
127523                                             "http://wacapps.net/api/camera.show", "http://wacapps.net/api/camera.capture",
127524                                             "http://wacapps.net/api/devicestatus", "http://wacapps.net/api/devicestatus.deviceinfo",
127525                                             "http://wacapps.net/api/devicestatus.networkinfo", "http://wacapps.net/api/filesystem",
127526                                             "http://wacapps.net/api/filesystem.read", "http://wacapps.net/api/filesystem.write",
127527                                             "http://wacapps.net/api/messaging", "http://wacapps.net/api/messaging.send", 
127528                                             "http://wacapps.net/api/messaging.find", "http://wacapps.net/api/messaging.subscribe",
127529                                             "http://wacapps.net/api/messaging.write", "http://wacapps.net/api/pim.contact",
127530                                             "http://wacapps.net/api/pim.contact.read", "http://wacapps.net/api/pim.contact.write",
127531                                             "http://wacapps.net/api/pim.calendar", "http://wacapps.net/api/pim.calendar.read",
127532                                             "http://wacapps.net/api/pim.calendar.write", "http://wacapps.net/api/pim.task", 
127533                                             "http://wacapps.net/api/pim.task.read", "http://wacapps.net/api/pim.task.write",
127534                                             "http://wacapps.net/api/deviceinteraction"]
127535                         },
127536                         required: {
127537                             attributeName: "required",
127538                             type: "boolean",
127539                             required: false
127540                         }
127541                     },
127542                     children: {
127543                         param: {
127544                             nodeName: "param",
127545                             required: false,
127546                             occurrence: 0,
127547                             attributes: {
127548                                 "xml:lang": {
127549                                     attributeName: "xml:lang",
127550                                     required: false,
127551                                     type: "iso-language",
127552                                 },
127553                                 dir: {
127554                                     attributeName: "dir",
127555                                     required: false,
127556                                     type: "list",
127557                                     listValues: ["ltr", "rtl", "lro", "rlo"]
127558                                 },
127559                                 name: {
127560                                     attributeName: "name",
127561                                     required: true,
127562                                     type: "string",
127563                                 },
127564                                 value: {
127565                                     attributeName: "value",
127566                                     required: true,
127567                                     type: "string",
127568                                 }
127569                             }
127570                         }
127571                     }
127572                 },
127573                 preference: {
127574                     nodeName: "preference",
127575                     required: false,
127576                     occurrence: 0,
127577                     attributes: {
127578                         "xml:lang": {
127579                             attributeName: "xml:lang",
127580                             required: false,
127581                             type: "iso-language",
127582                         },
127583                         dir: {
127584                             attributeName: "dir",
127585                             required: false,
127586                             type: "list",
127587                             listValues: ["ltr", "rtl", "lro", "rlo"]
127588                         },
127589                         name: {
127590                             attributeName: "name",
127591                             required: true,
127592                             type: "string"
127593                         },
127594                         value: {
127595                             type: "string",
127596                             required: false,
127597                             attributeName: "value"
127598                         },
127599                         readonly: {
127600                             attributeName: "readonly",
127601                             type: "boolean",
127602                             required: false
127603                         }
127604                     }
127605                 }
127606             }
127607         }
127608     }
127609 };
127610
127611 });
127612 define('ripple/platform/wac/2.0/spec/device', function (require, exports, module) {
127613 /*
127614  *  Copyright 2011 Intel Corporation.
127615  *
127616  * Licensed under the Apache License, Version 2.0 (the "License");
127617  * you may not use this file except in compliance with the License.
127618  * You may obtain a copy of the License at
127619  *
127620  * http://www.apache.org/licenses/LICENSE-2.0
127621  *
127622  * Unless required by applicable law or agreed to in writing, software
127623  * distributed under the License is distributed on an "AS IS" BASIS,
127624  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127625  * See the License for the specific language governing permissions and
127626  * limitations under the License.
127627  */
127628 var event = require('ripple/event');
127629
127630 function deviceStatusEventTrigger(setting) {
127631     event.trigger("DeviceStatusChanged", [setting]);
127632 }
127633
127634 module.exports = {
127635     "Config": {
127636         "vibratingMode": {
127637             "name": "Vibrator",
127638             "control": {
127639                 "type": "checkbox",
127640                 "value": true
127641             },
127642             "callback": function (setting) {
127643                 event.trigger("VibratingModeChanged", [setting]);
127644             }
127645         },
127646         "soundVolume": {
127647             "name": "Sound Volume",
127648             "control": {
127649                 "type": "range",
127650                 "value": 100,
127651                 "min": 0,
127652                 "max": 100
127653             },
127654             "callback": function (setting) {
127655                 event.trigger("VolumeChanged", [setting]);
127656             }
127657         },
127658         "backlight": {
127659             "name": "Backlight",
127660             "control": {
127661                 "type": "checkbox",
127662                 "value": true
127663             },
127664             "callback": function (setting) {
127665                 event.trigger("BacklightChanged", [setting]);
127666             }
127667         }
127668     },
127669     "Battery": {
127670         "batteryLevel": {
127671             "name": "Battery Remaining %",
127672             "control": {
127673                 "type": "select",
127674                 "value": 100
127675             },
127676             "options": (function () {
127677                 var i,
127678                     optionList = {};
127679
127680                 for (i = 0; i <= 100; i += 10) {
127681                     optionList[i] = i;
127682                 }
127683
127684                 return optionList;
127685             }()),
127686             "event": "BatteryLevelChanged",
127687             "callback": function (setting) {
127688                 event.trigger("BatteryLevelChanged", [setting]);
127689             }
127690         },
127691
127692         "batteryBeingCharged": {
127693             "name": "Battery Is Charging",
127694             "control": {
127695                 "type": "checkbox",
127696                 "value": true
127697             },
127698             "event": "BatteryBeingChargedChanged",
127699             "callback": function (setting) {
127700                 event.trigger("BatteryBeingChargedChanged", [setting]);
127701             }
127702         },
127703     },
127704     "CellularHardware": {
127705         "status": {
127706             "name": "status",
127707             "control": {
127708                 "type": "checkbox",
127709                 "value": true
127710             },
127711             "event": "CellularHardwareStatusChanged",
127712             "callback": function (setting) {
127713                 event.trigger("CellularHardwareStatusChanged", [setting]);
127714             }
127715         }
127716     },
127717     "CellularNetwork": {
127718         "isInRoaming": {
127719             "name": "Roaming",
127720             "control": {
127721                 "type": "checkbox",
127722                 "value": true
127723             },
127724             "event": "CellularNetworkIsInRoamingChanged",
127725             "callback": function (setting) {
127726                 event.trigger("CellularNetworkIsInRoamingChanged", [setting]);
127727             }
127728         }, 
127729         "mcc": {
127730             "name": "mcc",
127731             "control": {
127732                 "type": "text",
127733                 "value": "460",
127734                 "readonly": "readonly"
127735             }
127736         }, 
127737         "mnc": {
127738             "name": "mnc",
127739             "control": {
127740                 "type": "text",
127741                 "value": "0",
127742                 "readonly": "readonly"
127743             }
127744         }, 
127745         "signalStrength": {
127746             "name": "Signal Strength",
127747             "control": {
127748                 "type": "select",
127749                 "value": 100
127750             },
127751             "options": (function () {
127752                 var i,
127753                     optionList = {};
127754
127755                 for (i = 0; i <= 100; i += 10) {
127756                     optionList[i] = i;
127757                 }
127758
127759                 return optionList;
127760             }()),
127761             "event": "CellularNetworkSignalStrengthChanged",
127762             "callback": function (setting) {
127763                 event.trigger("CellularNetworkSignalStrengthChanged", [setting]);
127764             }
127765         }, 
127766         "operatorName": {
127767             "name": "Operator Name",
127768             "control": {
127769                 "type": "text",
127770                 "value": "CMCC",
127771                 "readonly": "readonly"
127772             }
127773         }
127774     },
127775     "Device": {
127776         "imei": {
127777             "name": "IMEI",
127778             "control": {
127779                 "type": "text",
127780                 "value": "860398001689659",
127781                 "readonly": "readonly"
127782             }
127783         }, 
127784         "model": {
127785             "name": "Model",
127786             "control": {
127787                 "type": "text",
127788                 "value": "",
127789                 "readonly": "readonly"
127790             }
127791         }, 
127792         "version": {
127793             "name": "Version",
127794             "control": {
127795                 "type": "text",
127796                 "value": "",
127797                 "readonly": "readonly"
127798             }
127799         }, 
127800         "vendor": {
127801             "name": "Vendor.",
127802             "control": {
127803                 "type": "text",
127804                 "value": "",
127805                 "readonly": "readonly"
127806             }
127807         }
127808     },
127809     "Display": {
127810         "resolutionHeight": {
127811             "name": "Resolution Height",
127812             "control": {
127813                 "type": "number",
127814                 "value": 0,
127815                 "readonly": "readonly"
127816             }
127817         }, 
127818         "resolutionWidth": {
127819             "name": "Resolution Width",
127820             "control": {
127821                 "type": "number",
127822                 "value": 0,
127823                 "readonly": "readonly"
127824             }
127825         }, 
127826         "pixelAspectRatio": {
127827             "name": "Pixel Aspectratio",
127828             "control": {
127829                 "type": "number",
127830                 "value": 0,
127831                 "readonly": "readonly"
127832             }
127833         }, 
127834         "dpiY": {
127835             "name": "DPI-Y",
127836             "control": {
127837                 "type": "number",
127838                 "value": 0,
127839                 "readonly": "readonly"
127840             }
127841         },         
127842         "dpiX": {
127843             "name": "DPI-X",
127844             "control": {
127845                 "type": "number",
127846                 "value": 0,
127847                 "readonly": "readonly"
127848             }
127849         }, 
127850         "colorDepth": {
127851             "name": "Color Depth",
127852             "control": {
127853                 "type": "number",
127854                 "value": 32,
127855                 "readonly": "readonly"
127856             }
127857         }
127858     },
127859     "MemoryUnit": {
127860         "removable": {
127861             "name": "Removable",
127862             "control": {
127863                 "type": "checkbox",
127864                 "value": true,
127865                 "readonly": "readonly"
127866             }
127867         },
127868         "size": {
127869             "name": "Total Memory",
127870             "control": {
127871                 "type": "number",
127872                 "value": 262144,
127873                 "readonly": "readonly"
127874             }
127875         },        
127876         "availableSize": {
127877             "name": "Available Size",
127878             "control": {
127879                 "type": "range",
127880                 "value": 16384,
127881                 "min": 0,
127882                 "max": 262144
127883             },
127884             "event": "MemoryUnitAvailableSizeChanged",
127885             "callback": function (setting) {
127886                 event.trigger("MemoryUnitAvailableSizeChanged", [setting]);
127887             }
127888         }
127889     },
127890     "OperatingSystem": {
127891         "language": {
127892             "name": "Language",
127893             "control": {
127894                 "type": "text",
127895                 "value": "English",
127896                 "readonly": "readonly"
127897             }
127898         }, 
127899         "version": {
127900             "name": "Version",
127901             "control": {
127902                 "type": "text",
127903                 "value": "",
127904                 "readonly": "readonly"
127905             }
127906         }, 
127907         "name": {
127908             "name": "Name",
127909             "control": {
127910                 "type": "text",
127911                 "value": "",
127912                 "readonly": "readonly"
127913             }
127914         }, 
127915         "vendor": {
127916             "name": "Vendor",
127917             "control": {
127918                 "type": "text",
127919                 "value": "",
127920                 "readonly": "readonly"
127921             }
127922         }
127923     },
127924     "WebRuntime": {
127925         "wacVersion": {
127926             "name": "WAC Version",
127927             "control": {
127928                 "type": "text",
127929                 "value": "2.0",
127930                 "readonly": "readonly"
127931             }
127932         }, 
127933         "supportedImageFormats": {
127934             "name": "Image Formats",
127935             "control": {
127936                 "type": "text",
127937                 "value": "gif87, gif89, png, jpeg",
127938                 "readonly": "readonly"
127939             },
127940             "event": "WebRuntimeSupportedImageFormatsChanged",
127941             "callback": function (setting) {
127942                 event.trigger("WebRuntimeSupportedImageFormatsChanged", [setting]);
127943             }
127944         }, 
127945         "version": {
127946             "name": "Web Runtime Version",
127947             "control": {
127948                 "type": "text",
127949                 "value": "1.0",
127950                 "readonly": "readonly"
127951             }
127952         }, 
127953         "name": {
127954             "name": "Web Runtime Name",
127955             "control": {
127956                 "type": "text",
127957                 "value": "Tizen Web Simulator",
127958                 "readonly": "readonly"
127959             }
127960         }, 
127961         "vendor": {
127962             "name": "Vendor Name",
127963             "control": {
127964                 "type": "text",
127965                 "value": "Tizen SDK team",
127966                 "readonly": "readonly"
127967             }
127968         }
127969     },
127970     "WiFiHardware": {
127971         "status": {
127972             "name": "Status",
127973             "control": {
127974                 "type": "checkbox",
127975                 "value": true
127976             },
127977             "event": "WiFiHardwareStatusChanged",
127978             "callback": function (setting) {
127979                 event.trigger("WiFiHardwareStatusChanged", [setting]);
127980             }
127981         }
127982     },
127983     "WiFiNetwork": {
127984         "ssid": {
127985             "name": "SSID",
127986             "control": {
127987                 "type": "text",
127988                 "value": "OfficeWLAN"
127989             },
127990             "event": "WiFiHardwareSsidChanged",
127991             "callback": function (setting) {
127992                 event.trigger("WiFiHardwareSsidChanged", [setting]);
127993             }
127994         }, 
127995         "signalStrength": {
127996             "name": "Signal Strength",
127997             "control": {
127998                 "type": "select",
127999                 "value": 10
128000             },
128001             "options": (function () {
128002                 var i,
128003                     optionList = {};
128004
128005                 for (i = 0; i <= 10; i++) {
128006                     optionList[i] = i;
128007                 }
128008
128009                 return optionList;
128010             }()),
128011             "event": "WiFiHardwareSignalStrengthChanged",
128012             "callback": function (setting) {
128013                 event.trigger("WiFiHardwareSignalStrengthChanged", [setting]);
128014             }
128015         }, 
128016         "networkStatus": {
128017             "name": "Network Status",
128018             "control": {
128019                 "type": "checkbox",
128020                 "value": true
128021             },
128022             "event": "WiFiHardwareNetworkStatusChanged",
128023             "callback": function (setting) {
128024                 event.trigger("WiFiHardwareNetworkStatusChanged", [setting]);
128025             }
128026         }
128027     }
128028 };
128029
128030
128031 });
128032 define('ripple/platform/wac/2.0/spec/ui', function (require, exports, module) {
128033 /*
128034  *  Copyright 2011 Intel Corporation.
128035  *
128036  * Licensed under the Apache License, Version 2.0 (the "License");
128037  * you may not use this file except in compliance with the License.
128038  * You may obtain a copy of the License at
128039  *
128040  * http://www.apache.org/licenses/LICENSE-2.0
128041  *
128042  * Unless required by applicable law or agreed to in writing, software
128043  * distributed under the License is distributed on an "AS IS" BASIS,
128044  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128045  * See the License for the specific language governing permissions and
128046  * limitations under the License.
128047  */
128048 module.exports = {
128049     plugins: [
128050         "accelerometer",
128051         "messaging",
128052         "geoView",
128053         "widgetConfig",
128054         "deviceSettings"
128055     ]
128056 };
128057
128058 });
128059 define('ripple/platform/wac/2.0/spec', function (require, exports, module) {
128060 /*
128061  *  Copyright 2011 Intel Corporation.
128062  *
128063  * Licensed under the Apache License, Version 2.0 (the "License");
128064  * you may not use this file except in compliance with the License.
128065  * You may obtain a copy of the License at
128066  *
128067  * http://www.apache.org/licenses/LICENSE-2.0
128068  *
128069  * Unless required by applicable law or agreed to in writing, software
128070  * distributed under the License is distributed on an "AS IS" BASIS,
128071  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128072  * See the License for the specific language governing permissions and
128073  * limitations under the License.
128074  */
128075
128076 module.exports = {
128077
128078     id: "wac",
128079     version: "2.0",
128080     name: "WAC",
128081
128082     persistencePrefix: "wac2-",
128083
128084     config: require('ripple/platform/wac/2.0/spec/config'),
128085     ui: require('ripple/platform/wac/2.0/spec/ui'),
128086     device: require('ripple/platform/wac/2.0/spec/device'),
128087
128088     objects: {
128089         Coordinates: {
128090             path: "w3c/1.0/Coordinates"
128091         },
128092         Position: {
128093             path: "w3c/1.0/Position"
128094         },
128095         PositionError: {
128096             path: "w3c/1.0/PositionError"
128097         },
128098         navigator: {
128099             path: "w3c/1.0/navigator",
128100             children: {
128101                 geolocation: {
128102                     path: "wac/2.0/geolocation",
128103                     feature: "http://www.w3.org/TR/geolocation-API/"
128104                 }
128105             }
128106         },
128107         deviceapis: {
128108             path: "wac/2.0/deviceapis",
128109             feature: "http://wacapps.net/api/deviceapis",
128110             /*
128111              * Before we inject those cloned objects into the simulated application
128112              * namespace, we will handle the feature requests from config.xml.
128113              * Especially for:
128114              * - camera.show, camera.capture
128115              * - devicestatus.deviceinfo, devicestatus.networkinfo
128116              * - filesystem.read, filesystem.write
128117              * - messaging.send, messaging.find, messaging.subscribe, messaging.write
128118              * - pim
128119              *  - contact.read, contact.write
128120              *  - calendar.read, calendar.write
128121              *  - task.read, task.write
128122              */
128123             children: {
128124                 accelerometer: {
128125                     path: "wac/2.0/accelerometer",
128126                     feature: "http://wacapps.net/api/accelerometer"
128127                 },
128128                 orientation: {
128129                     path: "wac/2.0/orientation",
128130                     feature: "http://wacapps.net/api/orientation"
128131                 },
128132                 camera: {
128133                     path: "wac/2.0/camera",
128134                     feature: "http://wacapps.net/api/camera|http://wacapps.net/api/camera.show|http://wacapps.net/api/camera.capture",
128135                     handleSubfeatures: true
128136                 },
128137                 devicestatus: {
128138                     path: "wac/2.0/devicestatus",
128139                     feature: "http://wacapps.net/api/devicestatus|http://wacapps.net/api/devicestatus.deviceinfo|http://wacapps.net/api/devicestatus.networkinfo",
128140                     handleSubfeatures: true
128141                 },
128142                 filesystem: {
128143                     path: "wac/2.0/filesystem",
128144                     feature: "http://wacapps.net/api/filesystem|http://wacapps.net/api/filesystem.read|http://wacapps.net/api/filesystem.write",
128145                     handleSubfeatures: true
128146                 },
128147                 messaging: {
128148                     path: "wac/2.0/messaging",
128149                     feature: "http://wacapps.net/api/messaging|http://wacapps.net/api/messaging.send|http://wacapps.net/api/messaging.find|http://wacapps.net/api/messaging.subscribe|http://wacapps.net/api/messaging.write",
128150                     handleSubfeatures: true
128151                 },
128152                 pim: {
128153                     children: {
128154                         contact: {
128155                             path: "wac/2.0/contact",
128156                             feature: "http://wacapps.net/api/pim.contact|http://wacapps.net/api/pim.contact.read|http://wacapps.net/api/pim.contact.write",
128157                             handleSubfeatures: true
128158                         },
128159                         calendar: {
128160                             path: "wac/2.0/calendar",
128161                             feature: "http://wacapps.net/api/pim.calendar.write|http://wacapps.net/api/pim.calendar.read|http://wacapps.net/api/pim.calendar",
128162                             handleSubfeatures: true
128163                         },
128164                         task: {
128165                             path: "wac/2.0/task",
128166                             feature: "http://wacapps.net/api/pim.task|http://wacapps.net/api/pim.task.read|http://wacapps.net/api/pim.task.write",
128167                             handleSubfeatures: true
128168                         }
128169                     }
128170                 },
128171                 deviceinteraction: {
128172                     path: "wac/2.0/deviceinteraction",
128173                     feature: "http://wacapps.net/api/deviceinteraction"
128174                 }
128175             }
128176         }
128177     }
128178 };
128179
128180
128181 });
128182 define('ripple/platform/wac/2.0/task', function (require, exports, module) {
128183 /*
128184  *  Copyright 2011 Intel Corporation.
128185  *
128186  * Licensed under the Apache License, Version 2.0 (the "License");
128187  * you may not use this file except in compliance with the License.
128188  * You may obtain a copy of the License at
128189  *
128190  * http://www.apache.org/licenses/LICENSE-2.0
128191  *
128192  * Unless required by applicable law or agreed to in writing, software
128193  * distributed under the License is distributed on an "AS IS" BASIS,
128194  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128195  * See the License for the specific language governing permissions and
128196  * limitations under the License.
128197  */
128198
128199 var db = require('ripple/db'),
128200     utils = require('ripple/utils'),
128201     _console = require('ripple/console'),
128202     exception = require('ripple/exception'),
128203     errorcode = require('ripple/platform/wac/2.0/errorcode'),
128204     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
128205     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
128206     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
128207     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
128208     Task, TaskList, _get,
128209     _ID_WITHOUT = 0, _ID_GEN_NEW = 1, _ID_FROM_PROP = 2,
128210     _SIM_TASK_LIST = 0, _DEVICE_TASK_LIST = 1,
128211     _HIGH_PRIORITY = 0, _MEDIUM_PRIORITY = 1, _LOW_PRIORITY = 2,
128212     _STATUS_COMPLETED = 0, _STATUS_NEEDS_ACTION = 1, _STATUS_IN_PROCESS = 2, _STATUS_CANCELLED = 3,
128213     _TASK_OBJECTS = "wac2.0-pim-task-objects",
128214     _addTaskAllowed = true, _deleteTaskAllowed = true,
128215     _updateTaskAllowed = true, _findTasksAllowed = true;
128216
128217
128218 module.exports = function () {
128219     var _taskListArray = [],
128220         _PENDING_TIME = 10;
128221
128222     function _pendingOperate(operate) {
128223         var pendingObj, pendingOperation, i, argumentVector = [];
128224
128225         for (i = 0; i < arguments.length - 1; i++)
128226             argumentVector[i] = arguments[i + 1];
128227
128228         pendingObj = new PendingObject();
128229
128230         pendingObj.pendingID = window.setTimeout(function () {
128231             pendingObj.setCancelFlag(false);
128232             operate.apply(this, argumentVector);
128233         }, _PENDING_TIME);
128234
128235         pendingOperation = new PendingOperation(pendingObj);
128236
128237         return pendingOperation;
128238     }
128239
128240     /* taskProperties attribute check & paste */
128241     function _checkAndPasteProperties(p, dst) {
128242
128243         if (p.summary !== null && p.summary !== undefined)
128244             dst.summary = String(p.summary);
128245
128246         if (p.description !== null && p.description !== undefined)
128247             dst.description = String(p.description);
128248
128249         if (p.status !== null && p.status !== undefined) {
128250             if (p.status === _STATUS_COMPLETED ||
128251                 p.status === _STATUS_NEEDS_ACTION ||
128252                 p.status === _STATUS_IN_PROCESS ||
128253                 p.status === _STATUS_CANCELLED) {
128254                 dst.status = p.status;
128255             } else
128256                 return false;
128257         }
128258
128259         if (p.priority !== null && p.priority !== undefined) {
128260             if (p.priority === _HIGH_PRIORITY ||
128261                 p.priority === _MEDIUM_PRIORITY ||
128262                 p.priority === _LOW_PRIORITY) {
128263                 dst.priority = p.priority;
128264             } else
128265                 return false;
128266         }
128267
128268         if (p.dueDate !== null && p.dueDate !== undefined) {
128269             if (!wac2_utils.isValidDate(p.dueDate))
128270                 return false;
128271             dst.dueDate = new Date(p.dueDate);
128272         }
128273
128274         /* dueDate is a option properties.
128275            "The default value is undefined.
128276              If no value is provided, the task has no due date."
128277            If p.dueDate is set its default value 'undefined',
128278            we assign default value to dst.dueDate */
128279         if (p.dueDate === undefined) {
128280             dst.dueDate = undefined;
128281         }
128282
128283         return true;
128284     }
128285
128286     function _taskFilterCheck(filter) {
128287         var i;
128288         if (filter.id !== undefined && filter.id !== null) {
128289             filter.id = String(filter.id);
128290         } else {
128291             filter.id = undefined;
128292         }
128293         if (filter.summary !== undefined && filter.summary !== null) {
128294             filter.summary = String(filter.summary);
128295         } else {
128296             filter.summary = undefined;
128297         }
128298         if (filter.description !== undefined && filter.description !== null) {
128299             filter.description = String(filter.description);
128300         } else {
128301             filter.description = undefined;
128302         }
128303         if (filter.status !== undefined && filter.status !== null) {
128304             if (!wac2_utils.isValidArray(filter.status))  {
128305                 return false;
128306             }
128307             for (i = 0; i < filter.status.length; i++) {
128308                 filter.status[i] = filter.status[i] | 0;
128309                 if (filter.status[i] !== _STATUS_COMPLETED &&
128310                     filter.status[i] !== _STATUS_NEEDS_ACTION &&
128311                     filter.status[i] !== _STATUS_IN_PROCESS &&
128312                     filter.status[i] !== _STATUS_CANCELLED) {
128313                     return false;
128314                 }
128315             }
128316         } else {
128317             filter.status = undefined;
128318         }
128319         if (filter.priority !== undefined && filter.priority !== null) {
128320             if (!wac2_utils.isValidArray(filter.priority))  {
128321                 return false;
128322             }
128323             for (i = 0; i < filter.priority.length; i++) {
128324                 filter.priority[i] = filter.priority[i] | 0;
128325                 if (filter.priority[i] !== _HIGH_PRIORITY &&
128326                     filter.priority[i] !== _MEDIUM_PRIORITY &&
128327                     filter.priority[i] !== _LOW_PRIORITY) {
128328                     return false;
128329                 }
128330             }
128331         } else {
128332             filter.priority = undefined;
128333         }
128334         if (filter.dueDate !== undefined && filter.dueDate !== null) {
128335             if (!wac2_utils.isValidDate(filter.dueDate)) {
128336                 return false;
128337             }
128338             filter.dueDate = new Date(filter.dueDate);
128339         } else {
128340             filter.dueDate = undefined;
128341         }
128342         return true;
128343     }
128344
128345     function TaskProperties(prop) {
128346         var _self;
128347         _self = {
128348             priority : _LOW_PRIORITY,
128349             description : "",
128350             summary : "",
128351             dueDate : undefined,
128352             status : _STATUS_NEEDS_ACTION
128353         };
128354         if (prop) {
128355             if (_checkAndPasteProperties(prop, _self) === false)
128356                 return undefined;
128357         }
128358         return _self;
128359     }
128360
128361     function Task(prop, idChoice) {
128362         var id, _self = new TaskProperties(prop);
128363         /* if error occurs during checking, _self is an empty object.
128364            so i randomly pick description to check if property check fails */
128365         if (_self.description === undefined)
128366             return undefined;
128367
128368         switch (idChoice) {
128369         case _ID_WITHOUT:
128370             // do nothing
128371             break;
128372         case _ID_GEN_NEW:
128373             id = Math.uuid(undefined, 16);
128374             _self.__defineGetter__("id", function () {
128375                 return id;
128376             });
128377             break;
128378         case _ID_FROM_PROP:
128379             id = String(prop.id);
128380             _self.__defineGetter__("id", function () {
128381                 return id;
128382             });
128383             break;
128384         }
128385
128386         return _self;
128387     }
128388
128389     function _get() {
128390         var taskListArray = [],
128391             data = db.retrieveObject(_TASK_OBJECTS);
128392         utils.forEach(data, function (taskList) {
128393             for (var t in taskList._list) {
128394                 if (taskList._list[t].dueDate !== undefined &&
128395                     taskList._list[t].dueDate !== null)
128396                     taskList._list[t].dueDate = new Date(taskList._list[t].dueDate);
128397             }
128398             taskListArray.push(new TaskList(taskList._list, taskList.type, taskList.name));
128399         });
128400
128401         /* add default taskList if taskListArray is empty */
128402         if (taskListArray.length === 0) {
128403             taskListArray = [new TaskList({}, 0, "Office tasks"), new TaskList({}, 1, "Home tasks")];
128404         }
128405
128406         return taskListArray;
128407     }
128408
128409     function _save() {
128410         db.saveObject(_TASK_OBJECTS, _taskListArray);
128411     }
128412
128413     function TaskList(taskList, type, name) {
128414         var task;
128415         this._list = taskList;
128416         this.type = type;
128417         this.name = name;
128418
128419         this.createTask = function (properties) {
128420             task = new Task(properties, _ID_WITHOUT);
128421             /* if error occurs during checking, task is an empty object.
128422                so i randomly pick summary to check if property check fails */
128423             if (task.summary === undefined) {
128424                 exception.raise(exception.types.Argument,
128425                         "EventProperties: input parameter contains invalid values",
128426                         new DeviceApiError(errorcode.INVALID_VALUES_ERR));
128427                 return undefined;
128428             }
128429             return task;
128430         };
128431
128432         this.addTask = function (onSuccess, onError, task) {
128433             var inner = this,
128434                 newTask, _task = Object(task);
128435             function _addTask() {
128436                 var ret;
128437                 if (!_addTaskAllowed) {
128438                     if (onError) {
128439                         setTimeout(function () {
128440                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
128441                         }, 1);
128442                     }
128443                     return undefined;
128444                 }
128445                 newTask = new Task(_task, _ID_GEN_NEW);
128446                 /* if error occurs during checking, newTask is an empty object.
128447                     so i randomly pick id to check if property check fails */
128448                 if (newTask.id === undefined) {
128449                     if (onError) {
128450                         setTimeout(function () {
128451                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
128452                         }, 1);
128453                     }
128454                     return undefined;
128455                 }
128456                 ret = _pendingOperate(function () {
128457                     inner._list[newTask.id] = newTask;
128458                     _save();
128459                     onSuccess(new Task(newTask, _ID_FROM_PROP));
128460                 });
128461             }
128462
128463             return wac2_utils.validateTypeMismatch(onSuccess, onError, "addTask", _addTask);
128464         };
128465
128466         this.updateTask = function (onSuccess, onError, task) {
128467             var inner = this,
128468                 newTask, _task = Object(task);
128469             function _updateTask() {
128470                 var ret;
128471                 if (!_updateTaskAllowed) {
128472                     if (onError) {
128473                         setTimeout(function () {
128474                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
128475                         }, 1);
128476                     }
128477                     return undefined;
128478                 }
128479
128480                 if (_checkAndPasteProperties(_task, _task) === false) {
128481                     if (onError) {
128482                         setTimeout(function () {
128483                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
128484                         }, 1);
128485                     }
128486                     return undefined;
128487                 }
128488
128489                 ret = _pendingOperate(function () {
128490                     if (inner._list[_task.id]) {
128491                         newTask = new Task(inner._list[_task.id], _ID_FROM_PROP);
128492                         /* Don't need to double check the return of _checkAndPasteProperties 
128493                            _task has been checked & pasted already */
128494                         _checkAndPasteProperties(_task, newTask);
128495                         inner._list[newTask.id] = newTask;
128496                         _save();
128497                         onSuccess();
128498                     } else {
128499                         if (onError) {
128500                             onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
128501                         }
128502                     }
128503                 });
128504                 return ret;
128505             }
128506
128507             return wac2_utils.validateTypeMismatch(onSuccess, onError, "updateTask", _updateTask);
128508         };
128509
128510         this.deleteTask = function (onSuccess, onError, id) {
128511             var inner = this;
128512             function _deleteTask() {
128513                 var ret;
128514                 /* according to spec  "If any of the input parameters are not 
128515                    compatible with the expected type for that parameter, 
128516                    a DeviceAPIError with code TYPE_MISMATCH_ERR MUST be 
128517                    synchronously thrown." so an error is raised synchronously */
128518                 utils.validateArgumentType(id, "string", null,
128519                         "Task:deleteTask: " + " invalid id parameter",
128520                         new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
128521                 if (!_deleteTaskAllowed) {
128522                     if (onError) {
128523                         setTimeout(function () {
128524                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
128525                         }, 1);
128526                     }
128527                     return undefined;
128528                 }
128529                 ret = _pendingOperate(function () {
128530                     if (inner._list[id]) {
128531                         delete inner._list[id];
128532                         _save();
128533                         onSuccess();
128534                     } else {
128535                         if (onError)
128536                             onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
128537                     }
128538                 });
128539                 return ret;
128540             }
128541
128542             return wac2_utils.validateTypeMismatch(onSuccess, onError, "deleteTask", _deleteTask);
128543         };
128544
128545         this.findTasks = function (onSuccess, onError, filter) {
128546             var inner = this, _filter = Object(filter), tmp = [], rst = [], valid_tmp = false;
128547             function _findTasks() {
128548                 var ret;
128549                 if (!_taskFilterCheck(_filter)) {
128550                     if (onError) {
128551                         setTimeout(function () {
128552                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
128553                         }, 1);
128554                     }
128555                     return undefined;
128556                 }
128557                 if (!_findTasksAllowed) {
128558                     if (onError) {
128559                         setTimeout(function () {
128560                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
128561                         }, 1);
128562                     }
128563                     return undefined;
128564                 }
128565                 ret = _pendingOperate(function () {
128566                     var i, e;
128567                     if (_filter.id !== undefined) {
128568                         tmp = wac2_utils.matchOptionString(inner._list, "id", _filter.id);
128569                         valid_tmp = true;
128570                     }
128571                     if (_filter.summary !== undefined) {
128572                         if (valid_tmp) {
128573                             tmp = wac2_utils.matchOptionString(tmp, "summary", _filter.summary);
128574                         } else {
128575                             tmp = wac2_utils.matchOptionString(inner._list, "summary", _filter.summary);
128576                             valid_tmp = true;
128577                         }
128578                     }
128579                     if (_filter.description !== undefined) {
128580                         if (valid_tmp) {
128581                             tmp = wac2_utils.matchOptionString(tmp, "description", _filter.description);
128582                         } else {
128583                             tmp = wac2_utils.matchOptionString(inner._list, "description", _filter.description);
128584                             valid_tmp = true;
128585                         }
128586                     }
128587                     if (_filter.status !== undefined) {
128588                         if (valid_tmp) {
128589                             tmp = wac2_utils.matchOptionShortArray(tmp, "status", _filter.status);
128590                         } else {
128591                             tmp = wac2_utils.matchOptionShortArray(inner._list, "status", _filter.status);
128592                             valid_tmp = true;
128593                         }
128594                     }
128595                     if (_filter.priority !== undefined) {
128596                         if (valid_tmp) {
128597                             tmp = wac2_utils.matchOptionShortArray(tmp, "priority", _filter.priority);
128598                         } else {
128599                             tmp = wac2_utils.matchOptionShortArray(inner._list, "priority", _filter.priority);
128600                             valid_tmp = true;
128601                         }
128602                     }
128603                     if (_filter.initialDueDate !== undefined ||
128604                         _filter.endDueDate !== undefined) {
128605                         if (valid_tmp) {
128606                             tmp = wac2_utils.matchOptionDate(tmp, "dueDate", _filter.initialDueDate, _filter.endDueDate);
128607                         } else {
128608                             tmp = wac2_utils.matchOptionDate(inner._list, "dueDate", _filter.initialDueDate, _filter.endDueDate);
128609                             valid_tmp = true;
128610                         }
128611                     }
128612
128613                     if (valid_tmp) {
128614                         for (i = 0; i < tmp.length; i++) {
128615                             rst.push(new Task(tmp[i], _ID_FROM_PROP));
128616                         } 
128617                     } else {
128618                         for (e in inner._list) {
128619                             rst.push(new Task(inner._list[e], _ID_FROM_PROP));
128620                         }
128621                     }
128622                     onSuccess(rst);
128623                 });
128624                 return ret;
128625             }
128626
128627             return wac2_utils.validateTypeMismatch(onSuccess, onError, "findTasks", _findTasks);
128628         };
128629     }
128630
128631     this.getTaskLists = function (onSuccess, onError) {
128632         function _getTaskLists() {
128633             var ret;
128634             ret = _pendingOperate(function () {
128635                 if (_taskListArray.length === 0) {
128636                     _taskListArray = _get();
128637                 }
128638                 onSuccess(_taskListArray);
128639             }, 1);
128640             return ret;
128641         }
128642
128643         return wac2_utils.validateTypeMismatch(onSuccess, onError, "getTaskLists", _getTaskLists);
128644     };
128645
128646     this.__defineGetter__("SIM_TASK_LIST", function () {
128647         return 0;
128648     });
128649     this.__defineGetter__("DEVICE_TASK_LIST", function () {
128650         return 1;
128651     });
128652     this.__defineGetter__("HIGH_PRIORITY", function () {
128653         return 0;
128654     });
128655     this.__defineGetter__("MEDIUM_PRIORITY", function () {
128656         return 1;
128657     });
128658     this.__defineGetter__("LOW_PRIORITY", function () {
128659         return 2;
128660     });
128661     this.__defineGetter__("STATUS_COMPLETED", function () {
128662         return 0;
128663     });
128664     this.__defineGetter__("STATUS_NEEDS_ACTION", function () {
128665         return 1;
128666     });
128667     this.__defineGetter__("STATUS_IN_PROCESS", function () {
128668         return 2;
128669     });
128670     this.__defineGetter__("STATUS_CANCELLED", function () {
128671         return 3;
128672     });
128673
128674     this.handleSubFeatures = function (subFeatures) {
128675         if (wac2_utils.isEmptyObject(subFeatures) ||
128676             subFeatures["http://wacapps.net/api/pim.task"] ||
128677             (subFeatures["http://wacapps.net/api/pim.task.read"] &&
128678             subFeatures["http://wacapps.net/api/pim.task.write"])) {
128679             return;
128680         }
128681         if (subFeatures["http://wacapps.net/api/pim.task.read"] &&
128682            !subFeatures["http://wacapps.net/api/pim.task.write"]) {
128683             _addTaskAllowed = false;
128684             _deleteTaskAllowed = false;
128685             _updateTaskAllowed = false;
128686             return;
128687         }
128688         if (subFeatures["http://wacapps.net/api/pim.task.write"] &&
128689            !subFeatures["http://wacapps.net/api/pim.task.read"]) {
128690             _findTasksAllowed = false;
128691             return;
128692         }
128693         _console.warn("WAC-2.0-Task-handleSubFeatures: something wrong");
128694     };
128695
128696 };
128697
128698
128699 });
128700 define('ripple/platform/wac/2.0/typecoerce', function (require, exports, module) {
128701 /*\r
128702  *  Copyright 2011 Intel Corporation.\r
128703  *\r
128704  * Licensed under the Apache License, Version 2.0 (the "License");\r
128705  * you may not use this file except in compliance with the License.\r
128706  * You may obtain a copy of the License at\r
128707  *\r
128708  * http://www.apache.org/licenses/LICENSE-2.0\r
128709  *\r
128710  * Unless required by applicable law or agreed to in writing, software\r
128711  * distributed under the License is distributed on an "AS IS" BASIS,\r
128712  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
128713  * See the License for the specific language governing permissions and\r
128714  * limitations under the License.\r
128715  */\r
128716 \r
128717 var utils = require('ripple/utils'),\r
128718     _self;\r
128719 \r
128720 _self = function (pattern) {\r
128721     var typeCoerce,\r
128722         typeOfPattern = Object.prototype.toString.call(pattern);\r
128723 \r
128724     typeCoerce = {\r
128725         cast: function (obj) {\r
128726             var validObj,\r
128727                 validValue,\r
128728                 elementType,\r
128729                 typeOfObj = Object.prototype.toString.call(obj);\r
128730 \r
128731             switch (typeOfPattern) {\r
128732             case "[object String]":\r
128733                 validObj = (typeOfObj !== typeOfPattern) ? String(obj) : obj;\r
128734                 break;\r
128735 \r
128736             case "[object Number]":\r
128737                 validObj = (typeOfObj !== typeOfPattern) ? (Number(obj) | 0) : obj;\r
128738                 break;\r
128739 \r
128740             case "[object Object]":\r
128741                 if (typeOfObj !== typeOfPattern) {\r
128742                     validObj = {};\r
128743                 } else {\r
128744                     validObj = obj;\r
128745                     utils.forEach(validObj, function (value, key) {\r
128746                         if (pattern[key] === undefined) {\r
128747                             delete validObj[key];\r
128748                         } else {\r
128749                             validValue = _self(pattern[key]).cast(value);\r
128750                             if (validObj[key] !== validValue)\r
128751                                 validObj[key] = validValue;\r
128752                         }\r
128753                     });\r
128754                 }\r
128755                 break;\r
128756 \r
128757             case "[object Array]":\r
128758                 if (typeOfObj !== typeOfPattern) {\r
128759                     validObj = [];\r
128760                 } else {\r
128761                     validObj = obj;\r
128762                     elementType = _self(pattern[0]);\r
128763                     utils.forEach(validObj, function (element, index) {\r
128764                         validObj[index] = elementType.cast(element);\r
128765                     });\r
128766                 }\r
128767                 break;\r
128768             }\r
128769 \r
128770             return validObj;\r
128771         }\r
128772     };\r
128773 \r
128774     return typeCoerce;\r
128775 };\r
128776 \r
128777 module.exports = _self;\r
128778
128779 });
128780 define('ripple/platform/wac/2.0/wac2_utils', function (require, exports, module) {
128781 /*
128782  *  Copyright 2011 Intel Corporation.
128783  *
128784  * Licensed under the Apache License, Version 2.0 (the "License");
128785  * you may not use this file except in compliance with the License.
128786  * You may obtain a copy of the License at
128787  *
128788  * http://www.apache.org/licenses/LICENSE-2.0
128789  *
128790  * Unless required by applicable law or agreed to in writing, software
128791  * distributed under the License is distributed on an "AS IS" BASIS,
128792  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128793  * See the License for the specific language governing permissions and
128794  * limitations under the License.
128795  */
128796
128797 var utils = require('ripple/utils'),
128798     errorcode = require('ripple/platform/wac/2.0/errorcode'),
128799     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror');
128800
128801 module.exports = {
128802     _wac2_regexSanitize: function (regexString) {
128803         var escapePattern = /([^\\]|^)(%)/g, percentPattern = /\\%/g;
128804         return regexString.replace("^", "\\^")
128805                 .replace("$", "\\$")
128806                 .replace("(", "\\(")
128807                 .replace(")", "\\)")
128808                 .replace("<", "\\<")
128809                 .replace("[", "\\[")
128810                 .replace("{", "\\{")
128811                 .replace(/\\([^%])/, "\\\\$1")    /* don't replace \\% */
128812                 .replace("|", "\\|")
128813                 .replace(">", "\\>")
128814                 .replace(".", "\\.")
128815                 .replace("*", "\\*")
128816                 .replace("+", "\\+")
128817                 .replace("?", "\\?")
128818                 .replace(escapePattern, "$1.*")  /* replace % with .* */
128819                 .replace(percentPattern, "%");   /* strip excape of % */ 
128820     }, 
128821
128822     isValidDate: function (d) {
128823         if (Object.prototype.toString.call(d) !== "[object Date]")
128824             return false;
128825         return !isNaN(d.getTime());
128826     },
128827
128828     isValidArray: function (a) {
128829         return (Object.prototype.toString.call(a) === "[object Array]");
128830     },
128831     
128832     matchOptionArrayString: function (src, attr, pattern) {
128833         /* src.obj[attr] is a StringArray */
128834         var _pattern, re, _stringMatch;
128835         _pattern = this._wac2_regexSanitize(pattern); 
128836         re = new RegExp("^" + _pattern + "$", "i");
128837
128838         _stringMatch = function (obj, index) {
128839             if (pattern.search(/^%*$/i) === 0) 
128840                 return true;
128841             if (obj[attr] === undefined || obj[attr] === null)
128842                 return false;
128843             return obj[attr].some(function (f) {
128844                 return f.search(re) !== -1;
128845             });
128846         };
128847         return utils.filter(src, _stringMatch);
128848     },
128849
128850     matchOptionString: function (src, attr, pattern) {
128851         /* src.obj[attr] is a string */
128852         var _stringMatch, _pattern, _re;
128853         _pattern = this._wac2_regexSanitize(pattern); 
128854         _re = new RegExp("^" + _pattern + "$", "mi");
128855
128856         _stringMatch = function (obj, index) {
128857             return (obj[attr].search(_re) !== -1);
128858         };
128859         return utils.filter(src, _stringMatch);
128860     },
128861
128862     matchOptionDate: function (src, attr, filterStart, filterEnd) {
128863         var _dateMatch;
128864         _dateMatch = function (obj, index) {
128865             var matched = true, valueDate = obj[attr];
128866     
128867             if (filterStart !== undefined && filterStart !== null) {
128868                 matched = (valueDate.getTime() >= filterStart.getTime());
128869             }
128870             if (matched && (filterEnd !== undefined && filterEnd !== null)) {
128871                 matched = (valueDate.getTime() <= filterEnd.getTime());
128872             }
128873             return matched;
128874         };
128875         return utils.filter(src, _dateMatch);
128876     },
128877
128878     matchOptionShortArray: function (src, attr, filterArray) {
128879         /* src.obj[attr] is a short, filterArray is an array 
128880            i.e. find status is [CONFRIMED or TENTATIVE] */
128881         var arraySome = function (obj, index) {
128882             return filterArray.some(function (f) {
128883                 return f === obj[attr];  
128884             });
128885         };
128886         return utils.filter(src, arraySome);
128887     },
128888
128889     validateTypeMismatch: function (onSuccess, onError, name, callback) {
128890         if (onSuccess) {
128891             utils.validateArgumentType(onSuccess, "function", null,
128892                                        name + " invalid successCallback parameter",
128893                                        new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
128894         }
128895
128896         if (onError) {
128897             utils.validateArgumentType(onError, "function", null,
128898                                        name + " invalid errorCallback parameter",
128899                                        new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
128900         }
128901
128902         if (onSuccess) {
128903             return callback && callback();
128904         } else {
128905             if (onError) {
128906                 setTimeout(function () {
128907                     onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
128908                 }, 1);
128909             }
128910         }
128911         return undefined;
128912     },
128913
128914     isEmptyObject: function (obj) {
128915         var prop;
128916
128917         for (prop in obj) {
128918             return false;
128919         }
128920         return true;
128921     }
128922 };
128923
128924
128925 });
128926 define('ripple/platform/web/default/device', function (require, exports, module) {
128927 /*
128928  *  Copyright 2011 Research In Motion Limited.
128929  *
128930  * Licensed under the Apache License, Version 2.0 (the "License");
128931  * you may not use this file except in compliance with the License.
128932  * You may obtain a copy of the License at
128933  *
128934  * http://www.apache.org/licenses/LICENSE-2.0
128935  *
128936  * Unless required by applicable law or agreed to in writing, software
128937  * distributed under the License is distributed on an "AS IS" BASIS,
128938  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128939  * See the License for the specific language governing permissions and
128940  * limitations under the License.
128941  */
128942 window.addEventListener("load", function () {
128943     var event = require('ripple/event');
128944
128945     event.on("HardwareKey", function (key) {
128946         event.trigger("HardwareKeyDefault", [key]);
128947     });
128948
128949     //HACK: Remove this guy from namespace since we are just hacking this in as a bootstrapper
128950     delete window.device;
128951 });
128952
128953 });
128954 define('ripple/platform/web/default/spec/ui', function (require, exports, module) {
128955 module.exports = {
128956     plugins: [
128957         "accelerometer",
128958         "geoView"
128959     ]
128960 };
128961
128962 });
128963 define('ripple/platform/web/default/spec', function (require, exports, module) {
128964 /*
128965  *  Copyright 2011 Research In Motion Limited.
128966  *
128967  * Licensed under the Apache License, Version 2.0 (the "License");
128968  * you may not use this file except in compliance with the License.
128969  * You may obtain a copy of the License at
128970  *
128971  * http://www.apache.org/licenses/LICENSE-2.0
128972  *
128973  * Unless required by applicable law or agreed to in writing, software
128974  * distributed under the License is distributed on an "AS IS" BASIS,
128975  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128976  * See the License for the specific language governing permissions and
128977  * limitations under the License.
128978  */
128979
128980 module.exports = {
128981
128982     id: "web",
128983     version: "default",
128984     name: "Mobile Web",
128985
128986     ui: require('ripple/platform/web/default/spec/ui'),
128987     device: {},
128988
128989     persistencePrefix: "tinyhippos-",
128990
128991     initialize: function () {},
128992
128993     objects: {
128994         Coordinates: {
128995             path: "w3c/1.0/Coordinates"
128996         },
128997         Position: {
128998             path: "w3c/1.0/Position"
128999         },
129000         PositionError: {
129001             path: "w3c/1.0/PositionError"
129002         },
129003         navigator: {
129004             path: "w3c/1.0/navigator",
129005             children: {
129006                 geolocation: {
129007                     path: "w3c/1.0/geolocation"
129008                 }
129009             }
129010         },
129011         device: {
129012             path: "web/default/device"
129013         }
129014     },
129015 };
129016
129017 });
129018 define('ripple/platform/webworks.bb10/1.0.0/app', function (require, exports, module) {
129019 /*
129020  *  Copyright 2011 Research In Motion Limited.
129021  *
129022  * Licensed under the Apache License, Version 2.0 (the "License");
129023  * you may not use this file except in compliance with the License.
129024  * You may obtain a copy of the License at
129025  *
129026  * http://www.apache.org/licenses/LICENSE-2.0
129027  *
129028  * Unless required by applicable law or agreed to in writing, software
129029  * distributed under the License is distributed on an "AS IS" BASIS,
129030  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129031  * See the License for the specific language governing permissions and
129032  * limitations under the License.
129033  */
129034 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
129035     app = require('ripple/app'),
129036     notifications = require('ripple/notifications'),
129037     _uri = "blackberry/app/",
129038     _self;
129039
129040 _self = {
129041     exit: function () {
129042         notifications.openNotification("normal", "blackberry.app.exit() was called, in the real world your app will exit, here... you get this notification");
129043     }
129044 };
129045
129046 _self.__defineGetter__("author", function () {
129047     return app.getInfo().author;
129048 });
129049
129050 _self.__defineGetter__("authorEmail", function () {
129051     return app.getInfo().authorEmail;
129052 });
129053
129054 _self.__defineGetter__("authorURL", function () {
129055     return app.getInfo().authorURL;
129056 });
129057
129058 _self.__defineGetter__("copyright", function () {
129059     return app.getInfo().copyright;
129060 });
129061
129062 _self.__defineGetter__("description", function () {
129063     return app.getInfo().description;
129064 });
129065
129066 _self.__defineGetter__("id", function () {
129067     return app.getInfo().id;
129068 });
129069
129070 _self.__defineGetter__("license", function () {
129071     return app.getInfo().license;
129072 });
129073
129074 _self.__defineGetter__("licenseURL", function () {
129075     return app.getInfo().licenseURL;
129076 });
129077
129078 _self.__defineGetter__("name", function () {
129079     return app.getInfo().name;
129080 });
129081
129082 _self.__defineGetter__("version", function () {
129083     return app.getInfo().version;
129084 });
129085
129086 module.exports = _self;
129087
129088 });
129089 define('ripple/platform/webworks.bb10/1.0.0/connection', function (require, exports, module) {
129090 /*
129091  *  Copyright 2011 Research In Motion Limited.
129092  *
129093  * Licensed under the Apache License, Version 2.0 (the "License");
129094  * you may not use this file except in compliance with the License.
129095  * You may obtain a copy of the License at
129096  *
129097  * http://www.apache.org/licenses/LICENSE-2.0
129098  *
129099  * Unless required by applicable law or agreed to in writing, software
129100  * distributed under the License is distributed on an "AS IS" BASIS,
129101  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129102  * See the License for the specific language governing permissions and
129103  * limitations under the License.
129104  */
129105 var deviceSettings = require('ripple/deviceSettings'),
129106     _self = {};
129107
129108 _self.__defineGetter__("type", function () {
129109     return deviceSettings.retrieve("NetworkStatus.connectionType");
129110 });
129111
129112 _self.__defineGetter__("UNKNOWN", function () { return "unknown"; });
129113 _self.__defineGetter__("ETHERNET", function () { return "ethernet"; });
129114 _self.__defineGetter__("WIFI", function () { return "wifi"; });
129115 _self.__defineGetter__("BLUETOOTH_DUN", function () { return "bluetooth_dun"; });
129116 _self.__defineGetter__("USB", function () { return "usb"; });
129117 _self.__defineGetter__("VPN", function () { return "vpn"; });
129118 _self.__defineGetter__("BB", function () { return "rim-bb"; });
129119 _self.__defineGetter__("CELL_2G", function () { return "2g"; });
129120 _self.__defineGetter__("CELL_3G", function () { return "3g"; });
129121 _self.__defineGetter__("CELL_4G", function () { return "4g"; });
129122 _self.__defineGetter__("NONE", function () { return "none"; });
129123
129124 module.exports = _self;
129125
129126 });
129127 define('ripple/platform/webworks.bb10/1.0.0/device', function (require, exports, module) {
129128 /*
129129  *  Copyright 2011 Research In Motion Limited.
129130  *
129131  * Licensed under the Apache License, Version 2.0 (the "License");
129132  * you may not use this file except in compliance with the License.
129133  * You may obtain a copy of the License at
129134  *
129135  * http://www.apache.org/licenses/LICENSE-2.0
129136  *
129137  * Unless required by applicable law or agreed to in writing, software
129138  * distributed under the License is distributed on an "AS IS" BASIS,
129139  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129140  * See the License for the specific language governing permissions and
129141  * limitations under the License.
129142  */
129143 var devices = require('ripple/devices'),
129144     _self = {};
129145
129146 _self.__defineGetter__("softwareVersion", function () {
129147     return devices.getCurrentDevice().osVersion;
129148 });
129149
129150 _self.__defineGetter__("hardwareId", function () {
129151     return devices.getCurrentDevice().hardwareId;
129152 });
129153 module.exports = _self;
129154
129155 });
129156 define('ripple/platform/webworks.bb10/1.0.0/dialog', function (require, exports, module) {
129157 /*
129158  *  Copyright 2011 Research In Motion Limited.
129159  *
129160  * Licensed under the Apache License, Version 2.0 (the "License");
129161  * you may not use this file except in compliance with the License.
129162  * You may obtain a copy of the License at
129163  *
129164  * http://www.apache.org/licenses/LICENSE-2.0
129165  *
129166  * Unless required by applicable law or agreed to in writing, software
129167  * distributed under the License is distributed on an "AS IS" BASIS,
129168  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129169  * See the License for the specific language governing permissions and
129170  * limitations under the License.
129171  */
129172 var _self,
129173     ui = require('ripple/ui'),
129174     event = require('ripple/event'),
129175     isDialogVisible = false,
129176     visibleDialogArgs,
129177     utils = require('ripple/utils');
129178
129179 function getButtonsForDialogType(dialogType) {
129180     switch (dialogType) {
129181     case _self.D_OK:
129182         return ["Ok"];
129183     case _self.D_SAVE:
129184         return ["Save", "Discard"];
129185     case _self.D_DELETE:
129186         return ["Delete", "Cancel"];
129187     case _self.D_YES_NO:
129188         return ["Yes", "No"];
129189     case _self.D_OK_CANCEL:
129190         return ["Ok", "Cancel"];
129191     default:
129192         throw new Error("Invalid dialog type: " + dialogType);
129193     }
129194 }
129195
129196 event.on("LayoutChanged", function () {
129197     if (isDialogVisible) {
129198         closeDialog();
129199         //Used to resize dialog on orientation change
129200         _self.ask(visibleDialogArgs);
129201     }
129202 });
129203
129204 function closeDialog() {
129205     var buttonsDiv = document.getElementById("dialog-buttons"),
129206         messageDiv = document.getElementById("dialog-message");
129207
129208     ui.hideOverlay("dialog-window", function (dialog) {
129209         buttonsDiv.innerHTML = "";
129210         messageDiv.innerHTML = "";
129211         isDialogVisible = false;
129212     });
129213 }
129214
129215 function ask(args, callback) {
129216     if (!args) {
129217         throw ("No arguments provided");
129218     } else if (!args.buttons || !args.message) {
129219         throw ("Invalid arguments");
129220     }
129221     visibleDialogArgs = args;
129222
129223     ui.showOverlay("dialog-window", function (dialog) {
129224         var container = document.getElementById("viewport-container"),
129225             height = window.getComputedStyle(container, null).getPropertyValue("height"),
129226             width = window.getComputedStyle(container, null).getPropertyValue("width"),
129227             sizeDiv = document.getElementById("dialog-wrapper"),
129228             positionDiv = document.getElementById("dialog-window"),
129229             titleDiv = document.getElementById("dialog-title"),
129230             buttonsDiv = document.getElementById("dialog-buttons"),
129231             messageDiv = document.getElementById("dialog-message"),
129232             position, size;
129233
129234         if (!messageDiv || !buttonsDiv) {
129235             return;
129236         }
129237
129238         dialog.setAttribute("style", "display:-webkit-box;height:" + height + "; width:" + width + ";");
129239
129240         position = "overlay-dialog";
129241         size = "overlay-dialog-wrapper";
129242
129243         if (args.settings && args.settings.position) {
129244             position += " overlay-dialog-" + args.settings.position;
129245         }
129246
129247         if (args.settings && args.settings.size) {
129248             size += " overlay-dialog-wrapper-" + args.settings.size;
129249         }
129250
129251         positionDiv.setAttribute("class", position);
129252         sizeDiv.setAttribute("class", size);
129253
129254         titleDiv.innerHTML = args.settings && args.settings.title ? args.settings.title : "";
129255         messageDiv.innerHTML = args.message;
129256         isDialogVisible = true;
129257
129258         args.buttons.forEach(function (button) {
129259             var buttonElement = utils.createElement("input", {
129260                 "type": "button",
129261                 "value": button
129262             });
129263             buttonElement.addEventListener("click", function () {
129264                 var buttonIndex = args.buttons.indexOf(button);
129265                 closeDialog();
129266                 callback(buttonIndex);
129267             });
129268             buttonsDiv.appendChild(buttonElement);
129269         });
129270     }, true);
129271 }
129272
129273 _self = {
129274     customAskAsync: function (message, choices, callback, settings) {
129275         ask({
129276             message: message,
129277             buttons: choices,
129278             settings: settings
129279         }, function (response) {
129280             if (callback) {
129281                 callback(response);
129282             }
129283         });
129284     },
129285
129286     standardAskAsync: function (message, type, callback, settings) {
129287         var choices = getButtonsForDialogType(type);
129288         ask({ 
129289             message: message, 
129290             buttons: choices, 
129291             settings: settings
129292         }, function (response) {
129293             if (callback) {
129294                 callback(response);
129295             }
129296         });
129297     }
129298 };
129299
129300 _self.__defineGetter__("D_OK", function () {
129301     return 0;
129302 });
129303
129304 _self.__defineGetter__("D_SAVE", function () {
129305     return 1;
129306 });
129307
129308 _self.__defineGetter__("D_DELETE", function () {
129309     return 2;
129310 });
129311
129312 _self.__defineGetter__("D_YES_NO", function () {
129313     return 3;
129314 });
129315
129316 _self.__defineGetter__("D_OK_CANCEL", function () {
129317     return 4;
129318 });
129319
129320 _self.__defineGetter__("BOTTOM", function () {
129321     return "bottomCenter";
129322 });
129323
129324 _self.__defineGetter__("CENTER", function () {
129325     return "middleCenter";
129326 });
129327
129328 _self.__defineGetter__("TOP", function () {
129329     return "topCenter";
129330 });
129331
129332 _self.__defineGetter__("SIZE_FULL", function () {
129333     return "full";
129334 });
129335
129336 _self.__defineGetter__("SIZE_LARGE", function () {
129337     return "large";
129338 });
129339
129340 _self.__defineGetter__("SIZE_MEDIUM", function () {
129341     return "medium";
129342 });
129343
129344 _self.__defineGetter__("SIZE_SMALL", function () {
129345     return "small";
129346 });
129347
129348 _self.__defineGetter__("SIZE_TALL", function () {
129349     return "tall";
129350 });
129351
129352 module.exports = _self;
129353
129354 });
129355 define('ripple/platform/webworks.bb10/1.0.0/event', function (require, exports, module) {
129356 /*
129357  *  Copyright 2011 Research In Motion Limited.
129358  *
129359  * Licensed under the Apache License, Version 2.0 (the "License");
129360  * you may not use this file except in compliance with the License.
129361  * You may obtain a copy of the License at
129362  *
129363  * http://www.apache.org/licenses/LICENSE-2.0
129364  *
129365  * Unless required by applicable law or agreed to in writing, software
129366  * distributed under the License is distributed on an "AS IS" BASIS,
129367  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129368  * See the License for the specific language governing permissions and
129369  * limitations under the License.
129370  */
129371
129372 var event = require('ripple/event'),
129373     settings = require('ripple/deviceSettings'),
129374     app = require('ripple/app'),
129375     cons = require('ripple/console'),
129376     utils = require('ripple/utils'),
129377     events = {
129378         batterystatus: {
129379             callbacks: [],
129380             feature: 'blackberry.system' 
129381         },
129382         batterylow: {
129383             callbacks: [],
129384             feature: 'blackberry.system'
129385         },
129386         batterycritical: {
129387             callbacks: [],
129388             feature: 'blackberry.system'
129389         },
129390         connectionchange: {
129391             callbacks: [],
129392             feature: 'blackberry.connection'
129393         },
129394         invoked: {
129395             callbacks: [],
129396             feature: 'blackberry.invoked'
129397         },
129398         swipedown: {
129399             callbacks: [],
129400             feature: 'blackberry.app'
129401         },
129402         resume: {
129403             callbacks: [],
129404             feature: 'blackberry.app'
129405         },
129406         pause: {
129407             callbacks: [],
129408             feature: 'blackberry.app'
129409         },
129410         languagechange: {
129411             callbacks: [],
129412             feature: "blackberry.system"
129413         },
129414         regionchange: {
129415             callbacks: [],
129416             feature: "blackberry.system"
129417         }
129418     };
129419
129420 function _apply(eventName, args) {
129421     events[eventName].callbacks.forEach(function (cb) {
129422         cb.apply(null, args);
129423     });
129424 }
129425
129426 event.on('DeviceBatteryStateChanged', function (charging) {
129427     var info = {
129428         isPlugged: charging,
129429         level: parseInt(settings.retrieve('battery.level'), 10)
129430     };
129431
129432     _apply('batterystatus', [info]);
129433 });
129434
129435 event.on('DeviceBatteryLevelChanged', function (level) {
129436     var info = {
129437         isPlugged: settings.retrieve('battery.state'),
129438         level: parseInt(level, 10)
129439     };
129440
129441     _apply('batterystatus', [info]);
129442     
129443     if (level === '14') {
129444         _apply('batterylow', [info]);
129445     }
129446
129447     if (level === '4') {
129448         _apply('batterycritical', [info]);
129449     }
129450 });
129451
129452 event.on('DeviceConnectionChanged', function (info) {
129453     _apply('connectionchange', [info]);
129454 });
129455
129456 event.on("LanguageChanged", function (lang) {
129457     _apply("languagechange", [lang]);
129458 });
129459
129460 event.on("RegionChanged", function (lang) {
129461     _apply("regionchange", [lang]);
129462 });
129463
129464 event.on("AppInvoke", function (invokeInfo) {
129465     var invokeTargets = app.getInfo().invokeTargets;
129466
129467     if (!invokeTargets) {
129468         cons.log("The application cannot be invoked, please add a rim:invoke-target node in config.xml");
129469         return;
129470     }
129471
129472     if (invokeTargets.some(function (target) {
129473         return target.filter.some(function (filter) {
129474             return (
129475                 (!filter.property ||
129476                 (filter.property && filter.property[0]["@attributes"].var === "exts" && filter.property[0]["@attributes"].value.split(",").some(function (value) {
129477                     return invokeInfo.extension.match(value);
129478                 })) ||
129479                 (filter.property && filter.property[0]["@attributes"].var === "uris" && filter.property[0]["@attributes"].value.split(",").some(function (value) {
129480                     return invokeInfo.uri.match(value);
129481                 }))) &&
129482                 filter.action.some(function (action) {
129483                     return invokeInfo.action.match(action["#text"][0].replace("*", ""));
129484                 }) &&
129485                 filter["mime-type"].some(function (type) {
129486                     return invokeInfo.type.match(type["#text"][0].replace("*", ""));
129487                 })
129488             );
129489         });
129490     })) {
129491         _apply('invoked', [invokeInfo]);
129492     }
129493     else {
129494         cons.log("Cannot invoke application, values enter to not match values in rim:invoke-target in config.xml");
129495     }
129496 });
129497
129498 event.on('AppSwipeDown', function () {
129499     _apply('swipedown');
129500 });
129501
129502 event.on('AppResume', function () {
129503     _apply('resume');
129504 });
129505
129506 event.on('AppPause', function () {
129507     _apply('pause');
129508 });
129509
129510 module.exports = {
129511     addEventListener: function (type, func) {
129512         this.removeEventListener(type, func);
129513
129514         if (!app.getInfo().features || app.getInfo().features[events[type].feature]) {
129515             events[type].callbacks.push(func);
129516         }
129517         else {
129518             throw ("Cannot register a hanlder for the " + type + " event. Please add the '" + 
129519                   events[type].feature + "' to your config.xml.");
129520         }
129521     },
129522
129523     removeEventListener: function (type, func) {
129524         var idx = events[type].callbacks.indexOf(func);
129525         if (idx >= 0) {
129526             delete events[type].callbacks[idx];
129527         }
129528     }
129529 };
129530
129531 });
129532 define('ripple/platform/webworks.bb10/1.0.0/identity', function (require, exports, module) {
129533 /*
129534  *  Copyright 2011 Research In Motion Limited.
129535  *
129536  * Licensed under the Apache License, Version 2.0 (the "License");
129537  * you may not use this file except in compliance with the License.
129538  * You may obtain a copy of the License at
129539  *
129540  * http://www.apache.org/licenses/LICENSE-2.0
129541  *
129542  * Unless required by applicable law or agreed to in writing, software
129543  * distributed under the License is distributed on an "AS IS" BASIS,
129544  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129545  * See the License for the specific language governing permissions and
129546  * limitations under the License.
129547  */
129548 var deviceSettings = require('ripple/deviceSettings'),
129549     _self = {};
129550
129551 _self.__defineGetter__("uuid", function () {
129552     return deviceSettings.retrieve("identity.uuid");
129553 });
129554
129555 module.exports = _self;
129556
129557 });
129558 define('ripple/platform/webworks.bb10/1.0.0/invoke', function (require, exports, module) {
129559 /*\r
129560  *  Copyright 2011 Research In Motion Limited.\r
129561  *\r
129562  * Licensed under the Apache License, Version 2.0 (the "License");\r
129563  * you may not use this file except in compliance with the License.\r
129564  * You may obtain a copy of the License at\r
129565  *\r
129566  * http://www.apache.org/licenses/LICENSE-2.0\r
129567  *\r
129568  * Unless required by applicable law or agreed to in writing, software\r
129569  * distributed under the License is distributed on an "AS IS" BASIS,\r
129570  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
129571  * See the License for the specific language governing permissions and\r
129572  * limitations under the License.\r
129573  */\r
129574 \r
129575 var notifications = require('ripple/notifications'),\r
129576     utils = require('ripple/utils'),\r
129577     _self = {};\r
129578 \r
129579 function _fail(onError) {\r
129580     if (onError && typeof onError === "function") {\r
129581         onError("invalid invocation request");\r
129582     }\r
129583 }\r
129584 \r
129585 _self.invoke = function (request, onSuccess, onError) {\r
129586     var argsString = "";\r
129587 \r
129588     if (!request) { // is this check even needed?\r
129589         _fail(onError);\r
129590         return;\r
129591     } else {\r
129592         if (request) {\r
129593             utils.forEach(request, function (arg, key) {\r
129594                 argsString += key + " = " + arg + "</br>";\r
129595             });\r
129596 \r
129597             notifications.openNotification("normal", "Requested to invoke external application with the following arguments:</br> " +\r
129598                                            argsString + "</br>");\r
129599         }\r
129600         else {\r
129601             _fail(onError);\r
129602             return;\r
129603         }\r
129604     }\r
129605 };\r
129606 \r
129607 _self.__defineGetter__("ACTION_OPEN", function () {\r
129608     return "bb.action.OPEN";\r
129609 });\r
129610 _self.__defineGetter__("ACTION_VIEW", function () { \r
129611     return "bb.action.VIEW"; \r
129612 });\r
129613 _self.__defineGetter__("ACTION_SHARE", function () {\r
129614     return "bb.action.SHARE";\r
129615 });\r
129616 \r
129617 module.exports = _self;\r
129618
129619 });
129620 define('ripple/platform/webworks.bb10/1.0.0/navigator', function (require, exports, module) {
129621 /*
129622  *  Copyright 2011 Research In Motion Limited.
129623  *
129624  * Licensed under the Apache License, Version 2.0 (the "License");
129625  * you may not use this file except in compliance with the License.
129626  * You may obtain a copy of the License at
129627  *
129628  * http://www.apache.org/licenses/LICENSE-2.0
129629  *
129630  * Unless required by applicable law or agreed to in writing, software
129631  * distributed under the License is distributed on an "AS IS" BASIS,
129632  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129633  * See the License for the specific language governing permissions and
129634  * limitations under the License.
129635  */
129636 var nav = require('ripple/platform/w3c/1.0/navigator'),
129637     utils = require('ripple/utils'),
129638     deviceSettings = require('ripple/deviceSettings'),
129639     _self = {};
129640
129641 utils.mixin(nav, _self);
129642
129643 _self.__defineGetter__("language", function () {
129644     return deviceSettings.retrieve("system.language");
129645 });
129646
129647 module.exports = _self;
129648
129649 });
129650 define('ripple/platform/webworks.bb10/1.0.0/spec/config', function (require, exports, module) {
129651 /*
129652  *  Copyright 2011 Research In Motion Limited.
129653  *
129654  * Licensed under the Apache License, Version 2.0 (the "License");
129655  * you may not use this file except in compliance with the License.
129656  * You may obtain a copy of the License at
129657  *
129658  * http://www.apache.org/licenses/LICENSE-2.0
129659  *
129660  * Unless required by applicable law or agreed to in writing, software
129661  * distributed under the License is distributed on an "AS IS" BASIS,
129662  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129663  * See the License for the specific language governing permissions and
129664  * limitations under the License.
129665  */
129666 var utils = require('ripple/utils');
129667
129668 module.exports = {
129669     fileName: "config.xml",
129670     validateVersion: function (config) {
129671         return true;
129672     },
129673     extractInfo: function (config) {
129674         if (!config) {
129675             return null;
129676         }
129677
129678         var widgetInfo = {},
129679             widgetFeatures = config.widget.children.feature.validationResult,
129680             accessUrls = config.widget.children.access.validationResult,
129681             invokeTargets = config.rawJSON.widget[0]["rim:invoke-target"],
129682             accessFeatures = config.widget.children.access.children.feature.validationResult,
129683             toFeature = function (validationResult) {
129684                 return {
129685                     id: validationResult.attributes.id.value,
129686                     required: !validationResult.attributes.required || validationResult.attributes.required.value,
129687                     URIs: []
129688                 };
129689             };
129690
129691         widgetInfo.id = config.widget.validationResult[0].attributes.id.value;
129692         widgetInfo.name = config.widget.children.name.validationResult[0].value;
129693         widgetInfo.icon = config.widget.children.icon.validationResult[0].attributes.src.value;
129694         widgetInfo.version = config.widget.validationResult[0].attributes.version.value;
129695         widgetInfo.author = config.widget.children.author.validationResult[0].value;
129696         widgetInfo.authorEmail = config.widget.children.author.validationResult[0].attributes.email.value;
129697         widgetInfo.authorURL = config.widget.children.author.validationResult[0].attributes.href.value;
129698         widgetInfo.copyright = config.widget.children.author.validationResult[0].attributes["rim:copyright"].value;
129699         widgetInfo.description = config.widget.children.description.validationResult[0].value;
129700         widgetInfo.invokeTargets = invokeTargets;
129701         if (config.widget.children.license.validationResult[0]) {
129702             widgetInfo.license = config.widget.children.license.validationResult[0].value;
129703             widgetInfo.licenseURL = config.widget.children.license.validationResult[0].attributes.href.value;
129704         }
129705
129706         widgetInfo.features = widgetFeatures.reduce(function (features, validationResult) {
129707             if (validationResult.valid) {
129708                 var feature = toFeature(validationResult);
129709                 feature.URIs.push({
129710                     value: utils.location().href,
129711                     subdomains: true
129712                 });
129713                 features = features || {};
129714                 features[feature.id] = feature;
129715             }
129716             return features;
129717         }, {});
129718
129719         widgetInfo.features = accessUrls.map(function (access) {
129720             return {
129721                 uri: access.attributes.uri.value,
129722                 subdomains: access.attributes.subdomains.value,
129723                 features: accessFeatures ? accessFeatures.filter(function (f) {
129724                     return f.node && f.node.parentNode && f.node.parentNode.attributes.uri.value === access.attributes.uri.value;
129725                 }) : null
129726             };
129727         }).reduce(function (result, access) {
129728             return access.features ? access.features.reduce(function (features, validationResult) {
129729                 var feature = features[validationResult.attributes.id.value] || toFeature(validationResult);
129730                 feature.URIs.push({
129731                     value: access.uri,
129732                     subdomains: access.subdomains
129733                 });
129734                 features[feature.id] = feature;
129735                 return features;
129736             }, result) : result;
129737         }, widgetInfo.features);
129738
129739         return widgetInfo;
129740     },
129741     schema: {
129742         rootElement: "widget",
129743         widget: {
129744             nodeName: "widget",
129745             required: true,
129746             occurrence: 1,
129747             attributes: {
129748                 xmlns: {
129749                     attributeName: "xmlns",
129750                     required: true,
129751                     type: "list",
129752                     listValues: ["http://www.w3.org/ns/widgets"]
129753                 },
129754                 "xmlns:rim": {
129755                     attributeName: "xmlns:rim",
129756                     required: true,
129757                     type: "list",
129758                     listValues: ["http://www.blackberry.com/ns/widgets"]
129759                 },
129760                 "xml:lang": {
129761                     attributeName: "xml:lang",
129762                     required: false,
129763                     type: "iso-language"
129764                 },
129765                 id: {
129766                     attributeName: "id",
129767                     required: false,
129768                     type: "string"
129769                 },
129770                 version: {
129771                     attributeName: "version",
129772                     required: false,
129773                     type: "string"
129774                 },
129775                 "rim:header": {
129776                     attributeName: "rim:header",
129777                     required: false,
129778                     type: "string"
129779                 },
129780                 "rim:backButton": {
129781                     attributeName: "rim:backButton",
129782                     required: false,
129783                     type: "string"
129784                 }
129785             },
129786             children: {
129787                 name: {
129788                     nodeName: "name",
129789                     required: true,
129790                     occurrence: 1,
129791                     attributes: {
129792                         "xml:lang": {
129793                             attributeName: "xml:lang",
129794                             required: false,
129795                             type: "iso-language"
129796                         },
129797                         "its:dir": {
129798                             attributeName: "its:dir",
129799                             required: false,
129800                             type: "list",
129801                             listValues: ["rtl", "ltr", "lro", "rlo"]
129802                         }
129803                     }
129804                 },
129805                 description: {
129806                     nodeName: "description",
129807                     required: false,
129808                     occurrence: 1,
129809                     attributes: {
129810                         "xml:lang": {
129811                             attributeName: "xml:lang",
129812                             required: false,
129813                             type: "iso-language"
129814                         },
129815                         "its:dir": {
129816                             attributeName: "its:dir",
129817                             required: false,
129818                             type: "list",
129819                             listValues: ["rtl", "ltr", "lro", "rlo"]
129820                         }
129821                     }
129822                 },
129823                 icon: {
129824                     nodeName: "icon",
129825                     required: false,
129826                     occurrence: 0,
129827                     attributes: {
129828                         src: {
129829                             attributeName: "src",
129830                             type: "string",
129831                             required: true
129832                         },
129833                         "rim:hover": {
129834                             attributeName: "rim:hover",
129835                             type: "boolean",
129836                             required: false
129837                         }
129838                     }
129839                 },
129840                 author: {
129841                     nodeName: "author",
129842                     required: false,
129843                     occurrence: 1,
129844                     attributes: {
129845                         href: {
129846                             attributeName: "href",
129847                             type: "string",
129848                             required: false
129849                         },
129850                         "rim:copyright": {
129851                             attributeName: "rim:copyright",
129852                             type: "string",
129853                             required: false
129854                         },
129855                         email: {
129856                             attributeName: "email",
129857                             type: "string",
129858                             required: false
129859                         },
129860                         "xml:lang": {
129861                             attributeName: "xml:lang",
129862                             required: false,
129863                             type: "iso-language"
129864                         },
129865                         "its:dir": {
129866                             attributeName: "its:dir",
129867                             required: false,
129868                             type: "list",
129869                             listValues: ["rtl", "ltr", "lro", "rlo"]
129870                         }
129871                     }
129872                 },
129873                 license: {
129874                     nodeName: "license",
129875                     required: false,
129876                     occurrence: 1,
129877                     attributes : {
129878                         href: {
129879                             attributeName: "href",
129880                             type: "string",
129881                             required: false
129882                         },
129883                         "xml:lang": {
129884                             attributeName: "xml:lang",
129885                             required: false,
129886                             type: "iso-language"
129887                         },
129888                         "its:dir": {
129889                             attributeName: "its:dir",
129890                             required: false,
129891                             type: "list",
129892                             listValues: ["rtl", "ltr", "lro", "rlo"]
129893                         }
129894                     }
129895                 },
129896                 "rim:cache": {
129897                     nodeName: "rim:cache",
129898                     required: false,
129899                     occurrence: 1,
129900                     attributes: {
129901                         disableAllCache: {
129902                             attributeName: "disableAllCache",
129903                             required: false,
129904                             type: "boolean"
129905                         },
129906                         aggressiveCacheAge: {
129907                             attributeName: "aggressiveCacheAge",
129908                             required: false,
129909                             type: "number"
129910                         },
129911                         maxCacheSizeTotal: {
129912                             attributeName: "maxCacheSizeTotal",
129913                             required: false,
129914                             type: "number"
129915                         },
129916                         maxCacheSizeItem: {
129917                             attributeName: "maxCacheSizeItem",
129918                             required: false,
129919                             type: "number"
129920                         }
129921                     }
129922                 },
129923                 access: {
129924                     nodeName: "access",
129925                     required: false,
129926                     occurrence: 0,
129927                     attributes: {
129928                         uri: {
129929                             attributeName: "uri",
129930                             required: true,
129931                             type: "string"
129932                         },
129933                         subdomains: {
129934                             attributeName: "subdomains",
129935                             required: false,
129936                             type: "boolean"
129937                         }
129938                     },
129939                     children: {
129940                         feature: {
129941                             nodeName: "feature",
129942                             required: false,
129943                             occurrence: 0,
129944                             attributes: {
129945                                 id: {
129946                                     attributeName: "id",
129947                                     required: true,
129948                                     //TODO: this should be a list
129949                                     type: "string"
129950                                 },
129951                                 required: {
129952                                     attributeName: "required",
129953                                     required: false,
129954                                     type: "boolean"
129955                                 },
129956                                 version: {
129957                                     attributeName: "version",
129958                                     required: false,
129959                                     type: "string"
129960                                 }
129961                             }
129962                         }
129963                     }
129964                 },
129965                 feature: {
129966                     nodeName: "feature",
129967                     required: false,
129968                     occurrence: 0,
129969                     attributes: {
129970                         id: {
129971                             attributeName: "id",
129972                             required: true,
129973                             //TODO: this should be a list
129974                             type: "string"
129975                         },
129976                         required: {
129977                             attributeName: "required",
129978                             required: false,
129979                             type: "boolean"
129980                         },
129981                         version: {
129982                             attributeName: "version",
129983                             required: false,
129984                             type: "string"
129985                         }
129986                     }
129987                 },
129988                 "rim:loadingScreen": {
129989                     nodeName: "rim:loadingScreen",
129990                     required: false,
129991                     occurrence: 1,
129992                     attributes: {
129993                         backgroundColor: {
129994                             attributeName: "backgroundColor",
129995                             required: false,
129996                             type: "string"
129997                         },
129998                         backgroundImage: {
129999                             attributeName: "backgroundImage",
130000                             required: false,
130001                             type: "string"
130002                         },
130003                         foregroundImage: {
130004                             attributeName: "foregroundImage",
130005                             required: false,
130006                             type: "string"
130007                         },
130008                         onRemotePageLoad: {
130009                             attributeName: "onRemotePageLoad",
130010                             required: false,
130011                             type: "boolean"
130012                         },
130013                         onLocalPageLoad: {
130014                             attributeName: "onLocalPageLoad",
130015                             required : false,
130016                             type: "boolean"
130017                         },
130018                         onFirstLaunch: {
130019                             attributeName: "onFirstLaunch",
130020                             required: false,
130021                             type: "boolean"
130022                         }
130023                     },
130024                     children: {
130025                         "rim:transitionEffect": {
130026                             nodeName: "rim:transitionEffect",
130027                             required: false,
130028                             occurrence: 1,
130029                             attributes: {
130030                                 "type": {
130031                                     attributeName: "type",
130032                                     required: true,
130033                                     type: "list",
130034                                     listValues: ["slidePush", "slideOver", "fadeIn", "fadeOut", "wipeIn", "wipeOut", "zoomIn", "zoomOut"]
130035                                 },
130036                                 duration: {
130037                                     attributeName: "duration",
130038                                     required: false,
130039                                     type: "number"
130040                                 },
130041                                 direction: {
130042                                     attributeName: "direction",
130043                                     required: false,
130044                                     type: "list",
130045                                     listValues: ["left", "right", "up", "down"]
130046                                 }
130047                             }
130048                         }
130049                     }
130050                 },
130051                 "rim:invoke-target": {
130052                     nodeName: "rim:invoke-target",
130053                     required: false,
130054                     occurrence: 0,
130055                     attributes: {
130056                         id: {
130057                             attributeName: "id",
130058                             required: true,
130059                             type: "string"
130060                         }
130061                     },
130062                     children: {
130063                         "type": {
130064                             nodeName: "type",
130065                             required: true,
130066                             occurrence: 1
130067                         },
130068                         "require-source-permissions": {
130069                             nodeName: "require-source-permissions",
130070                             required: false,
130071                             occurence: 0
130072                         },
130073                         "filter": {
130074                             nodeName: "filter",
130075                             required: false,
130076                             occurence: 0,
130077                             children: {
130078                                 "action": {
130079                                     nodeName: "action",
130080                                     required: true,
130081                                     occurence: 0
130082                                 },
130083                                 "mime-type": {
130084                                     nodeName: "mime-type",
130085                                     required: true,
130086                                     occurence: 0
130087                                 },
130088                                 "property": {
130089                                     nodeName: "property",
130090                                     required: false,
130091                                     occurenc: 0,
130092                                     attributes: {
130093                                         "var": {
130094                                             attributeName: "var",
130095                                             required: false,
130096                                             type: "string"
130097                                         },
130098                                         "value": {
130099                                             attributeName: "value",
130100                                             required: false,
130101                                             type: "string"
130102                                         }
130103                                     }
130104                                 }
130105                             },
130106                         }
130107                     }
130108                 },
130109                 "rim:connection": {
130110                     nodeName: "rim:connection",
130111                     required: false,
130112                     occurrence: 1,
130113                     attributes: {
130114                         timeout: {
130115                             attributeName: "timeout",
130116                             required: false,
130117                             type: "number"
130118                         }
130119                     },
130120                     children: {
130121                         id: {
130122                             nodeName: "id",
130123                             required: false,
130124                             occurrence: 0
130125                         }
130126                     }
130127                 },
130128                 "rim:navigation": {
130129                     nodeName: "rim:navigation",
130130                     required: false,
130131                     occurrence: 1,
130132                     attributes: {
130133                         mode: {
130134                             attributeName: "mode",
130135                             required: false,
130136                             type: "list",
130137                             listValues: ["focus"]
130138                         }
130139                     }
130140                 },
130141                 "content": {
130142                     nodeName: "content",
130143                     required: true,
130144                     occurrence: 1,
130145                     attributes: {
130146                         src: {
130147                             attributeName: "src",
130148                             required: true,
130149                             type: "string"
130150                         },
130151                         type: {
130152                             attributeName: "type",
130153                             required: false,
130154                             type: "string"
130155                         },
130156                         charset: {
130157                             attributeName: "charset",
130158                             required: false,
130159                             type: "string"
130160                         }
130161                     }
130162                 }
130163             }
130164         }
130165     }
130166 };
130167
130168 });
130169 define('ripple/platform/webworks.bb10/1.0.0/spec/device', function (require, exports, module) {
130170 /*
130171  *  Copyright 2011 Research In Motion Limited.
130172  *
130173  * Licensed under the Apache License, Version 2.0 (the "License");
130174  * you may not use this file except in compliance with the License.
130175  * You may obtain a copy of the License at
130176  *
130177  * http://www.apache.org/licenses/LICENSE-2.0
130178  *
130179  * Unless required by applicable law or agreed to in writing, software
130180  * distributed under the License is distributed on an "AS IS" BASIS,
130181  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130182  * See the License for the specific language governing permissions and
130183  * limitations under the License.
130184  */
130185 var event = require('ripple/event');
130186
130187 module.exports = {
130188     "NetworkStatus": {
130189         "connectionType": {
130190             "name": "Connection Type",
130191             "control": {
130192                 "type": "select",
130193                 "value": "ethernet"
130194             },
130195             "options": {
130196                 "unknown": "UNKNOWN",
130197                 "ethernet": "ETHERNET",
130198                 "wifi": "WIFI",
130199                 "bluetooth_dun": "BLUETOOTH_DUN",
130200                 "usb": "USB",
130201                 "vpn": "VPN",
130202                 "rim-bb": "BB",
130203                 "2g": "CELL_2G",
130204                 "3g": "CELL_3G",
130205                 "4g": "CELL_4G",
130206                 "none": "NONE"
130207             },
130208             "callback": function (setting, oldSetting) {
130209                 event.trigger("DeviceConnectionChanged", [{oldType: oldSetting, newType: setting}]);
130210             }
130211         }
130212     },
130213     "identity": {
130214         "uuid": {
130215             "name": "uuid",
130216             "control": {
130217                 "type": "text",
130218                 "value": "43A8C489"
130219             }
130220         }
130221     },
130222     "system": {
130223         "language": {
130224             "name": "language",
130225             "control": {
130226                 "type": "text",
130227                 "value": "en_US"
130228             },
130229             "callback": function (setting) {
130230                 event.trigger("LanguageChanged", [setting]);
130231             }
130232         },
130233         "region": {
130234             "name": "region",
130235             "control": {
130236                 "type": "text",
130237                 "value": "en_CA"
130238             },
130239             "callback": function (setting) {
130240                 event.trigger("RegionChanged", [setting]);
130241             }
130242         }
130243     },
130244     "battery": {
130245         "state": {
130246             "name": "Handset is Charging",
130247             "control": {
130248                 "type": "checkbox",
130249                 "value": true
130250             },
130251             "callback": function (setting) {
130252                 event.trigger("DeviceBatteryStateChanged", [setting]);
130253             }
130254         },
130255         "level":  {
130256             "name": "Charge Level (% remaining)",
130257             "control": {
130258                 "type": "select",
130259                 "value": 100
130260             },
130261             "options": (function () {
130262                 var i,
130263                     optionList = {};
130264
130265                 for (i = 0; i <= 100; i++) {
130266                     optionList[i] = i;
130267                 }
130268
130269                 return optionList;
130270             }()),
130271             "callback": function (setting) {
130272                 event.trigger("DeviceBatteryLevelChanged", [setting]);
130273             }
130274         }
130275     },
130276     "Perimeters": {
130277         "perimeter": {
130278             "name": "Perimeter",
130279             "control": {
130280                 "type": "select",
130281                 "value": "Consumer"
130282             },
130283             "options": {
130284                 "Enterprise": "Enterprise",
130285                 "Consumer": "Consumer"
130286             }
130287         }
130288     }
130289 };
130290
130291 });
130292 define('ripple/platform/webworks.bb10/1.0.0/spec/events', function (require, exports, module) {
130293 /*
130294  *  Copyright 2011 Research In Motion Limited.
130295  *
130296  * Licensed under the Apache License, Version 2.0 (the "License");
130297  * you may not use this file except in compliance with the License.
130298  * You may obtain a copy of the License at
130299  *
130300  * http://www.apache.org/licenses/LICENSE-2.0
130301  *
130302  * Unless required by applicable law or agreed to in writing, software
130303  * distributed under the License is distributed on an "AS IS" BASIS,
130304  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130305  * See the License for the specific language governing permissions and
130306  * limitations under the License.
130307  */
130308 var _self,
130309     event = require('ripple/event');
130310
130311 module.exports = {
130312     "blackberry.event.swipedown": {
130313         callback: function () {
130314             event.trigger("AppSwipeDown");
130315         }
130316     },
130317     "blackberry.event.resume": {
130318         callback: function () {
130319             event.trigger("AppResume");
130320         }
130321     },
130322     "blackberry.event.pause": {
130323         callback: function () {
130324             event.trigger("AppPause");
130325         }
130326     }
130327 };
130328
130329 });
130330 define('ripple/platform/webworks.bb10/1.0.0/spec/ui', function (require, exports, module) {
130331 /*
130332  *  Copyright 2011 Research In Motion Limited.
130333  *
130334  * Licensed under the Apache License, Version 2.0 (the "License");
130335  * you may not use this file except in compliance with the License.
130336  * You may obtain a copy of the License at
130337  *
130338  * http://www.apache.org/licenses/LICENSE-2.0
130339  *
130340  * Unless required by applicable law or agreed to in writing, software
130341  * distributed under the License is distributed on an "AS IS" BASIS,
130342  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130343  * See the License for the specific language governing permissions and
130344  * limitations under the License.
130345  */
130346 module.exports = {
130347     plugins: [
130348         "accelerometer",
130349         "deviceSettings",
130350         "geoView",
130351         "platformEvents",
130352         "widgetConfig",
130353         "build",
130354         "invoke"
130355     ]
130356 };
130357
130358 });
130359 define('ripple/platform/webworks.bb10/1.0.0/spec', function (require, exports, module) {
130360 /*
130361  *  Copyright 2011 Research In Motion Limited.
130362  *
130363  * Licensed under the Apache License, Version 2.0 (the "License");
130364  * you may not use this file except in compliance with the License.
130365  * You may obtain a copy of the License at
130366  *
130367  * http://www.apache.org/licenses/LICENSE-2.0
130368  *
130369  * Unless required by applicable law or agreed to in writing, software
130370  * distributed under the License is distributed on an "AS IS" BASIS,
130371  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130372  * See the License for the specific language governing permissions and
130373  * limitations under the License.
130374  */
130375 module.exports = {
130376
130377     id: "webworks.bb10",
130378     version: "1.0.0",
130379     name: "BlackBerry 10 WebWorks",
130380
130381     persistencePrefix: "rim-bb10-",
130382
130383     ui: require('ripple/platform/webworks.bb10/1.0.0/spec/ui'),
130384     device: require('ripple/platform/webworks.bb10/1.0.0/spec/device'),
130385     config: require('ripple/platform/webworks.bb10/1.0.0/spec/config'),
130386     events: require('ripple/platform/webworks.bb10/1.0.0/spec/events'),
130387
130388     initialize: function () {
130389         var event = require('ripple/event'),
130390             _console = require('ripple/console'),
130391             emulatorBridge = require('ripple/emulatorBridge');
130392
130393         event.on("TinyHipposLoaded", function () {
130394             var doc = emulatorBridge.document(),
130395                 evt = doc.createEvent("Events");
130396             evt.initEvent("webworksready", true, true);
130397             doc.dispatchEvent(evt);
130398             _console.log("fired webworksready event!");
130399         });
130400     },
130401
130402     objects: {
130403         Coordinates: {
130404             path: "w3c/1.0/Coordinates"
130405         },
130406         Position: {
130407             path: "w3c/1.0/Position"
130408         },
130409         PositionError: {
130410             path: "w3c/1.0/PositionError"
130411         },
130412         navigator: {
130413             path: "webworks.bb10/1.0.0/navigator",
130414             children: {
130415                 geolocation: {
130416                     path: "w3c/1.0/geolocation"
130417                 }
130418             }
130419         },
130420         blackberry: {
130421             children: {
130422                 event: {
130423                     path: "webworks.bb10/1.0.0/event"
130424                 },
130425                 app: {
130426                     path: "webworks.bb10/1.0.0/app",
130427                     feature: "blackberry.app"
130428                 },
130429                 invoke: {
130430                     path: "webworks.bb10/1.0.0/invoke",
130431                     feature: "blackberry.invoke"
130432                 },
130433                 identity: {
130434                     path: "webworks.bb10/1.0.0/identity",
130435                     feature: "blackberry.identity"
130436                 },
130437                 system: {
130438                     path: "webworks.bb10/1.0.0/system"
130439                 },
130440                 connection: {
130441                     path: "webworks.bb10/1.0.0/connection"
130442                 },
130443                 ui: {
130444                     children: {
130445                         dialog: {
130446                             path: "webworks.bb10/1.0.0/dialog",
130447                             feature: "blackberry.ui.dialog"
130448                         }
130449                     }
130450                 },
130451             }
130452         }
130453     }
130454 };
130455
130456 });
130457 define('ripple/platform/webworks.bb10/1.0.0/system', function (require, exports, module) {
130458 /*\r
130459  *  Copyright 2011 Research In Motion Limited.\r
130460  *\r
130461  * Licensed under the Apache License, Version 2.0 (the "License");\r
130462  * you may not use this file except in compliance with the License.\r
130463  * You may obtain a copy of the License at\r
130464  *\r
130465  * http://www.apache.org/licenses/LICENSE-2.0\r
130466  *\r
130467  * Unless required by applicable law or agreed to in writing, software\r
130468  * distributed under the License is distributed on an "AS IS" BASIS,\r
130469  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
130470  * See the License for the specific language governing permissions and\r
130471  * limitations under the License.\r
130472  */\r
130473 var deviceSettings = require('ripple/deviceSettings'),\r
130474     devices = require('ripple/devices'),\r
130475     app = require('ripple/app'),\r
130476     utils = require('ripple/utils'),\r
130477     _self;\r
130478 \r
130479 function _is(feature) {\r
130480     return {\r
130481         allowedFor: function (location) {\r
130482             return feature && feature.URIs.some(function (uri) {\r
130483                 return uri.value === location ||\r
130484                       (location.indexOf(uri.value) >= 0 && uri.subdomains);\r
130485             });\r
130486         }\r
130487     };\r
130488 }\r
130489 \r
130490 _self = {\r
130491     hasCapability: function (capability) {\r
130492         var capabilities = devices.getCurrentDevice().capabilities;\r
130493         return capabilities ? capabilities.some(function (type) {\r
130494                 return type === capability;\r
130495             }) : false;\r
130496     },\r
130497     hasPermission: function (desiredModule) {\r
130498         var info = app.getInfo(),\r
130499             feature = info.features ? info.features[desiredModule] : null;\r
130500 \r
130501         return feature === null || _is(feature).allowedFor(utils.location().href) ? _self.ALLOW : _self.DENY;\r
130502     }\r
130503 };\r
130504 \r
130505 _self.__defineGetter__("ALLOW", function () {\r
130506     return 0;\r
130507 });\r
130508 \r
130509 _self.__defineGetter__("DENY", function () {\r
130510     return 1;\r
130511 });\r
130512 \r
130513 _self.__defineGetter__("softwareVersion", function () {\r
130514     return devices.getCurrentDevice().osVersion;\r
130515 });\r
130516 \r
130517 _self.__defineGetter__("hardwareId", function () {\r
130518     return devices.getCurrentDevice().hardwareId;\r
130519 });\r
130520 \r
130521 _self.__defineGetter__("language", function () {\r
130522     return deviceSettings.retrieve("system.language");\r
130523 });\r
130524 \r
130525 _self.__defineGetter__("region", function () {\r
130526     return deviceSettings.retrieve("system.region");\r
130527 });\r
130528 \r
130529 module.exports = _self;\r
130530
130531 });
130532 define('ripple/platform/webworks.core/2.0.0/XMLHttpRequest', function (require, exports, module) {
130533 /*
130534  *  Copyright 2011 Research In Motion Limited.
130535  *
130536  * Licensed under the Apache License, Version 2.0 (the "License");
130537  * you may not use this file except in compliance with the License.
130538  * You may obtain a copy of the License at
130539  *
130540  * http://www.apache.org/licenses/LICENSE-2.0
130541  *
130542  * Unless required by applicable law or agreed to in writing, software
130543  * distributed under the License is distributed on an "AS IS" BASIS,
130544  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130545  * See the License for the specific language governing permissions and
130546  * limitations under the License.
130547  */
130548 module.exports = {
130549     create: function (server) {
130550         var XHR = window.XMLHttpRequest,
130551             webworks = require(server);
130552
130553         return function () {
130554             var _url,
130555                 _async,
130556                 xhr = new XHR(),
130557                 origMethods = {
130558                     open: xhr.open,
130559                     send: xhr.send,
130560                     setRequestHeader: xhr.setRequestHeader
130561                 };
130562
130563             function onreadystatechange() {
130564                 if (typeof xhr.onreadystatechange === "function") {
130565                     xhr.onreadystatechange();
130566                 }
130567             }
130568
130569             function statemachine(getResult) {
130570                 var state = 0,
130571                     incState = function (prev, baton) {
130572                         state++;
130573                         if (_async) {
130574                             baton.take();
130575                             window.setTimeout(baton.pass, 1);
130576                         }
130577                     },
130578                     setResponse = function (result) {
130579                         xhr.__defineGetter__("status", function () {
130580                             return 200;
130581                         });
130582
130583                         xhr.__defineGetter__("responseText", function () {
130584                             return result !== null && result !== undefined ?
130585                                 JSON.stringify(result) : null;
130586                         });
130587                     };
130588
130589                 xhr.__defineGetter__("readyState", function () {
130590                     return state;
130591                 });
130592
130593                 jWorkflow.order(incState)
130594                          .andThen(onreadystatechange)
130595                          .andThen(incState)
130596                          .andThen(onreadystatechange)
130597                          .andThen(incState)
130598                          .andThen(onreadystatechange)
130599                          .andThen(getResult)
130600                          .andThen(setResponse)
130601                          .andThen(incState)
130602                          .andThen(onreadystatechange)
130603                          .start();
130604             }
130605
130606             xhr.setRequestHeader = function (header, value) {
130607                 if (!_url.match(/^webworks:\/\//)) {
130608                     origMethods.setRequestHeader.apply(xhr, Array.prototype.slice.call(arguments));
130609                 }
130610             };
130611
130612             xhr.open = function (method, url, async, user, password) {
130613                 _url = url;
130614                 _async = async;
130615
130616                 if (!_url.match(/^webworks:\/\//)) {
130617                     origMethods.open.apply(xhr, Array.prototype.slice.call(arguments));
130618                 }
130619             };
130620
130621             xhr.send = function (post) {
130622                 if (!_url.match(/^webworks:\/\//)) {
130623                     origMethods.send.apply(xhr, Array.prototype.slice.call(arguments));
130624                     return;
130625                 }
130626
130627                 var params = _url.match(/\?(.*)$/),
130628                     objPath = _url.match(/^webworks:\/\/([^\?]*)/)[1].split("/"),
130629                     apiMethod = objPath.reduce(function (obj, name) {
130630                         return obj[name];
130631                     }, webworks),
130632                     postParams = {},
130633                     get = {};
130634
130635                 if (params) {
130636                     params[1].split("&").forEach(function (param) {
130637                             var pair = param.split("="),
130638                                 key = decodeURIComponent(pair[0]),
130639                                 value = decodeURIComponent(pair[1]);
130640                             // parsing undefied with JSON throws exception
130641                             get[key] = value === "undefined" ? undefined : JSON.parse(value);
130642                         });
130643                 }
130644
130645                 if (post) {
130646                     post.split("&").forEach(function (param) {
130647                             var pair = param.split("="),
130648                                 value;
130649                             try {
130650                                 value = JSON.parse(decodeURIComponent(pair[1]));
130651                             } catch (e) {
130652                                 value = pair[1] === "undefined" ? undefined : pair[1];
130653                             }
130654
130655                             postParams[pair[0]] = value;
130656                         });
130657                 }
130658
130659                 statemachine(function (prev, baton) {
130660                     return apiMethod(get, postParams, baton);
130661                 });
130662             };
130663
130664             return xhr;
130665         };
130666     }
130667 };
130668
130669 });
130670 define('ripple/platform/webworks.core/2.0.0/client/FileProperties', function (require, exports, module) {
130671 /*
130672  * Copyright 2011 Research In Motion Limited.
130673  *
130674  * Licensed under the Apache License, Version 2.0 (the "License");
130675  * you may not use this file except in compliance with the License.
130676  * You may obtain a copy of the License at
130677  *
130678  *     http://www.apache.org/licenses/LICENSE-2.0
130679  *
130680  * Unless required by applicable law or agreed to in writing, software
130681  * distributed under the License is distributed on an "AS IS" BASIS,
130682  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130683  * See the License for the specific language governing permissions and
130684  * limitations under the License.
130685  */
130686 function FileProperties(props) {
130687     props = props || {};
130688
130689     function _get(val) {
130690         return function () {
130691             return props[val];
130692         };
130693     }
130694
130695     this.__defineGetter__("dateCreated", _get("dateCreated")); //tablet only
130696     this.__defineGetter__("dateModified", _get("dateModified"));
130697     this.__defineGetter__("directory", _get("directory"));
130698     this.__defineGetter__("fileExtension", _get("fileExtension"));
130699     this.__defineGetter__("isHidden", _get("isHidden"));
130700     this.__defineGetter__("isReadonly", _get("isReadonly")); //handset only
130701     this.__defineGetter__("mimeType", _get("mimeType")); //handset only
130702     this.__defineGetter__("size", _get("size"));
130703 }
130704
130705 module.exports = FileProperties;
130706
130707 });
130708 define('ripple/platform/webworks.core/2.0.0/client/dialog', function (require, exports, module) {
130709 /*\r
130710  *  Copyright 2011 Research In Motion Limited.\r
130711  *\r
130712  * Licensed under the Apache License, Version 2.0 (the "License");\r
130713  * you may not use this file except in compliance with the License.\r
130714  * You may obtain a copy of the License at\r
130715  *\r
130716  * http://www.apache.org/licenses/LICENSE-2.0\r
130717  *\r
130718  * Unless required by applicable law or agreed to in writing, software\r
130719  * distributed under the License is distributed on an "AS IS" BASIS,\r
130720  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
130721  * See the License for the specific language governing permissions and\r
130722  * limitations under the License.\r
130723  */\r
130724 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
130725     _uri = "blackberry/ui/dialog/",\r
130726     _self;\r
130727 \r
130728 function getButtonsForDialogType(dialogType) {\r
130729     switch (dialogType) {\r
130730     case _self.D_OK:\r
130731         return ["Ok"];\r
130732     case _self.D_SAVE:\r
130733         return ["Save", "Discard"];\r
130734     case _self.D_DELETE:\r
130735         return ["Delete", "Cancel"];\r
130736     case _self.D_YES_NO:\r
130737         return ["Yes", "No"];\r
130738     case _self.D_OK_CANCEL:\r
130739         return ["Ok", "Cancel"];\r
130740     default:\r
130741         throw new Error("Invalid dialog type: " + dialogType);\r
130742     }\r
130743 }\r
130744 \r
130745 _self = {\r
130746     customAskAsync: function (message, choices, callback, settings) {\r
130747         return transport.call(_uri + "ask", {\r
130748             async: true,\r
130749             get: {\r
130750                 message: message,\r
130751                 buttons: choices,\r
130752                 settings: settings\r
130753             }\r
130754         }, function (response) {\r
130755             if (callback) {\r
130756                 callback(response);\r
130757             }\r
130758         });\r
130759     },\r
130760 \r
130761     standardAskAsync: function (message, type, callback, settings) {\r
130762         var choices = getButtonsForDialogType(type);\r
130763         return transport.call(_uri + "ask", {\r
130764             async: true,\r
130765             get: {\r
130766                 message: message,\r
130767                 buttons: choices,\r
130768                 settings: settings\r
130769             }\r
130770         }, function (response) {\r
130771             if (callback) {\r
130772                 callback(response);\r
130773             }\r
130774         });\r
130775     }\r
130776 };\r
130777 \r
130778 _self.__defineGetter__("D_OK", function () {\r
130779     return 0;\r
130780 });\r
130781 \r
130782 _self.__defineGetter__("D_SAVE", function () {\r
130783     return 1;\r
130784 });\r
130785 \r
130786 _self.__defineGetter__("D_DELETE", function () {\r
130787     return 2;\r
130788 });\r
130789 \r
130790 _self.__defineGetter__("D_YES_NO", function () {\r
130791     return 3;\r
130792 });\r
130793 \r
130794 _self.__defineGetter__("D_OK_CANCEL", function () {\r
130795     return 4;\r
130796 });\r
130797 \r
130798 _self.__defineGetter__("BOTTOM", function () {\r
130799     return "bottomCenter";\r
130800 });\r
130801 \r
130802 _self.__defineGetter__("CENTER", function () {\r
130803     return "middleCenter";\r
130804 });\r
130805 \r
130806 _self.__defineGetter__("TOP", function () {\r
130807     return "topCenter";\r
130808 });\r
130809 \r
130810 _self.__defineGetter__("SIZE_FULL", function () {\r
130811     return "full";\r
130812 });\r
130813 \r
130814 _self.__defineGetter__("SIZE_LARGE", function () {\r
130815     return "large";\r
130816 });\r
130817 \r
130818 _self.__defineGetter__("SIZE_MEDIUM", function () {\r
130819     return "medium";\r
130820 });\r
130821 \r
130822 _self.__defineGetter__("SIZE_SMALL", function () {\r
130823     return "small";\r
130824 });\r
130825 \r
130826 _self.__defineGetter__("SIZE_TALL", function () {\r
130827     return "tall";\r
130828 });\r
130829 \r
130830 module.exports = _self;\r
130831
130832 });
130833 define('ripple/platform/webworks.core/2.0.0/client/events', function (require, exports, module) {
130834 /*
130835  * Copyright 2011 Research In Motion Limited.
130836  *
130837  * Licensed under the Apache License, Version 2.0 (the "License");
130838  * you may not use this file except in compliance with the License.
130839  * You may obtain a copy of the License at
130840  *
130841  *     http://www.apache.org/licenses/LICENSE-2.0
130842  *
130843  * Unless required by applicable law or agreed to in writing, software
130844  * distributed under the License is distributed on an "AS IS" BASIS,
130845  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130846  * See the License for the specific language governing permissions and
130847  * limitations under the License.
130848  */
130849 var _handlers = [],
130850     _self;
130851
130852 _self = {
130853     eventsMap: {
130854         getHandlerById: function (handlerId) {
130855             return _handlers[handlerId];
130856         },
130857         addHandler: function (handler) {
130858             _handlers.push(handler);
130859             return _handlers.length - 1;
130860         },
130861         removeHandler: function (handlerId) {
130862             if (handlerId > -1 && handlerId < _handlers.length) {
130863                 delete _handlers[handlerId]; //cannot splice because all published IDs would refer to the wrong handler
130864             }
130865         }
130866     },
130867
130868     registerEventHandler : function (eventName, eventCallback, eventParams) {
130869         return _self.eventsMap.addHandler(eventCallback);
130870     },
130871
130872     getEventHandler : function (handlerId) {
130873         return _self.eventsMap.getHandlerById(handlerId);
130874     }
130875 };
130876
130877 module.exports = _self;
130878
130879 });
130880 define('ripple/platform/webworks.core/2.0.0/client/io/dir', function (require, exports, module) {
130881 /*
130882  * Copyright 2011 Research In Motion Limited.
130883  *
130884  * Licensed under the Apache License, Version 2.0 (the "License");
130885  * you may not use this file except in compliance with the License.
130886  * You may obtain a copy of the License at
130887  *
130888  *     http://www.apache.org/licenses/LICENSE-2.0
130889  *
130890  * Unless required by applicable law or agreed to in writing, software
130891  * distributed under the License is distributed on an "AS IS" BASIS,
130892  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130893  * See the License for the specific language governing permissions and
130894  * limitations under the License.
130895  */
130896 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
130897     _uri = "blackberry/io/dir/",
130898     FILE = "file://";
130899
130900 function _prunePrefix(path) {
130901     return path.replace(new RegExp("^" + FILE), '');
130902 }
130903
130904 function _addPrefix(path) {
130905     return FILE + path;
130906 }
130907
130908 module.exports = {
130909     createNewDir: function (path) {
130910         transport.call(_uri + "createNewDir", {
130911             post: {path: _prunePrefix(path)}
130912         });
130913     },
130914     deleteDirectory: function (path, recursive) {
130915         transport.call(_uri + "deleteDirectory", {
130916             post: {path: _prunePrefix(path), recursive: recursive}
130917         });
130918     },
130919     exists: function (path) {
130920         return transport.call(_uri + "exists", {
130921             post: {path: _prunePrefix(path)}
130922         });
130923     },
130924     getParentDirectory: function (path) {
130925         return _addPrefix(transport.call(_uri + "getParentDirectory", {
130926             post: {path: _prunePrefix(path)}
130927         }));
130928     },
130929     listDirectories: function (path) {
130930         return transport.call(_uri + "listDirectories", {
130931             post: {path: _prunePrefix(path)}
130932         });
130933     },
130934     listFiles: function (path) {
130935         return transport.call(_uri + "listFiles", {
130936             post: {path: _prunePrefix(path)}
130937         });
130938     },
130939     rename: function (path, newName) {
130940         transport.call(_uri + "rename", {
130941             post: {path: _prunePrefix(path), newName: newName}
130942         });
130943     }
130944 };
130945
130946 });
130947 define('ripple/platform/webworks.core/2.0.0/client/io/file', function (require, exports, module) {
130948 /*
130949  * Copyright 2011 Research In Motion Limited.
130950  *
130951  * Licensed under the Apache License, Version 2.0 (the "License");
130952  * you may not use this file except in compliance with the License.
130953  * You may obtain a copy of the License at
130954  *
130955  *     http://www.apache.org/licenses/LICENSE-2.0
130956  *
130957  * Unless required by applicable law or agreed to in writing, software
130958  * distributed under the License is distributed on an "AS IS" BASIS,
130959  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130960  * See the License for the specific language governing permissions and
130961  * limitations under the License.
130962  */
130963 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
130964     _uri = "blackberry/io/file/",
130965     FILE = "file://",
130966     _onFileOpened;
130967
130968 function _prunePrefix(path) {
130969     return path.replace(new RegExp("^" + FILE), '');
130970 }
130971
130972 module.exports = {
130973     copy: function (from, to) {
130974         transport.call(_uri + "copy", {
130975             post: {from: _prunePrefix(from), to: _prunePrefix(to)}
130976         });
130977     },
130978     deleteFile: function (path) {
130979         transport.call(_uri + "deleteFile", {
130980             post: {path: _prunePrefix(path)}
130981         });
130982     },
130983     exists: function (path) {
130984         return transport.call(_uri + "exists", {
130985             post: {path: _prunePrefix(path)}
130986         });
130987     },
130988     getFileProperties: function (path) {
130989         var properties = transport.call(_uri + "getFileProperties", {
130990             post: {path: _prunePrefix(path)}
130991         });
130992         properties.directory = FILE + properties.directory;
130993         return properties;
130994     },
130995     open: function (path, newName) {
130996         transport.call(_uri + "open", {
130997             post: {path: _prunePrefix(path)}
130998         });
130999     },
131000     readFile: function (path, onFileOpened, async) {
131001         async = async === false ? false : true;
131002
131003         var uri = _uri + "readFile",
131004             args = {
131005                 post: {path: _prunePrefix(path), async: async}
131006             },
131007             callResult;
131008
131009         _onFileOpened = onFileOpened;
131010
131011         if (async) {
131012             transport.poll(uri, args, function (data, res) {
131013                 if (_onFileOpened) {
131014                     _onFileOpened(FILE + data.fullPath, data.blobData);
131015                 }
131016                 return false;
131017             });
131018         } else {
131019             callResult = transport.call(uri, args);
131020             _onFileOpened(FILE + callResult.fullPath, callResult.blobData);
131021         }
131022     },
131023     rename: function (path, newName) {
131024         transport.call(_uri + "rename", {
131025             post: {path: _prunePrefix(path), newName: newName}
131026         });
131027     },
131028     saveFile: function (path, blob) {
131029         transport.call(_uri + "saveFile", {
131030             post: {path: _prunePrefix(path), blob: blob}
131031         });
131032     }
131033 };
131034
131035 });
131036 define('ripple/platform/webworks.core/2.0.0/client/system', function (require, exports, module) {
131037 /*\r
131038  *  Copyright 2011 Research In Motion Limited.\r
131039  *\r
131040  * Licensed under the Apache License, Version 2.0 (the "License");\r
131041  * you may not use this file except in compliance with the License.\r
131042  * You may obtain a copy of the License at\r
131043  *\r
131044  * http://www.apache.org/licenses/LICENSE-2.0\r
131045  *\r
131046  * Unless required by applicable law or agreed to in writing, software\r
131047  * distributed under the License is distributed on an "AS IS" BASIS,\r
131048  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
131049  * See the License for the specific language governing permissions and\r
131050  * limitations under the License.\r
131051  */\r
131052 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
131053     _uri = "blackberry/system/",\r
131054     _self;\r
131055 \r
131056 _self = {\r
131057     hasCapability: function (capability) {\r
131058         return transport.call(_uri + "hasCapability", {\r
131059             get: {capability: capability}\r
131060         });\r
131061     },\r
131062 \r
131063     hasDataCoverage: function () {\r
131064         return transport.call(_uri + "hasDataCoverage");\r
131065     },\r
131066 \r
131067     hasPermission: function (desiredModule) {\r
131068         return transport.call(_uri + "hasPermission", {\r
131069             get: {desiredModule: desiredModule}\r
131070         });\r
131071     },\r
131072 \r
131073     isMassStorageActive: function () {\r
131074         return transport.call(_uri + "isMassStorageActive");\r
131075     }\r
131076 };\r
131077 \r
131078 _self.__defineGetter__("model", function () {\r
131079     return transport.call(_uri + "model");\r
131080 });\r
131081 _self.__defineGetter__("scriptApiVersion", function () {\r
131082     return transport.call(_uri + "scriptApiVersion");\r
131083 });\r
131084 _self.__defineGetter__("softwareVersion", function () {\r
131085     return transport.call(_uri + "softwareVersion");\r
131086 });\r
131087 \r
131088 _self.__defineGetter__("ALLOW", function () {\r
131089     return 0;\r
131090 });\r
131091 _self.__defineGetter__("DENY", function () {\r
131092     return 1;\r
131093 });\r
131094 _self.__defineGetter__("PROMPT", function () {\r
131095     return 2;\r
131096 });\r
131097 _self.__defineGetter__("NOT_SET", function () {\r
131098     return 3;\r
131099 });\r
131100 \r
131101 module.exports = _self;\r
131102
131103 });
131104 define('ripple/platform/webworks.core/2.0.0/client/transport', function (require, exports, module) {
131105 /*
131106  * Copyright 2011 Research In Motion Limited.
131107  *
131108  * Licensed under the Apache License, Version 2.0 (the "License");
131109  * you may not use this file except in compliance with the License.
131110  * You may obtain a copy of the License at
131111  *
131112  *     http://www.apache.org/licenses/LICENSE-2.0
131113  *
131114  * Unless required by applicable law or agreed to in writing, software
131115  * distributed under the License is distributed on an "AS IS" BASIS,
131116  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131117  * See the License for the specific language governing permissions and
131118  * limitations under the License.
131119  */
131120 var _self;
131121
131122 function RemoteFunctionCall(functionUri) {
131123     var params = {},
131124         postString = "",
131125         postParams = {};
131126
131127     function composeUri() {
131128         var uri = "webworks://" + functionUri,
131129             paramCount = 1,
131130             param;
131131
131132         for (param in params) {
131133             if (params.hasOwnProperty(param)) {
131134                 if (paramCount === 1) {
131135                     uri += "?";
131136                 } else {
131137                     uri += "&";
131138                 }
131139                 uri += param + "=" + params[param];
131140                 paramCount++;
131141             }
131142
131143             uri = uri.replace(/\&$/, "");
131144         }
131145
131146         return uri;
131147     }
131148
131149     function createXhrRequest(uri, isAsync) {
131150         var request = new XMLHttpRequest(),
131151             paramCount = 1,
131152             param;
131153
131154         for (param in postParams) {
131155             if (postParams.hasOwnProperty(param)) {
131156                 postString += param + "=" + postParams[param] + "&";
131157                 paramCount++;
131158             }
131159         }
131160
131161         postString = postString.replace(/\&$/, "");
131162
131163         // TODO: make get/post
131164         request.open("POST", uri, isAsync);
131165         request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
131166
131167         return request;
131168     }
131169
131170     this.addParam = function (name, value) {
131171         params[name] = encodeURIComponent(JSON.stringify(value));
131172     };
131173
131174     this.addPostParam = function (name, value) {
131175         postParams[name] = encodeURIComponent(JSON.stringify(value));
131176     };
131177
131178     this.makeSyncCall = function (success, error) {
131179         var requestUri = composeUri(),
131180             request = createXhrRequest(requestUri, false),
131181             response, errored, cb, data;
131182
131183         request.send(postString);
131184
131185         response = JSON.parse(request.responseText || "null");
131186         errored = response.code < 0;
131187         cb = errored ? error : success;
131188         data = errored ? response.msg : response.data;
131189
131190         if (cb) {
131191             cb(data, response);
131192         }
131193         else if (errored) {
131194             throw data;
131195         }
131196
131197         return data;
131198     };
131199
131200     this.makeAsyncCall = function (success, error) {
131201         var requestUri = composeUri(),
131202             request = createXhrRequest(requestUri, true);
131203
131204         request.onreadystatechange = function () {
131205             if (request.readyState === 4 && request.status === 200) {
131206                 var response = JSON.parse(request.responseText || "null"),
131207                     cb = response.code < 0 ? error : success,
131208                     data = response.code < 0 ? response.msg : response.data;
131209
131210                 return cb && cb(data, response);
131211             }
131212         };
131213
131214         request.send(postString);
131215     };
131216 }
131217
131218 _self = {
131219     call: function (url, opts, success, error) {
131220         var request = new RemoteFunctionCall(url),
131221             name;
131222
131223         opts = opts || {};
131224
131225         if (opts.get) {
131226             for (name in opts.get) {
131227                 if (Object.hasOwnProperty.call(opts.get, name)) {
131228                     request.addParam(name, opts.get[name]);
131229                 }
131230             }
131231         }
131232
131233         if (opts.post) {
131234             for (name in opts.post) {
131235                 if (Object.hasOwnProperty.call(opts.post, name)) {
131236                     request.addPostParam(name, opts.post[name]);
131237                 }
131238             }
131239         }
131240
131241         return opts.async ? request.makeAsyncCall(success, error) : request.makeSyncCall(success, error);
131242     },
131243
131244     poll: function (url, opts, callback) {
131245         opts = opts || {};
131246         opts.async = true;
131247
131248         _self.call(url, opts, function (data, response) {
131249             if (callback(data, response)) {
131250                 _self.poll(url, opts, callback);
131251             }
131252         });
131253     }
131254 };
131255
131256 module.exports = _self;
131257
131258 });
131259 define('ripple/platform/webworks.core/2.0.0/client/utils', function (require, exports, module) {
131260 /*
131261  * Copyright 2011 Research In Motion Limited.
131262  *
131263  * Licensed under the Apache License, Version 2.0 (the "License");
131264  * you may not use this file except in compliance with the License.
131265  * You may obtain a copy of the License at
131266  *
131267  *     http://www.apache.org/licenses/LICENSE-2.0
131268  *
131269  * Unless required by applicable law or agreed to in writing, software
131270  * distributed under the License is distributed on an "AS IS" BASIS,
131271  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131272  * See the License for the specific language governing permissions and
131273  * limitations under the License.
131274  */
131275 var _blobs = {};
131276
131277 function _blobBuilder() {
131278     var BlobBuilder = BlobBuilder || WebKitBlobBuilder;
131279     return new BlobBuilder();
131280 }
131281
131282 module.exports = {
131283     parseURL: function (theUrl) {
131284         /********START IDEA BORROWING*******/
131285         // parseUri 1.2.2
131286         // (c) Steven Levithan <stevenlevithan.com>
131287         // MIT License
131288
131289         function parseUri(str) {
131290             var o   = parseUri.options,
131291                 m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
131292                 uri = {},
131293                 i   = 14;
131294
131295             while (i--) {
131296                 uri[o.key[i]] = m[i] || "";
131297             }
131298
131299             uri[o.q.name] = {};
131300             uri[o.q.arrayName] = [];
131301             uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
131302                 if ($1) {
131303                     uri[o.q.name][$1] = $2;
131304                     uri[o.q.arrayName].push($2);
131305                 }
131306             });
131307
131308             return uri;
131309         }
131310
131311         parseUri.options = {
131312                 strictMode: false,
131313                 key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"],
131314                 q:   {
131315                     name:   "queryKey",
131316                     arrayName:   "queryArray",
131317                     parser: /(?:^|&)([^&=]*)=?([^&]*)/g
131318                 },
131319                 parser: {
131320                     strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
131321                     loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
131322                 }
131323             };
131324         /********END IDEA BORROWING*******/
131325
131326         parseUri.strictMode = "strict";
131327         var uri = parseUri(theUrl),
131328             retVal = {
131329                 getURLParameter : function (key) {
131330                     return uri.queryKey[key];
131331                 },
131332
131333                 getURLParameterByIndex : function (index) {
131334                     return uri.queryArray[index];
131335                 }
131336             };
131337
131338         //Add default values for the http/https port if they weren't specified in the URL. The above parser returns undefined. We need the values
131339         //to be compatible with the BB version of API.
131340         if (uri["port"] === "") {
131341             if (uri["protocol"] === "http") {
131342                 uri["port"] = "80";
131343             }
131344             else if (uri["protocol"] === "https") {
131345                 uri["port"] = "443";
131346             }
131347             else {
131348                 uri["port"] = "0";
131349             }
131350         }
131351
131352         retVal.__defineGetter__("host", function () {
131353             return uri["host"];
131354         });
131355         retVal.__defineGetter__("port", function () {
131356             return parseInt(uri["port"], 10);
131357         });
131358
131359         return retVal;
131360     },
131361
131362     generateUniqueId: function () {
131363         return Math.floor(Math.random() * Number.MAX_VALUE);
131364     },
131365
131366     blobToString: function (blob, encoding) {
131367         return _blobs[blob.id];
131368     },
131369
131370     stringToBlob: function (string, encoding) {
131371         var id = Math.uuid(undefined, 16),
131372             blob = _blobBuilder(),
131373             finalBlob;
131374
131375         _blobs[id] = string;
131376         blob.append(string);
131377
131378         finalBlob = blob.getBlob();
131379         finalBlob.id = id;
131380         finalBlob.length = finalBlob.size;
131381
131382         return finalBlob;
131383     }
131384 };
131385
131386 });
131387 define('ripple/platform/webworks.core/2.0.0/fsCache', function (require, exports, module) {
131388 /*
131389  * Copyright 2011 Research In Motion Limited.
131390  *
131391  * Licensed under the Apache License, Version 2.0 (the "License");
131392  * you may not use this file except in compliance with the License.
131393  * You may obtain a copy of the License at
131394  *
131395  *     http://www.apache.org/licenses/LICENSE-2.0
131396  *
131397  * Unless required by applicable law or agreed to in writing, software
131398  * distributed under the License is distributed on an "AS IS" BASIS,
131399  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131400  * See the License for the specific language governing permissions and
131401  * limitations under the License.
131402  */
131403 var fs = require('ripple/dbfs'),
131404     utils = require('ripple/utils'),
131405     _console = require('ripple/console'),
131406     constants = require('ripple/constants'),
131407     event = require('ripple/event'),
131408     bbUtils = require('ripple/platform/webworks.core/2.0.0/client/utils'),
131409     FileProperties = require('ripple/platform/webworks.core/2.0.0/client/FileProperties'),
131410     _cache = {},
131411     _self;
131412
131413 function _createPath(path) {
131414     var parts = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
131415         workflow = jWorkflow.order();
131416
131417     parts.forEach(function (part, index) {
131418         var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/");
131419
131420         workflow.andThen(function (prev, baton) {
131421             baton.take();
131422             fs.mkdir(dir, baton.pass, baton.pass);
131423         });
131424     });
131425
131426     workflow.start(_self.refresh);
131427 }
131428 event.on("FileSystemInitialized", function () {
131429     _createPath("/SDCard");
131430     _createPath("/store/home/user/music");
131431     _createPath("/store/home/user/pictures");
131432     _createPath("/store/home/user/videos");
131433     _createPath("/store/home/user/videos");
131434     _createPath("/accounts/1000/appdata/emulatedapp/data");
131435     _createPath("/accounts/1000/appdata/emulatedapp/shared/bookmarks");
131436     _createPath("/accounts/1000/appdata/emulatedapp/shared/books");
131437     _createPath("/accounts/1000/appdata/emulatedapp/shared/camera");
131438     _createPath("/accounts/1000/appdata/emulatedapp/shared/documents");
131439     _createPath("/accounts/1000/appdata/emulatedapp/shared/downloads");
131440     _createPath("/accounts/1000/appdata/emulatedapp/shared/misc");
131441     _createPath("/accounts/1000/appdata/emulatedapp/shared/music");
131442     _createPath("/accounts/1000/appdata/emulatedapp/shared/photos");
131443     _createPath("/accounts/1000/appdata/emulatedapp/shared/print");
131444     _createPath("/accounts/1000/appdata/emulatedapp/shared/videos");
131445     _createPath("/accounts/1000/appdata/emulatedapp/shared/voice");
131446 });
131447
131448 function _fsError(e) {
131449     _self.refresh();
131450     if (e.code !== 1) { // suppress file not found error
131451         _console.error("FileSystem error (code " + e.code + ")");
131452     }
131453 }
131454
131455 function _walk(path, parent) {
131456     fs.ls(path, function (entries) {
131457         parent.children = parent.children || {};
131458
131459         entries.forEach(function (entry) {
131460             parent.children[entry.name] = entry;
131461             parent.children[entry.name].properties = {};
131462
131463             if (entry.isDirectory) {
131464                 _walk(entry.fullPath, entry);
131465             } else {
131466                 entry.file(function (file) {
131467                     utils.mixin(file, parent.children[entry.name].properties);
131468                 });
131469                 fs.read(entry.fullPath, function (data) {
131470                     parent.children[entry.name].data = data;
131471                 }, function (e) {
131472                     console.error(e);
131473                 });
131474             }
131475         });
131476     }, function (e) {
131477         console.error(e);
131478     });
131479 }
131480
131481 function _get(path) {
131482     return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
131483         return token === "" ? obj : (obj && obj.children ? obj.children[token] || null : null);
131484     }, _cache);
131485 }
131486
131487 function _getInfo(path) {
131488     var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
131489         name = parent.splice(parent.length - 1, 1).join(""),
131490         ext = name.split(".");
131491
131492     return {
131493         name: name,
131494         extension: ext.length > 1 ? ext[ext.length - 1] : "",
131495         hidden: (name.length > 0 && name[0] === ".") || false,
131496         parent: parent.join("/") || "/"
131497     };
131498 }
131499
131500 function _set(path, obj) {
131501     var parent = _cache,
131502         tokens = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
131503         child = tokens.splice(tokens.length - 1, 1).join("");
131504
131505     tokens.forEach(function (token) {
131506         parent = parent.children[token];
131507     });
131508
131509     parent.children = parent.children || {};
131510     obj.properties = obj.properties || {};
131511     parent.children[child] = obj;
131512 }
131513
131514 function _delete(path) {
131515     var parent = _cache,
131516         tokens = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
131517         child = tokens.splice(tokens.length - 1, 1).join("");
131518
131519     tokens.forEach(function (token) {
131520         parent = parent.children[token];
131521     });
131522
131523     delete parent.children[child];
131524 }
131525
131526 // TODO: handle exceptions so that any respective fs command can error out
131527 // TODO: dateCreated is always dateModified
131528
131529 _self = {
131530     refresh: function () {
131531         _cache = {};
131532         _walk("/", _cache);
131533     },
131534     file: {
131535         exists: function (path) {
131536             var entry = _get(path);
131537             return !!(entry && !entry.isDirectory);
131538         },
131539
131540         deleteFile: function (path) {
131541             _delete(path);
131542             fs.rm(path, function () {}, _fsError);
131543         },
131544
131545         copy: function (from, to) {
131546             var fromEntry = _get(from);
131547
131548             _set(to, {
131549                 fullPath: to,
131550                 properties: fromEntry.properties,
131551                 data: fromEntry.data
131552             });
131553
131554             fs.cp(from, to, function (entry) {
131555                 entry.file(function (file) {
131556                     entry.properties = entry.properties || {};
131557                     utils.mixin(file, entry.properties);
131558                     _set(to, entry);
131559                 });
131560             }, _fsError);
131561         },
131562
131563         getFileProperties: function (path) {
131564             var entry = _get(path),
131565                 info = _getInfo(path);
131566
131567             fs.stat(path, function () {}, _fsError);
131568
131569             return new FileProperties({
131570                 //HACK: not sure where these should come from so check both for now.
131571                 dateCreated: entry.properties.lastModifiedDate || entry.lastModifiedDate,
131572                 dateModified: entry.properties.lastModifiedDate || entry.lastModifiedDate,
131573                 directory: info.parent,
131574                 fileExtension: info.extension,
131575                 isHidden: info.hidden,
131576                 isReadonly: false,
131577                 mimeType: entry.properties.type,
131578                 size: entry.properties.size
131579             });
131580         },
131581
131582         rename: function (path, newName) {
131583             _self.dir.rename(path, newName);
131584         },
131585
131586         readFile: function (path, success, async) {
131587             var entry = _get(path);
131588
131589             async = async === false ? async : true;
131590
131591             if (!async) {
131592                 success(bbUtils.stringToBlob(entry.data));
131593             }
131594             else {
131595                 fs.read(path, function (data) {
131596                     var blob = bbUtils.stringToBlob(data);
131597                     if (async) {
131598                         success(blob);
131599                     }
131600                     entry.data = data;
131601                     _set(path, entry);
131602                 }, _fsError);
131603             }
131604         },
131605
131606         saveFile: function (path, blob) {
131607             var data = bbUtils.blobToString(blob);
131608
131609             _set(path, {
131610                 lastModifiedDate: new Date(),
131611                 fullPath: path,
131612                 isDirectory: false,
131613                 properties: {
131614                     type: "",
131615                     size: blob.size
131616                 },
131617                 data: data
131618             });
131619
131620             fs.write(path, data, function (entry) {
131621                 entry.data = data;
131622                 entry.file(function (file) {
131623                     entry.properties = entry.properties || {};
131624                     utils.mixin(file, entry.properties);
131625                     _set(path, entry);
131626                 });
131627             }, _fsError);
131628         }
131629     },
131630     dir: {
131631         createNewDir: function (path) {
131632             var entry = _get(path),
131633                 info = _getInfo(path);
131634
131635             if (!entry) {
131636                 _set(path, {
131637                     name: info.name,
131638                     isDirectory: true,
131639                     fullPath: path
131640                 });
131641             }
131642
131643             fs.mkdir(path, function (entry) {
131644                 _set(path, entry);
131645             }, _fsError);
131646         },
131647
131648         deleteDirectory: function (path, recursive) {
131649             _delete(path);
131650             if (recursive) {
131651                 fs.rm(path, function () {}, _fsError, {recursive: recursive});
131652             } else {
131653                 fs.rmdir(path, function () {}, _fsError);
131654             }
131655         },
131656
131657         exists: function (path) {
131658             var entry = _get(path);
131659             return !!(entry && entry.isDirectory);
131660         },
131661
131662         getFreeSpaceForRoot: function (path) {
131663             function _du(obj, size) {
131664                 utils.forEach(obj, function (child, key) {
131665                     if (child.isDirectory && child.children) {
131666                         size += _du(child.children, size);
131667                     } else if (child.properties && child.properties.size) {
131668                         size += child.properties.size;
131669                     }
131670                 });
131671                 return size;
131672             }
131673
131674             return constants.FS_SIZE - _du(_cache.children, 0);
131675         },
131676
131677         getParentDirectory: function (path) {
131678             path = "/" + path.replace(/^\//, '').replace(/\/$/, '');
131679
131680             var entry = _get(path),
131681                 array = path.split("/");
131682
131683             return entry ? array.splice(0, array.length - 1).join("/") || "/" : null;
131684         },
131685
131686         listDirectories: function (path) {
131687             var dir = _get(path),
131688                 directories = [];
131689
131690             utils.forEach(dir.children, function (item) {
131691                 if (item.isDirectory) {
131692                     directories.push(item.name);
131693                 }
131694             });
131695
131696             fs.ls(path, function () {}, _fsError);
131697
131698             return directories;
131699         },
131700
131701         listFiles: function (path) {
131702             var dir = _get(path),
131703                 files = [];
131704
131705             if (dir) {
131706                 utils.forEach(dir.children, function (item) {
131707                     if (!item.isDirectory) {
131708                         files.push(item.name);
131709                     }
131710                 });
131711             }
131712
131713             fs.ls(path, function () {}, _fsError);
131714
131715             return files;
131716         },
131717
131718         rename: function (path, newName) {
131719             var info = _getInfo(path),
131720                 parent = info.parent,
131721                 oldName = info.name,
131722                 from = (parent === "/" ? "" : parent) + "/" + oldName,
131723                 to =  (parent === "/" ? "" : parent) + "/" + newName;
131724
131725             _delete(from);
131726             _set(to, {
131727                 name: info.name,
131728                 fullPath: path
131729             });
131730
131731             fs.mv(from, to, function (entry) {
131732                 _set(to, entry);
131733             }, _fsError);
131734         },
131735
131736         getRootDirs: function () {
131737             return _self.dir.listDirectories("/");
131738         }
131739     }
131740 };
131741
131742 module.exports = _self;
131743
131744 });
131745 define('ripple/platform/webworks.core/2.0.0/select', function (require, exports, module) {
131746 /*
131747  *  Copyright 2011 Research In Motion Limited.
131748  *
131749  * Licensed under the Apache License, Version 2.0 (the "License");
131750  * you may not use this file except in compliance with the License.
131751  * You may obtain a copy of the License at
131752  *
131753  * http://www.apache.org/licenses/LICENSE-2.0
131754  *
131755  * Unless required by applicable law or agreed to in writing, software
131756  * distributed under the License is distributed on an "AS IS" BASIS,
131757  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131758  * See the License for the specific language governing permissions and
131759  * limitations under the License.
131760  */
131761 var utils = require('ripple/utils'),
131762     _select,
131763     _predicates = {
131764         "==": function (left, right) {
131765             return left === right;
131766         },
131767         "!=": function (left, right) {
131768             return left !== right;
131769         },
131770         "<": function (left, right) {
131771             return left < right;
131772         },
131773         ">": function (left, right) {
131774             return left > right;
131775         },
131776         "<=": function (left, right) {
131777             return left <= right;
131778         },
131779         ">=": function (left, right) {
131780             return left >= right;
131781         },
131782         "REGEX": function (left, right) {
131783             return left && left.match(new RegExp(right));
131784         },
131785         "CONTAINS": function (left, right) {
131786             return left.indexOf(right) >= 0;
131787         }
131788     };
131789
131790 function isFilter(field) {
131791     return field && field.operator !== undefined && field.operator !== null;
131792 }
131793
131794 function extractValue(item, field) {
131795     return field.split(".").reduce(function (value, prop) {
131796         return value[prop];
131797     }, item);
131798 }
131799
131800 function copy(items) {
131801     //use a reduce to ensure that we always just return an array
131802     //not the most performant but will whitewash the result
131803     return utils.reduce(items, function (array, item) {
131804         array.push(item);
131805         return array;
131806     }, []);
131807 }
131808
131809 _select = {
131810     ops: {
131811         find: {
131812             0: "!=",
131813             1: "==",
131814             2: "<",
131815             3: "<=",
131816             4: ">",
131817             5: ">=",
131818             8: "REGEX",
131819             16: "AND",
131820             32: "OR",
131821             64: "CONTAINS"
131822         },
131823         phone: {
131824             0: "!=",
131825             1: "==",
131826             2: "<",
131827             3: "<=",
131828             4: ">",
131829             5: ">=",
131830             8: "AND",
131831             16: "OR",
131832             32: "CONTAINS"
131833         }
131834     },
131835     from: function (items) {
131836         var _getPredicate = function (filter, operators) {
131837
131838                 var noOp = function () {
131839                         return false;
131840                     },
131841                     operator = (function () {
131842                         var result = operators[filter.operator] || filter.operator,
131843                             exists = function (op) {
131844                                 return result === op;
131845                             };
131846
131847                         return utils.some(operators, exists) ? result : "";
131848                     }());
131849
131850                 return function (item) {
131851                     var left = extractValue(item, filter.leftField),
131852                         right = filter.rightField,
131853                         predicate = _predicates[operator] || noOp;
131854
131855                     return filter.negate ? !predicate(left, right) : predicate(left, right);
131856                 };
131857
131858             },
131859             _applyFilter = function (filter, operators) {
131860                 var result = [],
131861                     left,
131862                     right,
131863                     op;
131864
131865                 if (isFilter(filter.leftField) && isFilter(filter.rightField)) {
131866
131867                     left = _select.from(items).where(filter.leftField);
131868                     right = _select.from(items).where(filter.rightField);
131869                     op = operators[filter.operator] || filter.operator;
131870
131871                     switch (op) {
131872                     case "AND":
131873                         result = left.filter(function (item) {
131874                             return right.indexOf(item) >= 0;
131875                         });
131876                         break;
131877                     case "OR":
131878                         result = left.concat(right.filter(function (item) {
131879                             return left.indexOf(item) < 0;
131880                         }));
131881                         break;
131882                     }
131883
131884                     if (filter.negate) {
131885                         //reverse the result set.
131886                         result = utils.filter(items, function (item) {
131887                             return result.indexOf(item) < 0;
131888                         });
131889                     }
131890                 }
131891                 else {
131892                     result = utils.filter(items, _getPredicate(filter, operators));
131893                 }
131894
131895                 return result;
131896             },
131897             _orderBy,
131898             _max,
131899             _direction,
131900             _self = {
131901                 orderBy: function (prop, dir) {
131902                     _orderBy = prop;
131903                     _direction = dir || "asc";
131904                     return _self;
131905                 },
131906                 max: function (max) {
131907                     _max = max;
131908                     return _self;
131909                 },
131910                 where: function (filter, ops) {
131911                     var result = isFilter(filter) ? _applyFilter(filter, ops || _select.ops.find) : copy(items);
131912
131913                     result.sort(function (a, b) {
131914                         if (a[_orderBy] < b[_orderBy]) {
131915                             return _direction === "asc" ? -1 : 1;
131916                         }
131917                         else if (a[_orderBy] > b[_orderBy]) {
131918                             return _direction === "asc" ? 1: -1;
131919                         }
131920                         return 0;
131921                     });
131922
131923                     return result.slice(0, _max === null || _max === -1 ? undefined : _max); // slice in V8 returns empty array if null
131924                 }
131925             };
131926
131927         return _self;
131928     }
131929 };
131930
131931 module.exports = _select;
131932
131933 });
131934 define('ripple/platform/webworks.core/2.0.0/server/dialog', function (require, exports, module) {
131935 /*
131936  *  Copyright 2011 Research In Motion Limited.
131937  *
131938  * Licensed under the Apache License, Version 2.0 (the "License");
131939  * you may not use this file except in compliance with the License.
131940  * You may obtain a copy of the License at
131941  *
131942  * http://www.apache.org/licenses/LICENSE-2.0
131943  *
131944  * Unless required by applicable law or agreed to in writing, software
131945  * distributed under the License is distributed on an "AS IS" BASIS,
131946  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131947  * See the License for the specific language governing permissions and
131948  * limitations under the License.
131949  */
131950 var event = require('ripple/event'),
131951     devices = require('ripple/devices'),
131952     ui = require('ripple/ui'),
131953     utils = require('ripple/utils'),
131954     isDialogVisible = false,
131955     visibleDialogArgs,
131956     _self;
131957
131958 function closeDialog() {
131959     var buttonsDiv = document.getElementById("dialog-buttons"),
131960         messageDiv = document.getElementById("dialog-message");
131961
131962     ui.hideOverlay("dialog-window", function (dialog) {
131963         buttonsDiv.innerHTML = "";
131964         messageDiv.innerHTML = "";
131965         isDialogVisible = false;
131966     });
131967 }
131968
131969 event.on("LayoutChanged", function () {
131970     if (isDialogVisible) {
131971         closeDialog();
131972         //Used to resize dialog on orientation change
131973         _self.ask(visibleDialogArgs);
131974     }
131975 });
131976
131977 _self = {
131978
131979     ask: function (args, post, baton) {
131980         if (!args) {
131981             throw ("No arguments provided");
131982         } else if (!args.buttons || !args.message) {
131983             throw ("Invalid arguments");
131984         }
131985         baton.take();
131986         visibleDialogArgs = args;
131987
131988         ui.showOverlay("dialog-window", function (dialog) {
131989             var container = document.getElementById("viewport-container"),
131990                 height = window.getComputedStyle(container, null).getPropertyValue("height"),
131991                 width = window.getComputedStyle(container, null).getPropertyValue("width"),
131992                 sizeDiv = document.getElementById("dialog-wrapper"),
131993                 positionDiv = document.getElementById("dialog-window"),
131994                 titleDiv = document.getElementById("dialog-title"),
131995                 buttonsDiv = document.getElementById("dialog-buttons"),
131996                 messageDiv = document.getElementById("dialog-message"),
131997                 position, size;
131998
131999             if (!messageDiv || !buttonsDiv) {
132000                 return;
132001             }
132002
132003             dialog.setAttribute("style", "display:-webkit-box;height:" + height + "; width:" + width + ";");
132004
132005             position = "overlay-dialog";
132006             size = "overlay-dialog-wrapper";
132007
132008             if (args.settings && args.settings.position) {
132009                 position += " overlay-dialog-" + args.settings.position;
132010             }
132011
132012             if (args.settings && args.settings.size) {
132013                 size += " overlay-dialog-wrapper-" + args.settings.size;
132014             }
132015
132016             positionDiv.setAttribute("class", position);
132017             sizeDiv.setAttribute("class", size);
132018
132019             titleDiv.innerHTML = args.settings && args.settings.title ? args.settings.title : "";
132020             messageDiv.innerHTML = args.message;
132021             isDialogVisible = true;
132022
132023             args.buttons.forEach(function (button) {
132024                 var buttonElement = utils.createElement("input", {
132025                     "type": "button",
132026                     "value": button
132027                 });
132028                 buttonElement.addEventListener("click", function () {
132029                     var buttonIndex = args.buttons.indexOf(button);
132030                     closeDialog();
132031                     baton.pass({code: 1, data: buttonIndex});
132032                 });
132033                 buttonsDiv.appendChild(buttonElement);
132034             });
132035         }, true);
132036     }
132037 };
132038
132039 module.exports = _self;
132040
132041 });
132042 define('ripple/platform/webworks.core/2.0.0/server/io/dir', function (require, exports, module) {
132043 /*
132044  * Copyright 2011 Research In Motion Limited.
132045  *
132046  * Licensed under the Apache License, Version 2.0 (the "License");
132047  * you may not use this file except in compliance with the License.
132048  * You may obtain a copy of the License at
132049  *
132050  *     http://www.apache.org/licenses/LICENSE-2.0
132051  *
132052  * Unless required by applicable law or agreed to in writing, software
132053  * distributed under the License is distributed on an "AS IS" BASIS,
132054  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132055  * See the License for the specific language governing permissions and
132056  * limitations under the License.
132057  */
132058 var cache = require('ripple/platform/webworks.core/2.0.0/fsCache');
132059
132060 function _packet(data) {
132061     return {
132062         code: 1,
132063         data: data
132064     };
132065 }
132066
132067 module.exports = {
132068     createNewDir: function (get, post, baton) {
132069         cache.dir.createNewDir(post.path);
132070         return _packet();
132071     },
132072     deleteDirectory: function (get, post, baton) {
132073         cache.dir.deleteDirectory(post.path, post.recursive);
132074         return _packet();
132075     },
132076     exists: function (get, post, baton) {
132077         return _packet(cache.dir.exists(post.path));
132078     },
132079     getParentDirectory: function (get, post, baton) {
132080         return _packet(cache.dir.getParentDirectory(post.path));
132081     },
132082     listDirectories: function (get, post, baton) {
132083         return _packet(cache.dir.listDirectories(post.path));
132084     },
132085     listFiles: function (get, post, baton) {
132086         return _packet(cache.dir.listFiles(post.path));
132087     },
132088     rename: function (get, post, baton) {
132089         cache.dir.rename(post.path, post.newName);
132090         return _packet();
132091     }
132092 };
132093
132094 });
132095 define('ripple/platform/webworks.core/2.0.0/server/io/file', function (require, exports, module) {
132096 /*
132097  *  Copyright 2011 Research In Motion Limited.
132098  *
132099  * Licensed under the Apache License, Version 2.0 (the "License");
132100  * you may not use this file except in compliance with the License.
132101  * You may obtain a copy of the License at
132102  *
132103  * http://www.apache.org/licenses/LICENSE-2.0
132104  *
132105  * Unless required by applicable law or agreed to in writing, software
132106  * distributed under the License is distributed on an "AS IS" BASIS,
132107  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132108  * See the License for the specific language governing permissions and
132109  * limitations under the License.
132110  */
132111 var cache = require('ripple/platform/webworks.core/2.0.0/fsCache'),
132112     constants = require('ripple/constants'),
132113     notifications = require('ripple/notifications');
132114
132115 function _packet(data) {
132116     return {
132117         code: 1,
132118         data: data
132119     };
132120 }
132121
132122 module.exports = {
132123     copy: function (get, post, baton) {
132124         cache.file.copy(post.from, post.to);
132125         return _packet();
132126     },
132127     deleteFile: function (get, post, baton) {
132128         cache.file.deleteFile(post.path);
132129         return _packet();
132130     },
132131     exists: function (get, post, baton) {
132132         return _packet(cache.file.exists(post.path));
132133     },
132134     getFileProperties: function (get, post, baton) {
132135         return _packet(cache.file.getFileProperties(post.path));
132136     },
132137     open: function (get, post, baton) {
132138         var msg = "Attempting to open file: " + post.path;
132139         notifications.openNotification("normal", msg);
132140         return _packet(cache.file.exists(post.path));
132141     },
132142     readFile: function (get, post, baton) {
132143         var val;
132144
132145         if (post.async) {
132146             baton.take();
132147         }
132148
132149         cache.file.readFile(post.path, function (data) {
132150             if (post.async) {
132151                 baton.pass(_packet({
132152                     fullPath: post.path,
132153                     blobData: data
132154                 }));
132155             } else {
132156                 val = data;
132157             }
132158         }, post.async);
132159
132160         if (!post.async) {
132161             return _packet({
132162                 fullPath: post.path,
132163                 blobData: val
132164             });
132165         }
132166     },
132167     rename: function (get, post, baton) {
132168         cache.file.rename(post.path, post.newName);
132169         return _packet();
132170     },
132171     saveFile: function (get, post, baton) {
132172         cache.file.saveFile(post.path, post.blob);
132173         return _packet();
132174     }
132175 };
132176
132177 });
132178 define('ripple/platform/webworks.core/2.0.0/server/system', function (require, exports, module) {
132179 /*
132180  *  Copyright 2011 Research In Motion Limited.
132181  *
132182  * Licensed under the Apache License, Version 2.0 (the "License");
132183  * you may not use this file except in compliance with the License.
132184  * You may obtain a copy of the License at
132185  *
132186  * http://www.apache.org/licenses/LICENSE-2.0
132187  *
132188  * Unless required by applicable law or agreed to in writing, software
132189  * distributed under the License is distributed on an "AS IS" BASIS,
132190  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132191  * See the License for the specific language governing permissions and
132192  * limitations under the License.
132193  */
132194 var deviceSettings = require('ripple/deviceSettings'),
132195     devices = require('ripple/devices'),
132196     app = require('ripple/app'),
132197     client = require('ripple/platform/webworks.core/2.0.0/client/system'),
132198     utils = require('ripple/utils'),
132199     notifications = require('ripple/notifications'),
132200     constants = require('ripple/constants'),
132201     platform = require('ripple/platform'),
132202     _self;
132203
132204 function _is(feature) {
132205     return {
132206         allowedFor: function (location) {
132207             return feature && feature.URIs.some(function (uri) {
132208                 return uri.value === location ||
132209                       (location.indexOf(uri.value) >= 0 && uri.subdomains);
132210             });
132211         }
132212     };
132213 }
132214
132215 _self = {
132216     hasCapability: function (args) {
132217         var capabilities = devices.getCurrentDevice().capabilities;
132218         return {
132219             code: 1,
132220             data: capabilities ? capabilities.some(function (type) {
132221                 return type === args.capability;
132222             }) : false
132223         };
132224     },
132225     isMassStorageActive: function () {
132226         return {code: 1, data: deviceSettings.retrieveAsBoolean("system.isMassStorageActive")};
132227     },
132228     hasDataCoverage: function () {
132229         return {code: 1, data: deviceSettings.retrieveAsBoolean("system.hasDataCoverage")};
132230     },
132231     softwareVersion: function () {
132232         return {code: 1, data: devices.getCurrentDevice().osVersion};
132233     },
132234     model: function () {
132235         return {code: 1, data: devices.getCurrentDevice().model};
132236     },
132237     scriptApiVersion: function () {
132238         return {code: 1, data: platform.current().version};
132239     },
132240     setHomeScreenBackground: function (args) {
132241         var path = args.filePath,
132242             msg = "Set home screen background to " + path + ".";
132243         notifications.openNotification("normal", msg);
132244         return {code: 1};
132245     },
132246     hasPermission: function (args) {
132247         var info = app.getInfo(),
132248             feature = info.features ? info.features[args.desiredModule] : null;
132249
132250         return {code: 1, data: feature === null || _is(feature).allowedFor(utils.location().href) ? client.ALLOW : client.DENY};
132251     },
132252     network: function () {
132253         return {code: 1, data: deviceSettings.retrieve("system.network")};
132254     }
132255 };
132256
132257 module.exports = _self;
132258
132259 });
132260 define('ripple/platform/webworks.core/2.0.0/spec/config', function (require, exports, module) {
132261 /*
132262  *  Copyright 2011 Research In Motion Limited.
132263  *
132264  * Licensed under the Apache License, Version 2.0 (the "License");
132265  * you may not use this file except in compliance with the License.
132266  * You may obtain a copy of the License at
132267  *
132268  * http://www.apache.org/licenses/LICENSE-2.0
132269  *
132270  * Unless required by applicable law or agreed to in writing, software
132271  * distributed under the License is distributed on an "AS IS" BASIS,
132272  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132273  * See the License for the specific language governing permissions and
132274  * limitations under the License.
132275  */
132276 var utils = require('ripple/utils');
132277
132278 module.exports = {
132279     fileName: "config.xml",
132280     validateVersion: function (config) {
132281         return true;
132282     },
132283     extractInfo: function (config) {
132284         if (!config) {
132285             return null;
132286         }
132287
132288         var widgetInfo = {},
132289             widgetFeatures = config.widget.children.feature.validationResult,
132290             accessUrls = config.widget.children.access.validationResult,
132291             accessFeatures = config.widget.children.access.children.feature.validationResult,
132292             toFeature = function (validationResult) {
132293                 return {
132294                     id: validationResult.attributes.id.value,
132295                     required: !validationResult.attributes.required || validationResult.attributes.required.value,
132296                     URIs: []
132297                 };
132298             };
132299
132300         widgetInfo.id = config.widget.validationResult[0].attributes.id.value;
132301         widgetInfo.name = config.widget.children.name.validationResult[0].value;
132302         widgetInfo.icon = config.widget.children.icon.validationResult[0].attributes.src.value;
132303         widgetInfo.version = config.widget.validationResult[0].attributes.version.value;
132304         widgetInfo.author = config.widget.children.author.validationResult[0].value;
132305         widgetInfo.authorEmail = config.widget.children.author.validationResult[0].attributes.email.value;
132306         widgetInfo.authorURL = config.widget.children.author.validationResult[0].attributes.href.value;
132307         widgetInfo.copyright = config.widget.children.author.validationResult[0].attributes["rim:copyright"].value;
132308         widgetInfo.description = config.widget.children.description.validationResult[0].value;
132309         if (config.widget.children.license.validationResult[0]) {
132310             widgetInfo.license = config.widget.children.license.validationResult[0].value;
132311             widgetInfo.licenseURL = config.widget.children.license.validationResult[0].attributes.href.value;
132312         }
132313
132314         widgetInfo.features = widgetFeatures.reduce(function (features, validationResult) {
132315             if (validationResult.valid) {
132316                 var feature = toFeature(validationResult);
132317                 feature.URIs.push({
132318                     value: utils.location().href,
132319                     subdomains: true
132320                 });
132321                 features = features || {};
132322                 features[feature.id] = feature;
132323             }
132324             return features;
132325         }, {});
132326
132327         widgetInfo.features = accessUrls.map(function (access) {
132328             return {
132329                 uri: access.attributes.uri.value,
132330                 subdomains: access.attributes.subdomains.value,
132331                 features: accessFeatures ? accessFeatures.filter(function (f) {
132332                     return f.node && f.node.parentNode && f.node.parentNode.attributes.uri.value === access.attributes.uri.value;
132333                 }) : null
132334             };
132335         }).reduce(function (result, access) {
132336             return access.features ? access.features.reduce(function (features, validationResult) {
132337                 var feature = features[validationResult.attributes.id.value] || toFeature(validationResult);
132338                 feature.URIs.push({
132339                     value: access.uri,
132340                     subdomains: access.subdomains
132341                 });
132342                 features[feature.id] = feature;
132343                 return features;
132344             }, result) : result;
132345         }, widgetInfo.features);
132346
132347         return widgetInfo;
132348     },
132349     schema: {
132350         rootElement: "widget",
132351         widget: {
132352             nodeName: "widget",
132353             required: true,
132354             occurrence: 1,
132355             attributes: {
132356                 xmlns: {
132357                     attributeName: "xmlns",
132358                     required: true,
132359                     type: "list",
132360                     listValues: ["http://www.w3.org/ns/widgets"]
132361                 },
132362                 "xmlns:rim": {
132363                     attributeName: "xmlns:rim",
132364                     required: true,
132365                     type: "list",
132366                     listValues: ["http://www.blackberry.com/ns/widgets"]
132367                 },
132368                 "xml:lang": {
132369                     attributeName: "xml:lang",
132370                     required: false,
132371                     type: "iso-language"
132372                 },
132373                 id: {
132374                     attributeName: "id",
132375                     required: false,
132376                     type: "string"
132377                 },
132378                 version: {
132379                     attributeName: "version",
132380                     required: false,
132381                     type: "string"
132382                 },
132383                 "rim:header": {
132384                     attributeName: "rim:header",
132385                     required: false,
132386                     type: "string"
132387                 },
132388                 "rim:backButton": {
132389                     attributeName: "rim:backButton",
132390                     required: false,
132391                     type: "string"
132392                 }
132393             },
132394             children: {
132395                 name: {
132396                     nodeName: "name",
132397                     required: true,
132398                     occurrence: 1,
132399                     attributes: {
132400                         "xml:lang": {
132401                             attributeName: "xml:lang",
132402                             required: false,
132403                             type: "iso-language"
132404                         },
132405                         "its:dir": {
132406                             attributeName: "its:dir",
132407                             required: false,
132408                             type: "list",
132409                             listValues: ["rtl", "ltr", "lro", "rlo"]
132410                         }
132411                     }
132412                 },
132413                 description: {
132414                     nodeName: "description",
132415                     required: false,
132416                     occurrence: 1,
132417                     attributes: {
132418                         "xml:lang": {
132419                             attributeName: "xml:lang",
132420                             required: false,
132421                             type: "iso-language"
132422                         },
132423                         "its:dir": {
132424                             attributeName: "its:dir",
132425                             required: false,
132426                             type: "list",
132427                             listValues: ["rtl", "ltr", "lro", "rlo"]
132428                         }
132429                     }
132430                 },
132431                 icon: {
132432                     nodeName: "icon",
132433                     required: false,
132434                     occurrence: 0,
132435                     attributes: {
132436                         src: {
132437                             attributeName: "src",
132438                             type: "string",
132439                             required: true
132440                         },
132441                         "rim:hover": {
132442                             attributeName: "rim:hover",
132443                             type: "boolean",
132444                             required: false
132445                         }
132446                     }
132447                 },
132448                 author: {
132449                     nodeName: "author",
132450                     required: false,
132451                     occurrence: 1,
132452                     attributes: {
132453                         href: {
132454                             attributeName: "href",
132455                             type: "string",
132456                             required: false
132457                         },
132458                         "rim:copyright": {
132459                             attributeName: "rim:copyright",
132460                             type: "string",
132461                             required: false
132462                         },
132463                         email: {
132464                             attributeName: "email",
132465                             type: "string",
132466                             required: false
132467                         },
132468                         "xml:lang": {
132469                             attributeName: "xml:lang",
132470                             required: false,
132471                             type: "iso-language"
132472                         },
132473                         "its:dir": {
132474                             attributeName: "its:dir",
132475                             required: false,
132476                             type: "list",
132477                             listValues: ["rtl", "ltr", "lro", "rlo"]
132478                         }
132479                     }
132480                 },
132481                 license: {
132482                     nodeName: "license",
132483                     required: false,
132484                     occurrence: 1,
132485                     attributes : {
132486                         href: {
132487                             attributeName: "href",
132488                             type: "string",
132489                             required: false
132490                         },
132491                         "xml:lang": {
132492                             attributeName: "xml:lang",
132493                             required: false,
132494                             type: "iso-language"
132495                         },
132496                         "its:dir": {
132497                             attributeName: "its:dir",
132498                             required: false,
132499                             type: "list",
132500                             listValues: ["rtl", "ltr", "lro", "rlo"]
132501                         }
132502                     }
132503                 },
132504                 "rim:cache": {
132505                     nodeName: "rim:cache",
132506                     required: false,
132507                     occurrence: 1,
132508                     attributes: {
132509                         disableAllCache: {
132510                             attributeName: "disableAllCache",
132511                             required: false,
132512                             type: "boolean"
132513                         },
132514                         aggressiveCacheAge: {
132515                             attributeName: "aggressiveCacheAge",
132516                             required: false,
132517                             type: "number"
132518                         },
132519                         maxCacheSizeTotal: {
132520                             attributeName: "maxCacheSizeTotal",
132521                             required: false,
132522                             type: "number"
132523                         },
132524                         maxCacheSizeItem: {
132525                             attributeName: "maxCacheSizeItem",
132526                             required: false,
132527                             type: "number"
132528                         }
132529                     }
132530                 },
132531                 access: {
132532                     nodeName: "access",
132533                     required: false,
132534                     occurrence: 0,
132535                     attributes: {
132536                         uri: {
132537                             attributeName: "uri",
132538                             required: true,
132539                             type: "string"
132540                         },
132541                         subdomains: {
132542                             attributeName: "subdomains",
132543                             required: false,
132544                             type: "boolean"
132545                         }
132546                     },
132547                     children: {
132548                         feature: {
132549                             nodeName: "feature",
132550                             required: false,
132551                             occurrence: 0,
132552                             attributes: {
132553                                 id: {
132554                                     attributeName: "id",
132555                                     required: true,
132556                                     //TODO: this should be a list
132557                                     type: "string"
132558                                 },
132559                                 required: {
132560                                     attributeName: "required",
132561                                     required: false,
132562                                     type: "boolean"
132563                                 },
132564                                 version: {
132565                                     attributeName: "version",
132566                                     required: false,
132567                                     type: "string"
132568                                 }
132569                             }
132570                         }
132571                     }
132572                 },
132573                 feature: {
132574                     nodeName: "feature",
132575                     required: false,
132576                     occurrence: 0,
132577                     attributes: {
132578                         id: {
132579                             attributeName: "id",
132580                             required: true,
132581                             //TODO: this should be a list
132582                             type: "string"
132583                         },
132584                         required: {
132585                             attributeName: "required",
132586                             required: false,
132587                             type: "boolean"
132588                         },
132589                         version: {
132590                             attributeName: "version",
132591                             required: false,
132592                             type: "string"
132593                         }
132594                     }
132595                 },
132596                 "rim:loadingScreen": {
132597                     nodeName: "rim:loadingScreen",
132598                     required: false,
132599                     occurrence: 1,
132600                     attributes: {
132601                         backgroundColor: {
132602                             attributeName: "backgroundColor",
132603                             required: false,
132604                             type: "string"
132605                         },
132606                         backgroundImage: {
132607                             attributeName: "backgroundImage",
132608                             required: false,
132609                             type: "string"
132610                         },
132611                         foregroundImage: {
132612                             attributeName: "foregroundImage",
132613                             required: false,
132614                             type: "string"
132615                         },
132616                         onRemotePageLoad: {
132617                             attributeName: "onRemotePageLoad",
132618                             required: false,
132619                             type: "boolean"
132620                         },
132621                         onLocalPageLoad: {
132622                             attributeName: "onLocalPageLoad",
132623                             required : false,
132624                             type: "boolean"
132625                         },
132626                         onFirstLaunch: {
132627                             attributeName: "onFirstLaunch",
132628                             required: false,
132629                             type: "boolean"
132630                         }
132631                     },
132632                     children: {
132633                         "rim:transitionEffect": {
132634                             nodeName: "rim:transitionEffect",
132635                             required: false,
132636                             occurrence: 1,
132637                             attributes: {
132638                                 "type": {
132639                                     attributeName: "type",
132640                                     required: true,
132641                                     type: "list",
132642                                     listValues: ["slidePush", "slideOver", "fadeIn", "fadeOut", "wipeIn", "wipeOut", "zoomIn", "zoomOut"]
132643                                 },
132644                                 duration: {
132645                                     attributeName: "duration",
132646                                     required: false,
132647                                     type: "number"
132648                                 },
132649                                 direction: {
132650                                     attributeName: "direction",
132651                                     required: false,
132652                                     type: "list",
132653                                     listValues: ["left", "right", "up", "down"]
132654                                 }
132655                             }
132656                         }
132657                     }
132658                 },
132659                 "rim:connection": {
132660                     nodeName: "rim:connection",
132661                     required: false,
132662                     occurrence: 1,
132663                     attributes: {
132664                         timeout: {
132665                             attributeName: "timeout",
132666                             required: false,
132667                             type: "number"
132668                         }
132669                     },
132670                     children: {
132671                         id: {
132672                             nodeName: "id",
132673                             required: false,
132674                             occurrence: 0
132675                         }
132676                     }
132677                 },
132678                 "rim:navigation": {
132679                     nodeName: "rim:navigation",
132680                     required: false,
132681                     occurrence: 1,
132682                     attributes: {
132683                         mode: {
132684                             attributeName: "mode",
132685                             required: false,
132686                             type: "list",
132687                             listValues: ["focus"]
132688                         }
132689                     }
132690                 },
132691                 "content": {
132692                     nodeName: "content",
132693                     required: true,
132694                     occurrence: 1,
132695                     attributes: {
132696                         src: {
132697                             attributeName: "src",
132698                             required: true,
132699                             type: "string"
132700                         },
132701                         type: {
132702                             attributeName: "type",
132703                             required: false,
132704                             type: "string"
132705                         },
132706                         charset: {
132707                             attributeName: "charset",
132708                             required: false,
132709                             type: "string"
132710                         }
132711                     }
132712                 }
132713             }
132714         }
132715     }
132716 };
132717
132718 });
132719 define('ripple/platform/webworks.core/2.0.0/spec/events', function (require, exports, module) {
132720 /*
132721  *  Copyright 2011 Research In Motion Limited.
132722  *
132723  * Licensed under the Apache License, Version 2.0 (the "License");
132724  * you may not use this file except in compliance with the License.
132725  * You may obtain a copy of the License at
132726  *
132727  * http://www.apache.org/licenses/LICENSE-2.0
132728  *
132729  * Unless required by applicable law or agreed to in writing, software
132730  * distributed under the License is distributed on an "AS IS" BASIS,
132731  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132732  * See the License for the specific language governing permissions and
132733  * limitations under the License.
132734  */
132735 var event = require('ripple/event');
132736
132737 module.exports = {
132738     "app.event.onBackground": {
132739         callback: function () {
132740             event.trigger("AppRequestBackground");
132741         }
132742     },
132743     "app.event.onForeground": {
132744         callback: function () {
132745             event.trigger("AppRequestForeground");
132746         }
132747     }
132748 };
132749
132750 });
132751 define('ripple/platform/webworks.handset/2.0.0/XMLHttpRequest', function (require, exports, module) {
132752 /*
132753  *  Copyright 2011 Research In Motion Limited.
132754  *
132755  * Licensed under the Apache License, Version 2.0 (the "License");
132756  * you may not use this file except in compliance with the License.
132757  * You may obtain a copy of the License at
132758  *
132759  * http://www.apache.org/licenses/LICENSE-2.0
132760  *
132761  * Unless required by applicable law or agreed to in writing, software
132762  * distributed under the License is distributed on an "AS IS" BASIS,
132763  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132764  * See the License for the specific language governing permissions and
132765  * limitations under the License.
132766  */
132767
132768 var xhr = require("ripple/platform/webworks.core/2.0.0/XMLHttpRequest");
132769 module.exports = xhr.create("ripple/platform/webworks.handset/2.0.0/server");
132770
132771 });
132772 define('ripple/platform/webworks.handset/2.0.0/client/Address', function (require, exports, module) {
132773 /*
132774  *  Copyright 2011 Research In Motion Limited.
132775  *
132776  * Licensed under the Apache License, Version 2.0 (the "License");
132777  * you may not use this file except in compliance with the License.
132778  * You may obtain a copy of the License at
132779  *
132780  * http://www.apache.org/licenses/LICENSE-2.0
132781  *
132782  * Unless required by applicable law or agreed to in writing, software
132783  * distributed under the License is distributed on an "AS IS" BASIS,
132784  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132785  * See the License for the specific language governing permissions and
132786  * limitations under the License.
132787  */
132788 function Address() {
132789     return {
132790         //readwrite  property  String   address1
132791         //readwrite  property  String   address2
132792         //readwrite  property  String   city
132793         //readwrite  property  String   country
132794         //readwrite  property  String   stateProvince
132795         //readwrite  property  String   zipPostal
132796
132797         address1: null,
132798         address2: null,
132799         city: null,
132800         country: null,
132801         stateProvince: null,
132802         zipPostal: null
132803     };
132804 }
132805
132806 module.exports = Address;
132807
132808 });
132809 define('ripple/platform/webworks.handset/2.0.0/client/AddressBookArguments', function (require, exports, module) {
132810 /*
132811  *  Copyright 2011 Research In Motion Limited.
132812  *
132813  * Licensed under the Apache License, Version 2.0 (the "License");
132814  * you may not use this file except in compliance with the License.
132815  * You may obtain a copy of the License at
132816  *
132817  * http://www.apache.org/licenses/LICENSE-2.0
132818  *
132819  * Unless required by applicable law or agreed to in writing, software
132820  * distributed under the License is distributed on an "AS IS" BASIS,
132821  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132822  * See the License for the specific language governing permissions and
132823  * limitations under the License.
132824  */
132825 //blackberry.invoke.AddressBookArguments ( [contact : blackberry.pim.Contact ] )
132826 var _self = function (contact) {
132827     return {
132828         contact: contact,
132829         //readwrite  property  Number   view
132830         view: 0
132831     };
132832 };
132833
132834 //const Number  VIEW_NEW  = 0
132835 _self.__defineGetter__("VIEW_NEW", function () {
132836     return 0;
132837 });
132838 //const Number  VIEW_COMPOSE  = 1
132839 _self.__defineGetter__("VIEW_COMPOSE", function () {
132840     return 1;
132841 });
132842 //const Number  VIEW_DISPLAY  = 2
132843 _self.__defineGetter__("VIEW_DISPLAY", function () {
132844     return 2;
132845 });
132846
132847 module.exports = _self;
132848
132849 });
132850 define('ripple/platform/webworks.handset/2.0.0/client/Appointment', function (require, exports, module) {
132851 /*
132852  *  Copyright 2011 Research In Motion Limited.
132853  *
132854  * Licensed under the Apache License, Version 2.0 (the "License");
132855  * you may not use this file except in compliance with the License.
132856  * You may obtain a copy of the License at
132857  *
132858  * http://www.apache.org/licenses/LICENSE-2.0
132859  *
132860  * Unless required by applicable law or agreed to in writing, software
132861  * distributed under the License is distributed on an "AS IS" BASIS,
132862  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132863  * See the License for the specific language governing permissions and
132864  * limitations under the License.
132865  */
132866 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
132867     utils = require('ripple/utils'),
132868     _uri = "blackberry/pim/appointment/";
132869
132870 function Appointment(service) {
132871     var _self = {
132872         allDay: false,
132873         attendees: [],
132874         end: null,
132875         freeBusy: null,
132876         location: null,
132877         note: null,
132878         recurrence: null,
132879         reminder: null,
132880         start: null,
132881         summary: null,
132882         uid: null,
132883         remove: function () {
132884             transport.call(_uri + "remove", {get: {uid: _self.uid}});
132885         },
132886         save: function () {
132887             if (_self.uid === null) {
132888                 _self.uid  = Number(Math.uuid(8, 10));
132889             }
132890             transport.call(_uri + "save", {post: {appointment: _self}});
132891         }
132892     };
132893
132894     return _self;
132895 }
132896
132897 function _massage(property, name) {
132898     if (name === "recurrence" && property) {
132899         if (property.end) {
132900             property.end = new Date(property.end);
132901         }
132902     }
132903     if (name === "reminder" && property) {
132904         if (property.date) {
132905             property.date = new Date(property.date);
132906         }
132907     }
132908     if ((name === "end" || name === "start") && property) {
132909         property = new Date(property);
132910     }
132911     return property;
132912 }
132913
132914 Appointment.find = function (filter, orderBy, maxReturn, service, isAscending) {
132915     var opts = {
132916         post: {
132917             filter: filter,
132918             orderBy: orderBy,
132919             maxReturn: maxReturn,
132920             service: service,
132921             isAscending: isAscending
132922         }
132923     };
132924
132925     return transport.call(_uri + "find", opts).map(function (obj) {
132926         var appt = new Appointment();
132927         appt.allDay = obj.allDay;
132928         appt.attendees = obj.attendees;
132929         appt.end = _massage(obj.end, "end");
132930         appt.freeBusy = obj.freeBusy;
132931         appt.location = obj.location;
132932         appt.note = obj.note;
132933         appt.recurrence = _massage(obj.recurrence, "recurrence");
132934         appt.reminder = _massage(obj.reminder, "reminder");
132935         appt.start = _massage(obj.start, "start");
132936         appt.summary = obj.summary;
132937         appt.uid = obj.uid;
132938         return appt;
132939     });
132940 };
132941
132942 Appointment.__defineGetter__("FREE", function () {
132943     return 0;
132944 });
132945 Appointment.__defineGetter__("TENTATIVE", function () {
132946     return 1;
132947 });
132948 Appointment.__defineGetter__("BUSY", function () {
132949     return 2;
132950 });
132951 Appointment.__defineGetter__("OUT_OF_OFFICE", function () {
132952     return 3;
132953 });
132954
132955 module.exports = Appointment;
132956
132957 });
132958 define('ripple/platform/webworks.handset/2.0.0/client/Attendee', function (require, exports, module) {
132959 /*
132960  *  Copyright 2011 Research In Motion Limited.
132961  *
132962  * Licensed under the Apache License, Version 2.0 (the "License");
132963  * you may not use this file except in compliance with the License.
132964  * You may obtain a copy of the License at
132965  *
132966  * http://www.apache.org/licenses/LICENSE-2.0
132967  *
132968  * Unless required by applicable law or agreed to in writing, software
132969  * distributed under the License is distributed on an "AS IS" BASIS,
132970  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132971  * See the License for the specific language governing permissions and
132972  * limitations under the License.
132973  */
132974 function Attendee() {
132975     return {
132976         //readwrite  property  String   address
132977         //readwrite  property  Number   type
132978
132979         address: null,
132980         type: null
132981     };
132982 }
132983
132984 Attendee.__defineGetter__("ORGANIZER", function () {
132985     return 0;
132986 });
132987
132988 Attendee.__defineGetter__("INVITED", function () {
132989     return 1;
132990 });
132991
132992 Attendee.__defineGetter__("ACCEPTED", function () {
132993     return 2;
132994 });
132995
132996 Attendee.__defineGetter__("DECLINED", function () {
132997     return 3;
132998 });
132999
133000 Attendee.__defineGetter__("TENTATIVE", function () {
133001     return 4;
133002 });
133003
133004 module.exports =  Attendee;
133005
133006 });
133007 define('ripple/platform/webworks.handset/2.0.0/client/AudioPlayer', function (require, exports, module) {
133008 /*
133009  *  Copyright 2011 Research In Motion Limited.
133010  *
133011  * Licensed under the Apache License, Version 2.0 (the "License");
133012  * you may not use this file except in compliance with the License.
133013  * You may obtain a copy of the License at
133014  *
133015  * http://www.apache.org/licenses/LICENSE-2.0
133016  *
133017  * Unless required by applicable law or agreed to in writing, software
133018  * distributed under the License is distributed on an "AS IS" BASIS,
133019  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133020  * See the License for the specific language governing permissions and
133021  * limitations under the License.
133022  */
133023 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
133024     _uri = "blackberry/audio/player/";
133025
133026 function Player(locator, type, async) {
133027     //we can't use the async prop since we need the ID before we can do anything else.
133028     var _id = transport.call(_uri + "create", {
133029             get: {locator: locator, type: type},
133030             async: false
133031         }),
133032         _listener,
133033         _closed,
133034         _self,
133035         _poll = function (path) {
133036             transport.poll(_uri + path, {
133037                 get: {id: _id}
133038             }, function (response) {
133039                 if (_listener) {
133040                     _listener(_self, response.event, response.eventData);
133041                 }
133042
133043                 return !!_listener;
133044             });
133045         };
133046
133047     _self = {
133048         addPlayerListener: function (callback) {
133049             if (!_closed && callback) {
133050                 _listener = callback;
133051                 _poll("onStart");
133052                 _poll("onStopped");
133053                 _poll("onBufferingStarted");
133054                 _poll("onBufferingStopped");
133055                 _poll("onDurationUpdated");
133056                 _poll("onEnd");
133057                 _poll("onError");
133058                 _poll("onVolumeChange");
133059                 _poll("onClose");
133060             }
133061             else {
133062                 _listener = null;
133063             }
133064
133065             return !_closed;
133066         },
133067
133068         close: function () {
133069             _listener = null;
133070             _closed = true;
133071             return transport.call(_uri + "close", {get: {id: _id}});
133072         },
133073
133074         pause: function () {
133075             return transport.call(_uri + "pause", {get: {id: _id}});
133076         },
133077
133078         play: function () {
133079             return transport.call(_uri + "play", {get: {id: _id}});
133080         }
133081     };
133082
133083     _self.__defineGetter__("duration", function () {
133084         return transport.call(_uri + "getDuration", {get: {id: _id}});
133085     });
133086
133087     _self.__defineGetter__("mediaTime", function () {
133088         return transport.call(_uri + "getMediaTime", {get: {id: _id}});
133089     });
133090
133091     _self.__defineSetter__("mediaTime", function (val) {
133092         transport.call(_uri + "setMediaTime", {get: {id: _id, value: val}});
133093     });
133094
133095     _self.__defineGetter__("state", function () {
133096         return transport.call(_uri + "getState", {get: {id: _id}});
133097     });
133098
133099     _self.__defineGetter__("volumeLevel", function () {
133100         return transport.call(_uri + "getVolumeLevel", {get: {id: _id}});
133101     });
133102
133103     _self.__defineSetter__("volumeLevel", function (val) {
133104         transport.call(_uri + "setVolumeLevel", {get: {id: _id, value: val}});
133105     });
133106
133107     _self.__defineGetter__("EVENT_BUFFERING_STARTED", function () {
133108         return "EVENT_BUFFERING_STARTED";
133109     });
133110     _self.__defineGetter__("EVENT_BUFFERING_STOPPED", function () {
133111         return "EVENT_BUFFERING_STOPPED";
133112     });
133113     _self.__defineGetter__("EVENT_CLOSED", function () {
133114         return "EVENT_CLOSED";
133115     });
133116     _self.__defineGetter__("EVENT_DEVICE_AVAILABLE", function () {
133117         return "EVENT_DEVICE_AVAILABLE";
133118     });
133119     _self.__defineGetter__("EVENT_DEVICE_UNAVAILABLE", function () {
133120         return "EVENT_DEVICE_UNAVAILABLE";
133121     });
133122     _self.__defineGetter__("EVENT_DURATION_UPDATED", function () {
133123         return "EVENT_DURATION_UPDATED";
133124     });
133125     _self.__defineGetter__("EVENT_END_OF_MEDIA", function () {
133126         return "EVENT_END_OF_MEDIA";
133127     });
133128     _self.__defineGetter__("EVENT_ERROR", function () {
133129         return "EVENT_ERROR";
133130     });
133131     _self.__defineGetter__("EVENT_RECORD_ERROR", function () {
133132         return "EVENT_ERROR";
133133     });
133134     _self.__defineGetter__("EVENT_RECORD_STARTED", function () {
133135         return "EVENT_RECORD_STARTED";
133136     });
133137     _self.__defineGetter__("EVENT_RECORD_STOPPED", function () {
133138         return "EVENT_RECORD_STOPPED";
133139     });
133140     _self.__defineGetter__("EVENT_SIZE_CHANGED", function () {
133141         return "EVENT_SIZE_CHANGED";
133142     });
133143     _self.__defineGetter__("EVENT_STARTED", function () {
133144         return "EVENT_STARTED";
133145     });
133146     _self.__defineGetter__("EVENT_STOPPED", function () {
133147         return "EVENT_STOPPED";
133148     });
133149     _self.__defineGetter__("EVENT_STOPPED_AT_TIME", function () {
133150         return "EVENT_STOPPED_AT_TIME";
133151     });
133152     _self.__defineGetter__("EVENT_VOLUME_CHANGED", function () {
133153         return "EVENT_VOLUME_CHANGED";
133154     });
133155
133156     return _self;
133157 }
133158
133159 Player.__defineGetter__("TIME_UNKNOWN", function () {
133160     return -1;
133161 });
133162 Player.__defineGetter__("CLOSED", function () {
133163     return 0;
133164 });
133165 Player.__defineGetter__("UNREALIZED", function () {
133166     return 100;
133167 });
133168 Player.__defineGetter__("REALIZED", function () {
133169     return 200;
133170 });
133171 Player.__defineGetter__("PREFETCHED", function () {
133172     return 300;
133173 });
133174 Player.__defineGetter__("STARTED", function () {
133175     return 400;
133176 });
133177
133178 module.exports = Player;
133179
133180 });
133181 define('ripple/platform/webworks.handset/2.0.0/client/BrowserArguments', function (require, exports, module) {
133182 /*
133183  *  Copyright 2011 Research In Motion Limited.
133184  *
133185  * Licensed under the Apache License, Version 2.0 (the "License");
133186  * you may not use this file except in compliance with the License.
133187  * You may obtain a copy of the License at
133188  *
133189  * http://www.apache.org/licenses/LICENSE-2.0
133190  *
133191  * Unless required by applicable law or agreed to in writing, software
133192  * distributed under the License is distributed on an "AS IS" BASIS,
133193  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133194  * See the License for the specific language governing permissions and
133195  * limitations under the License.
133196  */
133197 //blackberry.invoke.BrowserArguments ( url : String ,  [transport : blackberry.identity.Transport ] )
133198 module.exports = function (url, transport) {
133199     return {
133200         url: url
133201     };
133202 };
133203
133204 });
133205 define('ripple/platform/webworks.handset/2.0.0/client/CalendarArguments', function (require, exports, module) {
133206 /*
133207  *  Copyright 2011 Research In Motion Limited.
133208  *
133209  * Licensed under the Apache License, Version 2.0 (the "License");
133210  * you may not use this file except in compliance with the License.
133211  * You may obtain a copy of the License at
133212  *
133213  * http://www.apache.org/licenses/LICENSE-2.0
133214  *
133215  * Unless required by applicable law or agreed to in writing, software
133216  * distributed under the License is distributed on an "AS IS" BASIS,
133217  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133218  * See the License for the specific language governing permissions and
133219  * limitations under the License.
133220  */
133221 //blackberry.invoke.CalendarArguments ( )
133222 //blackberry.invoke.CalendarArguments ( date : Date )
133223 //blackberry.invoke.CalendarArguments ( appointment : blackberry.pim.Appointment )
133224 var _self = function () {
133225     //readonly  property  Appointment   appointment
133226     //readonly  property  Date   date
133227     //readwrite  property  Number   view
133228     return {
133229         appointment: undefined,
133230         date: undefined,
133231         view: 0
133232     };
133233 };
133234
133235 //const Number  VIEW_NEW  = 0
133236 _self.__defineGetter__("VIEW_NEW", function () {
133237     return 0;
133238 });
133239 //const Number  VIEW_VIEW  = 1
133240 _self.__defineGetter__("VIEW_VIEW", function () {
133241     return 1;
133242 });
133243 //const Number  VIEW_AGENDA  = 2
133244 _self.__defineGetter__("VIEW_AGENDA", function () {
133245     return 2;
133246 });
133247 //const Number  VIEW_DAY  = 3
133248 _self.__defineGetter__("VIEW_DAY", function () {
133249     return 3;
133250 });
133251 //const Number  VIEW_DEFAULT  = 4
133252 _self.__defineGetter__("VIEW_DEFAULT", function () {
133253     return 4;
133254 });
133255 //const Number  VIEW_MONTH  = 5
133256 _self.__defineGetter__("VIEW_MONTH", function () {
133257     return 5;
133258 });
133259 //const Number  VIEW_WEEK  = 6
133260 _self.__defineGetter__("VIEW_WEEK", function () {
133261     return 6;
133262 });
133263
133264 module.exports = _self;
133265
133266 });
133267 define('ripple/platform/webworks.handset/2.0.0/client/CallLog', function (require, exports, module) {
133268 /*
133269  *  Copyright 2011 Research In Motion Limited.
133270  *
133271  * Licensed under the Apache License, Version 2.0 (the "License");
133272  * you may not use this file except in compliance with the License.
133273  * You may obtain a copy of the License at
133274  *
133275  * http://www.apache.org/licenses/LICENSE-2.0
133276  *
133277  * Unless required by applicable law or agreed to in writing, software
133278  * distributed under the License is distributed on an "AS IS" BASIS,
133279  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133280  * See the License for the specific language governing permissions and
133281  * limitations under the License.
133282  */
133283 function CallLog() {
133284     // readwrite  property  String   addressBookNumber
133285     // readwrite  property  String   addressBookType
133286     // readwrite  property  Date   date
133287     // readwrite  property  Number   duration
133288     // readwrite  property  String   name
133289     // readwrite  property  String   notes
133290     // readwrite  property  String   number
133291     // readwrite  property  Number   status
133292     // readwrite  property  Number   type
133293     this.addressBookNumber = null;
133294     this.addressBookType = null;
133295     this.date = null;
133296     this.duration = null;
133297     this.name = null;
133298     this.notes = null;
133299     this.number = null;
133300     this.status = null;
133301     this.type = null;
133302 }
133303
133304 function _get(val) {
133305     return function () {
133306         return val;
133307     };
133308 }
133309
133310 CallLog.__defineGetter__("STATUS_NORMAL", _get(0));
133311 CallLog.__defineGetter__("STATUS_BUSY", _get(1));
133312 CallLog.__defineGetter__("STATUS_CONGESTION", _get(2));
133313 CallLog.__defineGetter__("STATUS_PATH_UNAVAILABLE", _get(3));
133314 CallLog.__defineGetter__("STATUS_NUMBER_UNOBTAINABLE", _get(4));
133315 CallLog.__defineGetter__("STATUS_AUTHENTICATION_FAILURE", _get(5));
133316 CallLog.__defineGetter__("STATUS_EMERGENCY_CALLS_ONLY", _get(6));
133317 CallLog.__defineGetter__("STATUS_HOLD_ERROR", _get(7));
133318 CallLog.__defineGetter__("STATUS_OUTGOING_CALLS_BARRED", _get(8));
133319 CallLog.__defineGetter__("STATUS_GENERAL_ERROR", _get(9));
133320 CallLog.__defineGetter__("STATUS_MAINTENANCE_REQUIRED", _get(10));
133321 CallLog.__defineGetter__("STATUS_SERVICE_NOT_AVAILABLE", _get(11));
133322 CallLog.__defineGetter__("STATUS_CALL_FAIL_DUE_TO_FADING", _get(12));
133323 CallLog.__defineGetter__("STATUS_CALL_LOST_DUE_TO_FADING", _get(13));
133324 CallLog.__defineGetter__("STATUS_CALL_FAILED_TRY_AGAIN", _get(14));
133325 CallLog.__defineGetter__("STATUS_FDN_MISMATCH", _get(15));
133326 CallLog.__defineGetter__("STATUS_CONNECTION_DENIED", _get(16));
133327 CallLog.__defineGetter__("STATUS_INCOMING_CALL_BARRED", _get(17));
133328 CallLog.__defineGetter__("TYPE_RECEIVED_CALL", _get(0));
133329 CallLog.__defineGetter__("TYPE_PLACED_CALL", _get(1));
133330 CallLog.__defineGetter__("TYPE_MISSED_CALL_UNOPENED", _get(2));
133331 CallLog.__defineGetter__("TYPE_MISSED_CALL_OPENED", _get(3));
133332
133333 module.exports = CallLog;
133334
133335 });
133336 define('ripple/platform/webworks.handset/2.0.0/client/CameraArguments', function (require, exports, module) {
133337 /*
133338  *  Copyright 2011 Research In Motion Limited.
133339  *
133340  * Licensed under the Apache License, Version 2.0 (the "License");
133341  * you may not use this file except in compliance with the License.
133342  * You may obtain a copy of the License at
133343  *
133344  * http://www.apache.org/licenses/LICENSE-2.0
133345  *
133346  * Unless required by applicable law or agreed to in writing, software
133347  * distributed under the License is distributed on an "AS IS" BASIS,
133348  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133349  * See the License for the specific language governing permissions and
133350  * limitations under the License.
133351  */
133352 //blackberry.invoke.CameraArguments ( )
133353 var _self = function () {
133354     return {
133355         //readwrite  property  Number   view
133356         view: 0
133357     };
133358 };
133359
133360 //const Number  VIEW_CAMERA  = 0
133361 _self.__defineGetter__("VIEW_CAMERA", function () {
133362     return 0;
133363 });
133364 //const Number  VIEW_RECORDER  = 1
133365 _self.__defineGetter__("VIEW_RECORDER", function () {
133366     return 1;
133367 });
133368
133369 module.exports = _self;
133370
133371 });
133372 define('ripple/platform/webworks.handset/2.0.0/client/Contact', function (require, exports, module) {
133373 /*
133374  *  Copyright 2011 Research In Motion Limited.
133375  *
133376  * Licensed under the Apache License, Version 2.0 (the "License");
133377  * you may not use this file except in compliance with the License.
133378  * You may obtain a copy of the License at
133379  *
133380  * http://www.apache.org/licenses/LICENSE-2.0
133381  *
133382  * Unless required by applicable law or agreed to in writing, software
133383  * distributed under the License is distributed on an "AS IS" BASIS,
133384  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133385  * See the License for the specific language governing permissions and
133386  * limitations under the License.
133387  */
133388 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
133389     _uri = "blackberry/pim/contact/";
133390
133391 function Contact(service) {
133392     var _self = {
133393         anniversary: null,
133394         birthday: null,
133395         categories: [],
133396         company: null,
133397         email1: "",
133398         email2: "",
133399         email3: "",
133400         faxPhone: null,
133401         firstName: null,
133402         homeAddress: null,
133403         homePhone: null,
133404         homePhone2: null,
133405         jobTitle: null,
133406         lastName: null,
133407         mobilePhone: null,
133408         note: null,
133409         otherPhone: null,
133410         pagerPhone: null,
133411         picture: null,
133412         pin: null,
133413         title: null,
133414         uid: null,
133415         user1: null,
133416         user2: null,
133417         user3: null,
133418         user4: null,
133419         webpage: null,
133420         workAddress: null,
133421         workPhone: null,
133422         workPhone2: null,
133423         remove: function () {
133424             if (!_self.uid) {
133425                 throw "task has not yet been saved (has no uid)";
133426             }
133427             transport.call(_uri + "remove", {
133428                 get: { id: _self.uid }
133429             });
133430         },
133431         save: function () {
133432             if (!_self.uid) {
133433                 _self.uid = Math.uuid(null, 16);
133434             }
133435             transport.call(_uri + "save", {
133436                 post: { contact: _self }
133437             });
133438         },
133439         setPicture: function (picture) {
133440             throw "not implemented";
133441         }
133442     };
133443
133444     return _self;
133445 }
133446
133447 function _massage(property, name) {
133448     if ((name === "anniversary" || name === "birthday") && property) {
133449         return new Date(property);
133450     }
133451     return property;
133452 }
133453
133454 Contact.find = function (fieldFilter, orderBy, maxReturn, service, isAscending) {
133455     return transport.call(_uri + "find", {
133456         post: {
133457             fieldFilter: fieldFilter,
133458             orderBy: orderBy,
133459             maxReturn: maxReturn,
133460             service: service,
133461             isAscending: isAscending
133462         }
133463     }).map(function (properties) {
133464         var contact = new Contact(),
133465             key;
133466         for (key in properties) {
133467             if (contact.hasOwnProperty(key)) {
133468                 contact[key] = _massage(properties[key], key);
133469             }
133470         }
133471         return contact;
133472     });
133473 };
133474
133475 module.exports = Contact;
133476
133477 });
133478 define('ripple/platform/webworks.handset/2.0.0/client/FilterExpression', function (require, exports, module) {
133479 /*
133480  *  Copyright 2011 Research In Motion Limited.
133481  *
133482  * Licensed under the Apache License, Version 2.0 (the "License");
133483  * you may not use this file except in compliance with the License.
133484  * You may obtain a copy of the License at
133485  *
133486  * http://www.apache.org/licenses/LICENSE-2.0
133487  *
133488  * Unless required by applicable law or agreed to in writing, software
133489  * distributed under the License is distributed on an "AS IS" BASIS,
133490  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133491  * See the License for the specific language governing permissions and
133492  * limitations under the License.
133493  */
133494 //blackberry.find.FilterExpression ( leftField  : object ,  operator  : object ,  rightField : object ,  [negate : Boolean ] )
133495 var FilterExpression = function (leftField, operator, rightField, negate) {
133496     this.__defineGetter__("leftField", function () {
133497         return leftField;
133498     });
133499
133500     this.__defineGetter__("operator", function () {
133501         return operator;
133502     });
133503
133504     this.__defineGetter__("rightField", function () {
133505         return rightField;
133506     });
133507
133508     this.__defineGetter__("negate", function () {
133509         return negate ? true : false;
133510     });
133511 };
133512
133513 module.exports = FilterExpression;
133514
133515 });
133516 define('ripple/platform/webworks.handset/2.0.0/client/JavaArguments', function (require, exports, module) {
133517 /*
133518  *  Copyright 2011 Research In Motion Limited.
133519  *
133520  * Licensed under the Apache License, Version 2.0 (the "License");
133521  * you may not use this file except in compliance with the License.
133522  * You may obtain a copy of the License at
133523  *
133524  * http://www.apache.org/licenses/LICENSE-2.0
133525  *
133526  * Unless required by applicable law or agreed to in writing, software
133527  * distributed under the License is distributed on an "AS IS" BASIS,
133528  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133529  * See the License for the specific language governing permissions and
133530  * limitations under the License.
133531  */
133532 //blackberry.invoke.JavaArguments ( uri : String ,  [params : String [ ] ] )
133533 var _self = function (uri, params) {
133534     return {
133535         uri: uri,
133536         params: params,
133537         args: arguments
133538     };
133539 };
133540
133541 module.exports = _self;
133542
133543 });
133544 define('ripple/platform/webworks.handset/2.0.0/client/MapsArguments', function (require, exports, module) {
133545 /*
133546  *  Copyright 2011 Research In Motion Limited.
133547  *
133548  * Licensed under the Apache License, Version 2.0 (the "License");
133549  * you may not use this file except in compliance with the License.
133550  * You may obtain a copy of the License at
133551  *
133552  * http://www.apache.org/licenses/LICENSE-2.0
133553  *
133554  * Unless required by applicable law or agreed to in writing, software
133555  * distributed under the License is distributed on an "AS IS" BASIS,
133556  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133557  * See the License for the specific language governing permissions and
133558  * limitations under the License.
133559  */
133560 //blackberry.invoke.MapsArguments ( )
133561 //blackberry.invoke.MapsArguments ( latitude : Number ,  longitude : Number )
133562 //blackberry.invoke.MapsArguments ( locationDocument : Document ) - Supported in 5.0.0 only
133563 //blackberry.invoke.MapsArguments ( locationDocument : String ) - Supported in 6.0.0 only
133564 //blackberry.invoke.MapsArguments ( address : blackberry.pim.Address )
133565 var _self = function () {
133566     return {};
133567 };
133568
133569 module.exports = _self;
133570
133571 });
133572 define('ripple/platform/webworks.handset/2.0.0/client/Memo', function (require, exports, module) {
133573 /*
133574  *  Copyright 2011 Research In Motion Limited.
133575  *
133576  * Licensed under the Apache License, Version 2.0 (the "License");
133577  * you may not use this file except in compliance with the License.
133578  * You may obtain a copy of the License at
133579  *
133580  * http://www.apache.org/licenses/LICENSE-2.0
133581  *
133582  * Unless required by applicable law or agreed to in writing, software
133583  * distributed under the License is distributed on an "AS IS" BASIS,
133584  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133585  * See the License for the specific language governing permissions and
133586  * limitations under the License.
133587  */
133588 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
133589     _uri = "blackberry/pim/memo/";
133590
133591 function Memo() {
133592     var _self = {
133593         categories: [],
133594         note: null,
133595         title: null,
133596         uid: null,
133597         remove: function () {
133598             transport.call(_uri + "remove", {
133599                 get: {uid: _self.uid}
133600             });
133601         },
133602         save: function () {
133603             if (_self.uid  === null) {
133604                 _self.uid  = Number(Math.uuid(8, 10));
133605             }
133606             transport.call(_uri + "save", {
133607                 post: {memo: _self}
133608             });
133609         }
133610     };
133611
133612     return _self;
133613 }
133614
133615 Memo.find = function (filter, orderBy, maxReturn, service, isAscending) {
133616     var opts = {
133617         post: {
133618             filter: filter,
133619             orderBy: orderBy,
133620             maxReturn: maxReturn,
133621             isAscending: isAscending,
133622             service: service
133623         }
133624     };
133625
133626     return transport.call(_uri + "find", opts).map(function (obj) {
133627         var memo = new Memo();
133628         memo.uid = obj.uid;
133629         memo.categories = obj.categories || [];
133630         memo.note = obj.note;
133631         memo.title = obj.title;
133632         return memo;
133633     });
133634 };
133635
133636 module.exports = Memo;
133637
133638 });
133639 define('ripple/platform/webworks.handset/2.0.0/client/MemoArguments', function (require, exports, module) {
133640 /*
133641  *  Copyright 2011 Research In Motion Limited.
133642  *
133643  * Licensed under the Apache License, Version 2.0 (the "License");
133644  * you may not use this file except in compliance with the License.
133645  * You may obtain a copy of the License at
133646  *
133647  * http://www.apache.org/licenses/LICENSE-2.0
133648  *
133649  * Unless required by applicable law or agreed to in writing, software
133650  * distributed under the License is distributed on an "AS IS" BASIS,
133651  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133652  * See the License for the specific language governing permissions and
133653  * limitations under the License.
133654  */
133655 //blackberry.invoke.MemoArguments ( [memo : blackberry.pim.Memo ] )
133656 var _self = function (memo) {
133657     return {
133658         memo: memo,
133659         view: 0
133660     };
133661 };
133662
133663 //const Number  VIEW_NEW  = 0
133664 _self.__defineGetter__("VIEW_NEW", function () {
133665     return 0;
133666 });
133667 //const Number  VIEW_EDIT  = 1
133668 _self.__defineGetter__("VIEW_EDIT", function () {
133669     return 1;
133670 });
133671
133672 module.exports = _self;
133673
133674 });
133675 define('ripple/platform/webworks.handset/2.0.0/client/MenuItem', function (require, exports, module) {
133676 /*
133677  *  Copyright 2011 Research In Motion Limited.
133678  *
133679  * Licensed under the Apache License, Version 2.0 (the "License");
133680  * you may not use this file except in compliance with the License.
133681  * You may obtain a copy of the License at
133682  *
133683  * http://www.apache.org/licenses/LICENSE-2.0
133684  *
133685  * Unless required by applicable law or agreed to in writing, software
133686  * distributed under the License is distributed on an "AS IS" BASIS,
133687  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133688  * See the License for the specific language governing permissions and
133689  * limitations under the License.
133690  */
133691 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
133692     event = require('ripple/event');
133693
133694 function MenuItem(isSeparator, ordinal, caption, callback) {
133695     var _isDefault = false,
133696         id = Math.uuid();
133697
133698     if (ordinal < 0) {
133699         throw "Ordinal cannot be less than 0";
133700     } else if (isSeparator) {
133701         if (caption !== undefined) {
133702             throw "caption must not be supplied";
133703         } else if (callback !== undefined) {
133704             throw "callback must not be supplied";
133705         }
133706     } else if (!isSeparator) {
133707         if (caption === undefined) {
133708             throw "caption must be supplied";
133709         }
133710     }
133711
133712     this.callback = callback;
133713
133714     this.__defineSetter__("id", function (i) {
133715         id = i;
133716     });
133717
133718     this.__defineGetter__("id", function () {
133719         return id;
133720     });
133721
133722     this.__defineSetter__("caption", function (c) {
133723         caption = c;
133724         event.trigger("MenuItemChanged", [this]);
133725     });
133726
133727     this.__defineGetter__("caption", function () {
133728         return caption;
133729     });
133730
133731     this.__defineSetter__("ordinal", function (o) {
133732         ordinal = o;
133733         event.trigger("MenuItemChanged", [this]);
133734     });
133735
133736     this.__defineGetter__("ordinal", function () {
133737         return ordinal;
133738     });
133739
133740     this.__defineGetter__("isSeparator", function () {
133741         return isSeparator;
133742     });
133743
133744     this.__defineSetter__("isDefault", function (d) {
133745         _isDefault = d;
133746         event.trigger("MenuItemChanged", [this]);
133747     });
133748
133749     this.__defineGetter__("isDefault", function () {
133750         return _isDefault;
133751     });
133752
133753     this.__defineGetter__("id", function () {
133754         return id;
133755     });
133756 }
133757
133758 module.exports = MenuItem;
133759
133760 });
133761 define('ripple/platform/webworks.handset/2.0.0/client/Message', function (require, exports, module) {
133762 /*
133763  *  Copyright 2011 Research In Motion Limited.
133764  *
133765  * Licensed under the Apache License, Version 2.0 (the "License");
133766  * you may not use this file except in compliance with the License.
133767  * You may obtain a copy of the License at
133768  *
133769  * http://www.apache.org/licenses/LICENSE-2.0
133770  *
133771  * Unless required by applicable law or agreed to in writing, software
133772  * distributed under the License is distributed on an "AS IS" BASIS,
133773  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133774  * See the License for the specific language governing permissions and
133775  * limitations under the License.
133776  */
133777 var utils = require('ripple/platform/webworks.core/2.0.0/client/utils'),
133778     identity = require('ripple/platform/webworks.handset/2.0.0/client/identity'),
133779     transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
133780     Service = require('ripple/platform/webworks.handset/2.0.0/client/identity/Service'),
133781     select = require('ripple/platform/webworks.core/2.0.0/select'),
133782     _uri = "blackberry/message/message/";
133783
133784 function Message(service) {
133785     var _service = service,
133786         _msg = {
133787             uid: 0,
133788             status: Message.STATUS_DRAFT,
133789             from: "",
133790             folder: Message.FOLDER_DRAFT,
133791             replyTo: "",
133792             bccRecipients: "",
133793             body: "",
133794             ccRecipients: "",
133795             priority: Message.PRIORITY_MEDIUM, //default to med priority
133796             subject: "",
133797             toRecipients: "",
133798
133799             remove: function () {
133800                 _msg.folder = Message.FOLDER_DELETED;
133801                 transport.call(_uri + "remove", {
133802                     get: {uid: _msg.uid}
133803                 });
133804             },
133805
133806             save: function () {
133807                 if (_msg.uid === 0) {
133808                     _msg.uid = Number(Math.uuid(8, 10));
133809                 }
133810
133811                 _msg.replyTo  = _msg.from = _service.emailAddress;
133812                 _msg.status =  Message.STATUS_SAVED;
133813                 transport.call(_uri + "save", {
133814                     post: {message: _msg}
133815                 });
133816             },
133817
133818             send: function () {
133819                 if (_msg.toRecipients) {
133820                     if (_msg.uid === 0) {
133821                         _msg.uid = Number(Math.uuid(8, 10));
133822                     }
133823
133824                     _msg.folder = Message.FOLDER_DRAFT;
133825                     _msg.status = Message.STATUS_UNKNOWN;
133826                     transport.call(_uri + "send", {
133827                         get: {message: _msg}
133828                     });
133829                 } else {
133830                     throw "message has no recipients";
133831                 }
133832             }
133833         };
133834
133835     if (!_service) {
133836         _service = identity.getDefaultService().reduce(function (email, service) {
133837             return service.type === Service.TYPE_EMAIL ? service : email;
133838         }, null);
133839     }
133840
133841     return _msg;
133842 }
133843
133844 Message.find = function (filter, maxReturn, service) {
133845     var opts = {
133846         post: {
133847             filter: filter,
133848             maxReturn: maxReturn,
133849             service: service
133850         }
133851     };
133852
133853     return transport.call(_uri + "find", opts).map(function (obj) {
133854         var msg = new Message();
133855
133856         msg.uid = obj.uid;
133857         msg.status = obj.status;
133858         msg.from = obj.from;
133859         msg.folder = obj.folder;
133860         msg.replyTo = obj.replyTo;
133861         msg.bccRecipients = obj.bccRecipients;
133862         msg.body = obj.body;
133863         msg.ccRecipients = obj.ccRecipients;
133864         msg.priority = obj.priority;
133865         msg.subject = obj.subject;
133866         msg.toRecipients = obj.toRecipients;
133867
133868         return msg;
133869     });
133870 };
133871
133872
133873 Message.__defineGetter__("STATUS_UNKNOWN", function () {
133874     return -1;
133875 });
133876 Message.__defineGetter__("STATUS_SAVED", function () {
133877     return 0;
133878 });
133879 Message.__defineGetter__("STATUS_DRAFT", function () {
133880     return 1;
133881 });
133882 Message.__defineGetter__("STATUS_SENT", function () {
133883     return 2;
133884 });
133885 Message.__defineGetter__("STATUS_ERROR_OCCURED", function () {
133886     return 3;
133887 });
133888 Message.__defineGetter__("PRIORITY_HIGH", function () {
133889     return 0;
133890 });
133891 Message.__defineGetter__("PRIORITY_MEDIUM", function () {
133892     return 1;
133893 });
133894 Message.__defineGetter__("PRIORITY_LOW", function () {
133895     return 2;
133896 });
133897 Message.__defineGetter__("FOLDER_INBOX", function () {
133898     return 0;
133899 });
133900 Message.__defineGetter__("FOLDER_SENT", function () {
133901     return 1;
133902 });
133903 Message.__defineGetter__("FOLDER_DRAFT", function () {
133904     return 2;
133905 });
133906 Message.__defineGetter__("FOLDER_OUTBOX", function () {
133907     return 3;
133908 });
133909 Message.__defineGetter__("FOLDER_DELETED", function () {
133910     return 4;
133911 });
133912 Message.__defineGetter__("FOLDER_OTHER", function () {
133913     return 5;
133914 });
133915
133916 module.exports = Message;
133917
133918 });
133919 define('ripple/platform/webworks.handset/2.0.0/client/MessageArguments', function (require, exports, module) {
133920 /*
133921  *  Copyright 2011 Research In Motion Limited.
133922  *
133923  * Licensed under the Apache License, Version 2.0 (the "License");
133924  * you may not use this file except in compliance with the License.
133925  * You may obtain a copy of the License at
133926  *
133927  * http://www.apache.org/licenses/LICENSE-2.0
133928  *
133929  * Unless required by applicable law or agreed to in writing, software
133930  * distributed under the License is distributed on an "AS IS" BASIS,
133931  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133932  * See the License for the specific language governing permissions and
133933  * limitations under the License.
133934  */
133935 //blackberry.invoke.MessageArguments ( )
133936 //blackberry.invoke.MessageArguments ( message : blackberry.message.Message )
133937 //blackberry.invoke.MessageArguments ( to : String ,  subject : String ,  body : String )
133938 var _self = function () {
133939     return {
133940         view: 1
133941     };
133942 };
133943
133944 //const Number  VIEW_NEW  = 0
133945 _self.__defineGetter__("VIEW_NEW", function () {
133946     return 0;
133947 });
133948 //const Number  VIEW_DEFAULT  = 1
133949 _self.__defineGetter__("VIEW_DEFAULT", function () {
133950     return 1;
133951 });
133952 //const Number  VIEW_SAVED  = 2
133953 _self.__defineGetter__("VIEW_SAVED", function () {
133954     return 2;
133955 });
133956 //const Number  VIEW_SEARCH  = 3
133957 _self.__defineGetter__("VIEW_SEARCH", function () {
133958     return 3;
133959 });
133960
133961 module.exports = _self;
133962
133963 });
133964 define('ripple/platform/webworks.handset/2.0.0/client/Phone', function (require, exports, module) {
133965 /*
133966  *  Copyright 2011 Research In Motion Limited.
133967  *
133968  * Licensed under the Apache License, Version 2.0 (the "License");
133969  * you may not use this file except in compliance with the License.
133970  * You may obtain a copy of the License at
133971  *
133972  * http://www.apache.org/licenses/LICENSE-2.0
133973  *
133974  * Unless required by applicable law or agreed to in writing, software
133975  * distributed under the License is distributed on an "AS IS" BASIS,
133976  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133977  * See the License for the specific language governing permissions and
133978  * limitations under the License.
133979  */
133980 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
133981     _uri = "blackberry/phone/",
133982     _listeners = {},
133983     _self;
133984
133985 _self = {
133986     activeCalls: function () {
133987         return transport.call(_uri + "activeCalls");
133988     },
133989
133990     addPhoneListener: function (callback, eventType) {
133991         var assigned = false;
133992
133993         if (callback && typeof eventType === "number") {
133994             _listeners[eventType] = callback;
133995             assigned = true;
133996         } else if (eventType && callback === null) {
133997             delete _listeners[eventType];
133998         } else {
133999             _listeners = {};
134000         }
134001
134002         transport.poll(_uri + "onPhoneEvent", {
134003             get: {eventType: eventType}
134004         }, function (response) {
134005             var func = _listeners[eventType];
134006
134007             if (func) {
134008                 func(response.callId, response.error);
134009             }
134010
134011             return !!func;
134012         });
134013
134014         // hackish (return true that event was assigned, this is a disconnect between transport poll api and server)
134015         return assigned;
134016     },
134017
134018     inActiveCall: function () {
134019         return transport.call(_uri + "inActiveCall");
134020     }
134021 };
134022
134023 _self.__defineGetter__("CB_CALL_INITIATED", function () {
134024     return 0;
134025 });
134026 _self.__defineGetter__("CB_CALL_WAITING", function () {
134027     return 1;
134028 });
134029 _self.__defineGetter__("CB_CALL_INCOMING", function () {
134030     return 2;
134031 });
134032 _self.__defineGetter__("CB_CALL_ANSWERED", function () {
134033     return 3;
134034 });
134035 _self.__defineGetter__("CB_CALL_CONNECTED", function () {
134036     return 4;
134037 });
134038 _self.__defineGetter__("CB_CALL_CONFERENCECALL_ESTABLISHED", function () {
134039     return 5;
134040 });
134041 _self.__defineGetter__("CB_CONFERENCECALL_DISCONNECTED", function () {
134042     return 6;
134043 });
134044 _self.__defineGetter__("CB_CALL_DISCONNECTED", function () {
134045     return 7;
134046 });
134047 _self.__defineGetter__("CB_CALL_DIRECTCONNECT_CONNECTED", function () {
134048     return 8;
134049 });
134050 _self.__defineGetter__("CB_CALL_DIRECTCONNECT_DISCONNECTED", function () {
134051     return 9;
134052 });
134053 _self.__defineGetter__("CB_CALL_ENDED_BYUSER", function () {
134054     return 10;
134055 });
134056 _self.__defineGetter__("CB_CALL_FAILED", function () {
134057     return 11;
134058 });
134059 _self.__defineGetter__("CB_CALL_RESUMED", function () {
134060     return 12;
134061 });
134062 _self.__defineGetter__("CB_CALL_HELD", function () {
134063     return 13;
134064 });
134065 _self.__defineGetter__("CB_CALL_ADDED", function () {
134066     return 14;
134067 });
134068 _self.__defineGetter__("CB_CALL_REMOVED", function () {
134069     return 15;
134070 });
134071 _self.__defineGetter__("CALL_ERROR_SUBSCRIBER_BUSY", function () {
134072     return 1;
134073 });
134074 _self.__defineGetter__("CALL_ERROR_CONGESTION", function () {
134075     return 2;
134076 });
134077 _self.__defineGetter__("CALL_ERROR_RADIO_PATH_UNAVAILABLE", function () {
134078     return 3;
134079 });
134080 _self.__defineGetter__("CALL_ERROR_NUMBER_UNOBTAINABLE", function () {
134081     return 4;
134082 });
134083 _self.__defineGetter__("CALL_ERROR_AUTHORIZATION_FAILURE", function () {
134084     return 5;
134085 });
134086 _self.__defineGetter__("CALL_ERROR_EMERGENCY_CALLS_ONLY", function () {
134087     return 6;
134088 });
134089 _self.__defineGetter__("CALL_ERROR_HOLD_ERROR", function () {
134090     return 7;
134091 });
134092 _self.__defineGetter__("CALL_ERROR_OUTGOING_CALLS_BARRED", function () {
134093     return 8;
134094 });
134095 _self.__defineGetter__("CALL_ERROR_GENERAL", function () {
134096     return 9;
134097 });
134098 _self.__defineGetter__("CALL_ERROR_MAINTENANCE_REQUIRED", function () {
134099     return 10;
134100 });
134101 _self.__defineGetter__("CALL_ERROR_SERVICE_NOT_AVAILABLE", function () {
134102     return 11;
134103 });
134104 _self.__defineGetter__("CALL_ERROR_DUE_TO_FADING", function () {
134105     return 12;
134106 });
134107 _self.__defineGetter__("CALL_ERROR_LOST_DUE_TO_FADING", function () {
134108     return 13;
134109 });
134110 _self.__defineGetter__("CALL_ERROR_TRY_AGAIN", function () {
134111     return 14;
134112 });
134113 _self.__defineGetter__("CALL_ERROR_FDN_MISMATCH", function () {
134114     return 15;
134115 });
134116 _self.__defineGetter__("CALL_ERROR_CONNECTION_DENIED_BY_NETWORK", function () {
134117     return 16;
134118 });
134119 _self.__defineGetter__("CALL_ERROR_NUMBER_NOT_IN_SERVICE", function () {
134120     return 17;
134121 });
134122 _self.__defineGetter__("CALL_ERROR_PLEASE_TRY_LATER", function () {
134123     return 18;
134124 });
134125 _self.__defineGetter__("CALL_ERROR_SERVICE_CONFLICT", function () {
134126     return 19;
134127 });
134128 _self.__defineGetter__("CALL_ERROR_SYSTEM_BUSY_TRY_LATER", function () {
134129     return 20;
134130 });
134131 _self.__defineGetter__("CALL_ERROR_USER_BUSY_IN_PRIVATE", function () {
134132     return 21;
134133 });
134134 _self.__defineGetter__("CALL_ERROR_USER_BUSY_IN_DATA", function () {
134135     return 22;
134136 });
134137 _self.__defineGetter__("CALL_ERROR_USER_NOT_AUTHORIZED", function () {
134138     return 23;
134139 });
134140 _self.__defineGetter__("CALL_ERROR_USER_NOT_AVAILABLE", function () {
134141     return 24;
134142 });
134143 _self.__defineGetter__("CALL_ERROR_USER_UNKNOWN", function () {
134144     return 25;
134145 });
134146 _self.__defineGetter__("CALL_ERROR_USER_NOT_REACHABLE", function () {
134147     return 26;
134148 });
134149 _self.__defineGetter__("CALL_ERROR_INCOMING_CALL_BARRED", function () {
134150     return 27;
134151 });
134152 _self.__defineGetter__("CALL_ERROR_CALL_REPLACED_BY_STK", function () {
134153     return 28;
134154 });
134155 _self.__defineGetter__("CALL_ERROR_STK_CALL_NOT_ALLOWED", function () {
134156     return 29;
134157 });
134158
134159 module.exports = _self;
134160
134161 });
134162 define('ripple/platform/webworks.handset/2.0.0/client/PhoneArguments', function (require, exports, module) {
134163 /*
134164  *  Copyright 2011 Research In Motion Limited.
134165  *
134166  * Licensed under the Apache License, Version 2.0 (the "License");
134167  * you may not use this file except in compliance with the License.
134168  * You may obtain a copy of the License at
134169  *
134170  * http://www.apache.org/licenses/LICENSE-2.0
134171  *
134172  * Unless required by applicable law or agreed to in writing, software
134173  * distributed under the License is distributed on an "AS IS" BASIS,
134174  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134175  * See the License for the specific language governing permissions and
134176  * limitations under the License.
134177  */
134178 //blackberry.invoke.PhoneArguments ( [dialString : String ] ,  [smartDialing : Boolean ] ,  [lineId : Number ] )
134179 var _self = function (dialString, smartDialing, lineId) {
134180     return {
134181         dialString: dialString,
134182         smartDialing: smartDialing,
134183         lineId: (lineId ? lineId : -1),
134184         view: 0
134185     };
134186 };
134187
134188 //const Number  VIEW_NEW  = 0
134189 _self.__defineGetter__("VIEW_CALL", function () {
134190     return 0;
134191 });
134192 //const Number  VIEW_DEFAULT  = 1
134193 _self.__defineGetter__("VIEW_VOICEMAIL", function () {
134194     return 1;
134195 });
134196
134197 module.exports = _self;
134198
134199 });
134200 define('ripple/platform/webworks.handset/2.0.0/client/PhoneCall', function (require, exports, module) {
134201 /*
134202  *  Copyright 2011 Research In Motion Limited.
134203  *
134204  * Licensed under the Apache License, Version 2.0 (the "License");
134205  * you may not use this file except in compliance with the License.
134206  * You may obtain a copy of the License at
134207  *
134208  * http://www.apache.org/licenses/LICENSE-2.0
134209  *
134210  * Unless required by applicable law or agreed to in writing, software
134211  * distributed under the License is distributed on an "AS IS" BASIS,
134212  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134213  * See the License for the specific language governing permissions and
134214  * limitations under the License.
134215  */
134216 function PhoneCall(onhold) {
134217     return {
134218         //Boolean   isOnHold ( )
134219         //readonly  property  Boolean   outgoing
134220         //readonly  property  String   recipientName
134221         //readonly  property  String   recipientNumber
134222
134223         outgoing: false,
134224         recipientName: null,
134225         recipientNumber: null,
134226
134227         isOnHold: function () {
134228             return onhold;
134229         }
134230     };
134231 }
134232
134233 module.exports = PhoneCall;
134234
134235 });
134236 define('ripple/platform/webworks.handset/2.0.0/client/PhoneLogs', function (require, exports, module) {
134237 /*
134238  *  Copyright 2011 Research In Motion Limited.
134239  *
134240  * Licensed under the Apache License, Version 2.0 (the "License");
134241  * you may not use this file except in compliance with the License.
134242  * You may obtain a copy of the License at
134243  *
134244  * http://www.apache.org/licenses/LICENSE-2.0
134245  *
134246  * Unless required by applicable law or agreed to in writing, software
134247  * distributed under the License is distributed on an "AS IS" BASIS,
134248  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134249  * See the License for the specific language governing permissions and
134250  * limitations under the License.
134251  */
134252 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
134253     CallLog = require('ripple/platform/webworks.handset/2.0.0/client/CallLog'),
134254     utils = require('ripple/utils'),
134255     _onCallLog = {
134256         Added: null,
134257         Removed: null,
134258         Updated: null,
134259         Reset: null,
134260     },
134261     _uri = "blackberry/phone/logs/",
134262     _self;
134263
134264 function _massage(property, name) {
134265     if (name === "date" && property) {
134266         return new Date(property);
134267     }
134268     return property;
134269 }
134270
134271 function _toCallLog(log) {
134272     var callLog = new CallLog(),
134273         prop;
134274     for (prop in log) {
134275         if (log.hasOwnProperty(prop)) {
134276             callLog[prop] = _massage(log[prop], prop);
134277         }
134278     }
134279     return callLog;
134280 }
134281
134282 function handle(evt) {
134283     return function (response) {
134284         var func = _onCallLog[evt], args;
134285
134286         if (func) {
134287             args = utils.map(response, function (value) {
134288                 return _toCallLog(value);
134289             });
134290             func.apply(null, args);
134291         }
134292
134293         return !!func;
134294     };
134295 }
134296
134297 function poll(path) {
134298     transport.poll(_uri + path, {}, handle(path.replace("onCallLog", "")));
134299 }
134300
134301 _self = {
134302     addPhoneLogListener: function (onCallLogAdded, onCallLogRemoved, onCallLogUpdated, onCallLogReset) {
134303         _onCallLog.Added = onCallLogAdded;
134304         _onCallLog.Removed = onCallLogRemoved;
134305         _onCallLog.Updated = onCallLogUpdated;
134306         _onCallLog.Reset = onCallLogReset;
134307
134308         if (onCallLogAdded) {
134309             poll("onCallLogAdded");
134310         }
134311
134312         if (onCallLogRemoved) {
134313             poll("onCallLogRemoved");
134314         }
134315
134316         if (onCallLogUpdated) {
134317             poll("onCallLogUpdated");
134318         }
134319
134320         if (onCallLogReset) {
134321             poll("onCallLogReset");
134322         }
134323
134324         return !!(onCallLogAdded || onCallLogRemoved ||
134325                   onCallLogUpdated || onCallLogRemoved);
134326     },
134327
134328     callAt: function (index, folderID) {
134329         var log = transport.call(_uri + "callAt", {
134330             get: {
134331                 index: index,
134332                 folderID: folderID
134333             }
134334         });
134335
134336         if (log && log.date) {
134337             log.date = new Date(log.date);
134338         }
134339
134340         return log;
134341     },
134342
134343     deleteCallAt: function (index, folderID) {
134344         return transport.call(_uri + "deleteCallAt", {
134345             get: {
134346                 index: index,
134347                 folderID: folderID
134348             }
134349         });
134350     },
134351
134352     find: function (filter, folderID, orderBy, maxReturn, isAscending) {
134353         return transport.call(_uri + "find", {
134354             post: {
134355                 filter: filter,
134356                 folderID: folderID,
134357                 orderBy: orderBy,
134358                 maxReturn: maxReturn,
134359                 isAscending: isAscending
134360             }
134361         }).map(_toCallLog);
134362     },
134363
134364     numberOfCalls: function (folderID) {
134365         return transport.call(_uri + "numberOfCalls", {
134366             get: {
134367                 folderID: folderID
134368             }
134369         });
134370     }
134371 };
134372
134373 _self.__defineGetter__("FOLDER_MISSED_CALLS", function () {
134374     return 0;
134375 });
134376
134377 _self.__defineGetter__("FOLDER_NORMAL_CALLS", function () {
134378     return 1;
134379 });
134380
134381 module.exports = _self;
134382
134383 });
134384 define('ripple/platform/webworks.handset/2.0.0/client/PushData', function (require, exports, module) {
134385 /*
134386  *  Copyright 2011 Research In Motion Limited.
134387  *
134388  * Licensed under the Apache License, Version 2.0 (the "License");
134389  * you may not use this file except in compliance with the License.
134390  * You may obtain a copy of the License at
134391  *
134392  * http://www.apache.org/licenses/LICENSE-2.0
134393  *
134394  * Unless required by applicable law or agreed to in writing, software
134395  * distributed under the License is distributed on an "AS IS" BASIS,
134396  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134397  * See the License for the specific language governing permissions and
134398  * limitations under the License.
134399  */
134400 function PushData(data, port) {
134401     this.port = port;
134402     this.data = data;
134403
134404     this.getHeaderField = function (field) {
134405         if (field === undefined || field === null) {
134406             throw "no field specified";
134407         }
134408         else if (!(typeof field === 'number' && field >= 0) && typeof field !== 'string') {
134409             throw "field is not valid";
134410         }
134411
134412         return data.headerField[field];
134413     };
134414
134415     this.getRequestURI =  function () {
134416         return data.requestURI;
134417     };
134418
134419     this.getSource = function () {
134420         return data.source;
134421     };
134422
134423     this.isChannelEncrypted = data.isChannelEncrypted;
134424
134425     this.payload = data.payload;
134426
134427     this.__defineGetter__("ACCEPT", function () {
134428         return 0;
134429     });
134430     this.__defineGetter__("DECLINE_USERDCR", function () {
134431         return 1;
134432     });
134433     this.__defineGetter__("DECLINE_USERDCU", function () {
134434         return 2;
134435     });
134436     this.__defineGetter__("DECLINE_USERPND", function () {
134437         return 3;
134438     });
134439     this.__defineGetter__("DECLINE_USERREQ", function () {
134440         return 4;
134441     });
134442     this.__defineGetter__("DECLINE_USERRFS", function () {
134443         return 5;
134444     });
134445 }
134446
134447 module.exports = PushData;
134448
134449 });
134450 define('ripple/platform/webworks.handset/2.0.0/client/Recurrence', function (require, exports, module) {
134451 /*
134452  *  Copyright 2011 Research In Motion Limited.
134453  *
134454  * Licensed under the Apache License, Version 2.0 (the "License");
134455  * you may not use this file except in compliance with the License.
134456  * You may obtain a copy of the License at
134457  *
134458  * http://www.apache.org/licenses/LICENSE-2.0
134459  *
134460  * Unless required by applicable law or agreed to in writing, software
134461  * distributed under the License is distributed on an "AS IS" BASIS,
134462  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134463  * See the License for the specific language governing permissions and
134464  * limitations under the License.
134465  */
134466 function Recurrence() {
134467     return {
134468         //readwrite  property  Number   count
134469         //readwrite  property  Number   dayInMonth
134470         //readwrite  property  Number   dayInWeek
134471         //readwrite  property  Number   dayInYear
134472         //readwrite  property  Date   end
134473         //readwrite  property  Number   frequency
134474         //readwrite  property  Number   interval
134475         //readwrite  property  Number   monthInYear
134476         //readwrite  property  Number   weekInMonth
134477
134478         count: null,
134479         dayInMonth: null,
134480         dayInWeek: null,
134481         dayInYear: null,
134482         end: null,
134483         frequency: null,
134484         interval: null,
134485         monthInYear: null,
134486         weekInMonth: null
134487     };
134488 }
134489
134490 Recurrence.__defineGetter__("NO_REPEAT", function () {
134491     return 0;
134492 });
134493 Recurrence.__defineGetter__("DAILY", function () {
134494     return 1;
134495 });
134496 Recurrence.__defineGetter__("WEEKLY", function () {
134497     return 2;
134498 });
134499 Recurrence.__defineGetter__("MONTHLY", function () {
134500     return 3;
134501 });
134502 Recurrence.__defineGetter__("YEARLY", function () {
134503     return 4;
134504 });
134505 Recurrence.__defineGetter__("JANUARY", function () {
134506     return 0x20000;
134507 });
134508 Recurrence.__defineGetter__("FEBRUARY", function () {
134509     return 0x40000;
134510 });
134511 Recurrence.__defineGetter__("MARCH", function () {
134512     return 0x80000;
134513 });
134514 Recurrence.__defineGetter__("APRIL", function () {
134515     return 0x100000;
134516 });
134517 Recurrence.__defineGetter__("MAY", function () {
134518     return 0x200000;
134519 });
134520 Recurrence.__defineGetter__("JUNE", function () {
134521     return 0x400000;
134522 });
134523 Recurrence.__defineGetter__("JULY", function () {
134524     return 0x800000;
134525 });
134526 Recurrence.__defineGetter__("AUGUST", function () {
134527     return 0x1000000;
134528 });
134529 Recurrence.__defineGetter__("SEPTEMBER", function () {
134530     return 0x2000000;
134531 });
134532 Recurrence.__defineGetter__("OCTOBER", function () {
134533     return 0x4000000;
134534 });
134535 Recurrence.__defineGetter__("NOVEMBER", function () {
134536     return 0x8000000;
134537 });
134538 Recurrence.__defineGetter__("DECEMBER", function () {
134539     return 0x10000000;
134540 });
134541 Recurrence.__defineGetter__("FIRST", function () {
134542     return 0x1;
134543 });
134544 Recurrence.__defineGetter__("SECOND", function () {
134545     return 0x2;
134546 });
134547 Recurrence.__defineGetter__("THIRD", function () {
134548     return 0x4;
134549 });
134550 Recurrence.__defineGetter__("FOURTH", function () {
134551     return 0x8;
134552 });
134553 Recurrence.__defineGetter__("FIFTH", function () {
134554     return 0x10;
134555 });
134556 Recurrence.__defineGetter__("LAST", function () {
134557     return 0x20;
134558 });
134559 Recurrence.__defineGetter__("SECONDLAST", function () {
134560     return 0x40;
134561 });
134562 Recurrence.__defineGetter__("THIRDLAST", function () {
134563     return 0x80;
134564 });
134565 Recurrence.__defineGetter__("FOURTHLAST", function () {
134566     return 0x100;
134567 });
134568 Recurrence.__defineGetter__("FIFTHLAST", function () {
134569     return 0x200;
134570 });
134571 Recurrence.__defineGetter__("SUNDAY", function () {
134572     return 0x10000;
134573 });
134574 Recurrence.__defineGetter__("MONDAY", function () {
134575     return 0x8000;
134576 });
134577 Recurrence.__defineGetter__("TUESDAY", function () {
134578     return 0x4000;
134579 });
134580 Recurrence.__defineGetter__("WEDNESDAY", function () {
134581     return 0x2000;
134582 });
134583 Recurrence.__defineGetter__("THURSDAY", function () {
134584     return 0x1000;
134585 });
134586 Recurrence.__defineGetter__("FRIDAY", function () {
134587     return 0x800;
134588 });
134589 Recurrence.__defineGetter__("SATURDAY", function () {
134590     return 0x400;
134591 });
134592
134593 module.exports = Recurrence;
134594
134595 });
134596 define('ripple/platform/webworks.handset/2.0.0/client/Reminder', function (require, exports, module) {
134597 /*
134598  *  Copyright 2011 Research In Motion Limited.
134599  *
134600  * Licensed under the Apache License, Version 2.0 (the "License");
134601  * you may not use this file except in compliance with the License.
134602  * You may obtain a copy of the License at
134603  *
134604  * http://www.apache.org/licenses/LICENSE-2.0
134605  *
134606  * Unless required by applicable law or agreed to in writing, software
134607  * distributed under the License is distributed on an "AS IS" BASIS,
134608  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134609  * See the License for the specific language governing permissions and
134610  * limitations under the License.
134611  */
134612 var Reminder = function () {
134613
134614     return {
134615         //readwrite  property  Date   date
134616         //readwrite  property  Number   relativeHours
134617         //readwrite  property  Number   type
134618
134619         date: null,
134620         relativeHours: null,
134621         type: null
134622
134623     };
134624
134625 };
134626
134627 Reminder.__defineGetter__("DATE", function () {
134628     return 0;
134629 });
134630
134631 Reminder.__defineGetter__("RELATIVE", function () {
134632     return 1;
134633 });
134634
134635 module.exports = Reminder;
134636
134637 });
134638 define('ripple/platform/webworks.handset/2.0.0/client/SearchArguments', function (require, exports, module) {
134639 /*
134640  *  Copyright 2011 Research In Motion Limited.
134641  *
134642  * Licensed under the Apache License, Version 2.0 (the "License");
134643  * you may not use this file except in compliance with the License.
134644  * You may obtain a copy of the License at
134645  *
134646  * http://www.apache.org/licenses/LICENSE-2.0
134647  *
134648  * Unless required by applicable law or agreed to in writing, software
134649  * distributed under the License is distributed on an "AS IS" BASIS,
134650  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134651  * See the License for the specific language governing permissions and
134652  * limitations under the License.
134653  */
134654 //blackberry.invoke.SearchArguments ( )
134655 //blackberry.invoke.SearchArguments ( text : String ,  name : String )
134656 var _self = function (text, name) {
134657
134658     return {
134659         text: text,
134660         name: name
134661     };
134662
134663 };
134664
134665 module.exports = _self;
134666
134667 });
134668 define('ripple/platform/webworks.handset/2.0.0/client/Task', function (require, exports, module) {
134669 /*
134670  *  Copyright 2011 Research In Motion Limited.
134671  *
134672  * Licensed under the Apache License, Version 2.0 (the "License");
134673  * you may not use this file except in compliance with the License.
134674  * You may obtain a copy of the License at
134675  *
134676  * http://www.apache.org/licenses/LICENSE-2.0
134677  *
134678  * Unless required by applicable law or agreed to in writing, software
134679  * distributed under the License is distributed on an "AS IS" BASIS,
134680  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134681  * See the License for the specific language governing permissions and
134682  * limitations under the License.
134683  */
134684 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
134685     _uri = "blackberry/pim/Task/";
134686
134687 function Task() {
134688     var _self = {
134689         save: function () {
134690             if (!_self.uid) {
134691                 _self.uid = Math.uuid(null, 16);
134692             }
134693             transport.call(_uri + "save",  {
134694                 post: {
134695                     task: _self
134696                 }
134697             });
134698         },
134699         remove: function () {
134700             if (!_self.uid) {
134701                 throw "task has not yet been saved (has no uid)";
134702             }
134703             transport.call(_uri + "remove", {
134704                 get: {
134705                     id: _self.uid
134706                 }
134707             });
134708         },
134709         uid: null,
134710         categories: [],
134711         due: null,
134712         note: "",
134713         priority: Task.PRIORITY_NORMAL,
134714         recurrence: null,
134715         reminder: null,
134716         status: Task.NOT_STARTED,
134717         summary: ""
134718     };
134719
134720     return _self;
134721 }
134722
134723 function _massage(property, name) {
134724     if (name === "recurrence" && property) {
134725         if (property.end) {
134726             property.end = new Date(property.end);
134727         }
134728     }
134729     if (name === "reminder" && property) {
134730         if (property.date) {
134731             property.date = new Date(property.date);
134732         }
134733     }
134734     if (name === "due" && property) {
134735         property = new Date(property);
134736     }
134737     return property;
134738 }
134739
134740 Task.find = function (filter, orderBy, maxReturn, isAscending) {
134741     return transport.call(_uri + "find", {
134742         post: {
134743             filter: filter,
134744             orderBy: orderBy,
134745             maxReturn: maxReturn,
134746             isAscending: isAscending
134747         }
134748     }).map(function (properties) {
134749         var task = new Task(),
134750             key;
134751         for (key in properties) {
134752             if (task.hasOwnProperty(key)) {
134753                 task[key] = _massage(properties[key], key);
134754             }
134755         }
134756         return task;
134757     });
134758 };
134759
134760 Task.__defineGetter__("NOT_STARTED", function () {
134761     return 0;
134762 });
134763
134764 Task.__defineGetter__("IN_PROGRESS", function () {
134765     return 1;
134766 });
134767
134768 Task.__defineGetter__("COMPLETED", function () {
134769     return 2;
134770 });
134771
134772 Task.__defineGetter__("WAITING", function () {
134773     return 3;
134774 });
134775
134776 Task.__defineGetter__("DEFERRED", function () {
134777     return 4;
134778 });
134779
134780 Task.__defineGetter__("PRIORITY_HIGH", function () {
134781     return 0;
134782 });
134783
134784 Task.__defineGetter__("PRIORITY_NORMAL", function () {
134785     return 1;
134786 });
134787
134788 Task.__defineGetter__("PRIORITY_LOW", function () {
134789     return 2;
134790 });
134791
134792 module.exports = Task;
134793
134794 });
134795 define('ripple/platform/webworks.handset/2.0.0/client/TaskArguments', function (require, exports, module) {
134796 /*
134797  *  Copyright 2011 Research In Motion Limited.
134798  *
134799  * Licensed under the Apache License, Version 2.0 (the "License");
134800  * you may not use this file except in compliance with the License.
134801  * You may obtain a copy of the License at
134802  *
134803  * http://www.apache.org/licenses/LICENSE-2.0
134804  *
134805  * Unless required by applicable law or agreed to in writing, software
134806  * distributed under the License is distributed on an "AS IS" BASIS,
134807  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134808  * See the License for the specific language governing permissions and
134809  * limitations under the License.
134810  */
134811 //blackberry.invoke.TaskArguments ( [task : blackberry.pim.Task ] )
134812 var _self = function (task) {
134813     return {
134814         view: 0,
134815         task: task
134816     };
134817 };
134818
134819 //const Number  VIEW_NEW  = 0
134820 _self.__defineGetter__("VIEW_NEW", function () {
134821     return 0;
134822 });
134823 //const Number  VIEW_EDIT  = 1
134824 _self.__defineGetter__("VIEW_EDIT", function () {
134825     return 1;
134826 });
134827
134828 module.exports = _self;
134829
134830 });
134831 define('ripple/platform/webworks.handset/2.0.0/client/app', function (require, exports, module) {
134832 /*\r
134833  *  Copyright 2011 Research In Motion Limited.\r
134834  *\r
134835  * Licensed under the Apache License, Version 2.0 (the "License");\r
134836  * you may not use this file except in compliance with the License.\r
134837  * You may obtain a copy of the License at\r
134838  *\r
134839  * http://www.apache.org/licenses/LICENSE-2.0\r
134840  *\r
134841  * Unless required by applicable law or agreed to in writing, software\r
134842  * distributed under the License is distributed on an "AS IS" BASIS,\r
134843  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
134844  * See the License for the specific language governing permissions and\r
134845  * limitations under the License.\r
134846  */\r
134847 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
134848     _uri = "blackberry/app/",\r
134849     _self;\r
134850 \r
134851 _self = {\r
134852     exit: function () {\r
134853         transport.call(_uri + "exit", {async: true});\r
134854     },\r
134855 \r
134856     setHomeScreenIcon: function (uri, hover) {\r
134857         transport.call(_uri + "setHomeScreenIcon", {\r
134858             get: {\r
134859                 uri: uri,\r
134860                 hover: hover\r
134861             },\r
134862             async: true\r
134863         });\r
134864 \r
134865         return true;\r
134866     },\r
134867 \r
134868     setHomeScreenName: function (text) {\r
134869         transport.call(_uri + "setHomeScreenName", {\r
134870             get: {text: text},\r
134871             async: true\r
134872         });\r
134873 \r
134874         return true;\r
134875     },\r
134876 \r
134877     requestForeground: function () {\r
134878         transport.call(_uri + "requestForeground", {async: true});\r
134879     },\r
134880 \r
134881     requestBackground: function () {\r
134882         transport.call(_uri + "requestBackground", {async: true});\r
134883     },\r
134884 \r
134885     removeBannerIndicator: function () {\r
134886         transport.call(_uri + "removeBannerIndicator", {async: true});\r
134887     },\r
134888 \r
134889     showBannerIndicator: function (icon, count) {\r
134890         transport.call(_uri + "showBannerIndicator", {\r
134891             get: {\r
134892                 icon: icon,\r
134893                 count: count\r
134894             },\r
134895             async: true\r
134896         });\r
134897     },\r
134898 };\r
134899 \r
134900 _self.__defineGetter__("author", function () {\r
134901     return transport.call(_uri + "author");\r
134902 });\r
134903 \r
134904 _self.__defineGetter__("authorEmail", function () {\r
134905     return transport.call(_uri + "authorEmail");\r
134906 });\r
134907 \r
134908 _self.__defineGetter__("authorURL", function () {\r
134909     return transport.call(_uri + "authorURL");\r
134910 });\r
134911 \r
134912 _self.__defineGetter__("copyright", function () {\r
134913     return transport.call(_uri + "copyright");\r
134914 });\r
134915 \r
134916 _self.__defineGetter__("description", function () {\r
134917     return transport.call(_uri + "description");\r
134918 });\r
134919 \r
134920 _self.__defineGetter__("id", function () {\r
134921     return transport.call(_uri + "id");\r
134922 });\r
134923 \r
134924 _self.__defineGetter__("isForeground", function () {\r
134925     return transport.call(_uri + "isForeground");\r
134926 });\r
134927 \r
134928 _self.__defineGetter__("license", function () {\r
134929     return transport.call(_uri + "license");\r
134930 });\r
134931 \r
134932 _self.__defineGetter__("licenseURL", function () {\r
134933     return transport.call(_uri + "licenseURL");\r
134934 });\r
134935 \r
134936 _self.__defineGetter__("name", function () {\r
134937     return transport.call(_uri + "name");\r
134938 });\r
134939 \r
134940 _self.__defineGetter__("version", function () {\r
134941     return transport.call(_uri + "version");\r
134942 });\r
134943 \r
134944 module.exports = _self;\r
134945
134946 });
134947 define('ripple/platform/webworks.handset/2.0.0/client/appEvent', function (require, exports, module) {
134948 /*
134949  *  Copyright 2011 Research In Motion Limited.
134950  *
134951  * Licensed under the Apache License, Version 2.0 (the "License");
134952  * you may not use this file except in compliance with the License.
134953  * You may obtain a copy of the License at
134954  *
134955  * http://www.apache.org/licenses/LICENSE-2.0
134956  *
134957  * Unless required by applicable law or agreed to in writing, software
134958  * distributed under the License is distributed on an "AS IS" BASIS,
134959  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134960  * See the License for the specific language governing permissions and
134961  * limitations under the License.
134962  */
134963 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
134964     _callbacks = {},
134965     _self;
134966
134967 function _poll(evt, handler) {
134968     _callbacks[evt] = handler;
134969
134970     transport.poll("blackberry/app/event/" + evt, {}, function () {
134971         var func = _callbacks[evt];
134972
134973         if (func) {
134974             func();
134975         }
134976
134977         return !!func;
134978     });
134979 }
134980
134981 _self = {
134982     onBackground: function (handler) {
134983         _poll("onBackground", handler);
134984     },
134985
134986     onForeground: function (handler) {
134987         _poll("onForeground", handler);
134988     },
134989
134990     onExit: function (handler) {
134991         _poll("onExit", handler);
134992     }
134993 };
134994
134995 module.exports = _self;
134996
134997 });
134998 define('ripple/platform/webworks.handset/2.0.0/client/audio', function (require, exports, module) {
134999 /*
135000  *  Copyright 2011 Research In Motion Limited.
135001  *
135002  * Licensed under the Apache License, Version 2.0 (the "License");
135003  * you may not use this file except in compliance with the License.
135004  * You may obtain a copy of the License at
135005  *
135006  * http://www.apache.org/licenses/LICENSE-2.0
135007  *
135008  * Unless required by applicable law or agreed to in writing, software
135009  * distributed under the License is distributed on an "AS IS" BASIS,
135010  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135011  * See the License for the specific language governing permissions and
135012  * limitations under the License.
135013  */
135014 module.exports = {
135015     supportedContentTypes: function (protocol) {
135016         return protocol === 'rtsp' ?
135017             ['audio/amr', 'audio/mp4', 'audio/aac'] :
135018             ['audio/midi', 'mpeg', 'x-wav', 'amr', 'basic', 'x-gsm', 'mp4', 'aac', 'x-ms-wma', 'flac', 'ogg'];
135019     },
135020     supportedProtocols: function (contentType) {
135021         return ['http', 'file', 'rtsp'];
135022     }
135023 };
135024
135025 });
135026 define('ripple/platform/webworks.handset/2.0.0/client/blackberry', function (require, exports, module) {
135027 /*
135028  * Copyright 2011 Research In Motion Limited.
135029  *
135030  * Licensed under the Apache License, Version 2.0 (the "License");
135031  * you may not use this file except in compliance with the License.
135032  * You may obtain a copy of the License at
135033  *
135034  *     http://www.apache.org/licenses/LICENSE-2.0
135035  *
135036  * Unless required by applicable law or agreed to in writing, software
135037  * distributed under the License is distributed on an "AS IS" BASIS,
135038  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135039  * See the License for the specific language governing permissions and
135040  * limitations under the License.
135041  */
135042 var blackberry = {},
135043     transport = require('ripple/platform/webworks.core/2.0.0/client/transport');
135044
135045 blackberry.__defineGetter__("network", function () {
135046     return transport.call("blackberry/system/network");
135047 });
135048
135049 module.exports = blackberry;
135050
135051 });
135052 define('ripple/platform/webworks.handset/2.0.0/client/category', function (require, exports, module) {
135053 /*
135054  *  Copyright 2011 Research In Motion Limited.
135055  *
135056  * Licensed under the Apache License, Version 2.0 (the "License");
135057  * you may not use this file except in compliance with the License.
135058  * You may obtain a copy of the License at
135059  *
135060  * http://www.apache.org/licenses/LICENSE-2.0
135061  *
135062  * Unless required by applicable law or agreed to in writing, software
135063  * distributed under the License is distributed on an "AS IS" BASIS,
135064  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135065  * See the License for the specific language governing permissions and
135066  * limitations under the License.
135067  */
135068 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
135069     _uri = "blackberry/pim/category/",
135070     _self;
135071
135072 _self = {
135073     addCategory: function (categoryName) {
135074         transport.call(_uri + "addCategory", {
135075             get: {categoryName: categoryName}
135076         });
135077     },
135078     deleteCategory: function (categoryName) {
135079         transport.call(_uri + "deleteCategory", {
135080             get: {categoryName: categoryName}
135081         });
135082     },
135083     getCategories: function () {
135084         return transport.call(_uri + "getCategories");
135085     }
135086 };
135087
135088 module.exports = _self;
135089
135090 });
135091 define('ripple/platform/webworks.handset/2.0.0/client/identity/Service', function (require, exports, module) {
135092 /*
135093  *  Copyright 2011 Research In Motion Limited.
135094  *
135095  * Licensed under the Apache License, Version 2.0 (the "License");
135096  * you may not use this file except in compliance with the License.
135097  * You may obtain a copy of the License at
135098  *
135099  * http://www.apache.org/licenses/LICENSE-2.0
135100  *
135101  * Unless required by applicable law or agreed to in writing, software
135102  * distributed under the License is distributed on an "AS IS" BASIS,
135103  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135104  * See the License for the specific language governing permissions and
135105  * limitations under the License.
135106  */
135107 function Service() {
135108     return {
135109         emailAddress: null,
135110         isDefault: null,
135111         name: null,
135112         type: null
135113     };
135114 }
135115
135116 Service.__defineGetter__("TYPE_EMAIL", function () {
135117     return 0;
135118 });
135119
135120 Service.__defineGetter__("TYPE_CALENDAR", function () {
135121     return 1;
135122 });
135123
135124 Service.__defineGetter__("TYPE_CONTACT", function () {
135125     return 2;
135126 });
135127
135128 module.exports = Service;
135129
135130 });
135131 define('ripple/platform/webworks.handset/2.0.0/client/identity/Transport', function (require, exports, module) {
135132 /*
135133  *  Copyright 2011 Research In Motion Limited.
135134  *
135135  * Licensed under the Apache License, Version 2.0 (the "License");
135136  * you may not use this file except in compliance with the License.
135137  * You may obtain a copy of the License at
135138  *
135139  * http://www.apache.org/licenses/LICENSE-2.0
135140  *
135141  * Unless required by applicable law or agreed to in writing, software
135142  * distributed under the License is distributed on an "AS IS" BASIS,
135143  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135144  * See the License for the specific language governing permissions and
135145  * limitations under the License.
135146  */
135147 function Transport(name, type) {
135148     this.__defineGetter__("name", function () {
135149         return name || "";
135150     });
135151     this.__defineGetter__("type", function () {
135152         return type || "";
135153     });
135154 }
135155
135156 module.exports = Transport;
135157
135158 });
135159 define('ripple/platform/webworks.handset/2.0.0/client/identity/phone', function (require, exports, module) {
135160 /*
135161  *  Copyright 2011 Research In Motion Limited.
135162  *
135163  * Licensed under the Apache License, Version 2.0 (the "License");
135164  * you may not use this file except in compliance with the License.
135165  * You may obtain a copy of the License at
135166  *
135167  * http://www.apache.org/licenses/LICENSE-2.0
135168  *
135169  * Unless required by applicable law or agreed to in writing, software
135170  * distributed under the License is distributed on an "AS IS" BASIS,
135171  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135172  * See the License for the specific language governing permissions and
135173  * limitations under the License.
135174  */
135175 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
135176     _uri = "blackberry/identity/phone/",
135177     _self;
135178
135179 _self = {
135180     getLineIds: function () {
135181         return transport.call(_uri + "getLineIds");
135182     },
135183     getLineLabel: function (id) {
135184         return transport.call(_uri + "getLineLabel", {get: {id: id}});
135185     },
135186     getLineNumber: function (id) {
135187         return transport.call(_uri + "getLineNumber", {get: {id: id}});
135188     },
135189     getLineType: function (id) {
135190         return transport.call(_uri + "getLineType", {get: {id: id}});
135191     }
135192 };
135193
135194 module.exports = _self;
135195
135196 });
135197 define('ripple/platform/webworks.handset/2.0.0/client/identity', function (require, exports, module) {
135198 /*
135199  *  Copyright 2011 Research In Motion Limited.
135200  *
135201  * Licensed under the Apache License, Version 2.0 (the "License");
135202  * you may not use this file except in compliance with the License.
135203  * You may obtain a copy of the License at
135204  *
135205  * http://www.apache.org/licenses/LICENSE-2.0
135206  *
135207  * Unless required by applicable law or agreed to in writing, software
135208  * distributed under the License is distributed on an "AS IS" BASIS,
135209  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135210  * See the License for the specific language governing permissions and
135211  * limitations under the License.
135212  */
135213 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
135214     _uri = "blackberry/identity/",
135215     _self;
135216
135217 _self = {
135218     getDefaultService: function () {
135219         return transport.call(_uri + "getDefaultService");
135220     },
135221     getServiceList: function () {
135222         return transport.call(_uri + "getServiceList");
135223     },
135224     getTransportList: function () {
135225         return transport.call(_uri + "getTransportList");
135226     }
135227 };
135228
135229 _self.__defineGetter__("IMEI", function () {
135230     return transport.call(_uri + "IMEI");
135231 });
135232
135233 _self.__defineGetter__("IMSI", function () {
135234     return transport.call(_uri + "IMSI");
135235 });
135236
135237 _self.__defineGetter__("PIN", function () {
135238     return transport.call(_uri + "PIN");
135239 });
135240
135241 module.exports = _self;
135242
135243 });
135244 define('ripple/platform/webworks.handset/2.0.0/client/invoke', function (require, exports, module) {
135245 /*\r
135246  *  Copyright 2011 Research In Motion Limited.\r
135247  *\r
135248  * Licensed under the Apache License, Version 2.0 (the "License");\r
135249  * you may not use this file except in compliance with the License.\r
135250  * You may obtain a copy of the License at\r
135251  *\r
135252  * http://www.apache.org/licenses/LICENSE-2.0\r
135253  *\r
135254  * Unless required by applicable law or agreed to in writing, software\r
135255  * distributed under the License is distributed on an "AS IS" BASIS,\r
135256  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
135257  * See the License for the specific language governing permissions and\r
135258  * limitations under the License.\r
135259  */\r
135260 var _uri = "blackberry/invoke/invoke",\r
135261     APP_URL_CAMERA = "camera://",\r
135262     APP_URL_CAMERA_VIDEO = "camera://video",\r
135263     APP_URL_MAP = "map://",\r
135264     APP_URL_MUSIC = "music://",\r
135265     APP_URL_PHOTOS = "photos://",\r
135266     APP_URL_VIDEOS = "videos://",\r
135267     APP_URL_APPWORLD = "appworld://",\r
135268     APP_URL_UPDATE = "update://",\r
135269     APP_BROWSER_ERROR = "Protocol specified in the url is not supported.",\r
135270     APP_ADDRESSBOOK_ERROR = "Invalid arguments specified",\r
135271     transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
135272     _self;\r
135273 \r
135274 _self = {\r
135275     invoke: function (appType, args) {\r
135276         var get = {};\r
135277 \r
135278         switch (appType) {\r
135279 \r
135280         //AddressBook\r
135281         case 0:\r
135282             if (args) {\r
135283                 if (args.view === 1 && args.contact) {\r
135284                     throw APP_ADDRESSBOOK_ERROR; //contact cannot be used with this view\r
135285                 }\r
135286                 else if (args.view === 2 && !args.contact) {\r
135287                     throw APP_ADDRESSBOOK_ERROR; //need contact for this view\r
135288                 }\r
135289             }\r
135290 \r
135291             get.appType = appType;\r
135292             break;\r
135293 \r
135294         //Bluetooth Config\r
135295         case 1:\r
135296             get.appType = appType;\r
135297             break;\r
135298 \r
135299         //Calculator\r
135300         case 2:\r
135301             get.appType = appType;\r
135302             break;\r
135303 \r
135304         //Calendar\r
135305         case 3:\r
135306             get.appType = appType;\r
135307             break;\r
135308 \r
135309         //Camera\r
135310         case 4:\r
135311             if (!args || args.view === 1) {\r
135312                 get.appType = APP_URL_CAMERA_VIDEO;\r
135313             } else {\r
135314                 get.appType = APP_URL_CAMERA;\r
135315             }\r
135316             break;\r
135317 \r
135318         //Maps\r
135319         case 5:\r
135320             get.appType = APP_URL_MAP;\r
135321             break;\r
135322 \r
135323         //Memopad\r
135324         case 6:\r
135325             get.appType = appType;\r
135326             break;\r
135327 \r
135328         //Messages\r
135329         case 7:\r
135330             get.appType = appType;\r
135331             break;\r
135332 \r
135333         //Phone\r
135334         case 8:\r
135335             get.appType = appType;\r
135336             break;\r
135337 \r
135338         //Search\r
135339         case 9:\r
135340             get.appType = appType;\r
135341             break;\r
135342 \r
135343         //Tasks\r
135344         case 10:\r
135345             get.appType = appType;\r
135346             break;\r
135347 \r
135348         //Browser\r
135349         case 11:\r
135350 \r
135351             if (!args) {\r
135352                 get.appType = "http://";\r
135353             } else {\r
135354                 if (args.url && !args.url.match(/^https?:\/\//)) {\r
135355                     throw APP_BROWSER_ERROR;\r
135356                 }\r
135357                 get.appType = args.url;\r
135358             }\r
135359 \r
135360             break;\r
135361 \r
135362         //Java\r
135363         case 12:\r
135364             get.appType = appType;\r
135365             break;\r
135366 \r
135367         default:\r
135368             throw "appType not supported";\r
135369         }\r
135370 \r
135371         transport.call(_uri, {\r
135372             get: get,\r
135373             async: true\r
135374         });\r
135375     }\r
135376 };\r
135377 \r
135378 _self.__defineGetter__("APP_ADDRESSBOOK", function () {\r
135379     return 0;\r
135380 });\r
135381 _self.__defineGetter__("APP_BLUETOOTH_CONFIG", function () {\r
135382     return 1;\r
135383 });\r
135384 _self.__defineGetter__("APP_CALCULATOR", function () {\r
135385     return 2;\r
135386 });\r
135387 _self.__defineGetter__("APP_CALENDAR", function () {\r
135388     return 3;\r
135389 });\r
135390 _self.__defineGetter__("APP_CAMERA", function () {\r
135391     return 4;\r
135392 });\r
135393 _self.__defineGetter__("APP_MAPS", function () {\r
135394     return 5;\r
135395 });\r
135396 _self.__defineGetter__("APP_MEMOPAD", function () {\r
135397     return 6;\r
135398 });\r
135399 _self.__defineGetter__("APP_MESSAGES", function () {\r
135400     return 7;\r
135401 });\r
135402 _self.__defineGetter__("APP_PHONE", function () {\r
135403     return 8;\r
135404 });\r
135405 _self.__defineGetter__("APP_SEARCH", function () {\r
135406     return 9;\r
135407 });\r
135408 _self.__defineGetter__("APP_TASKS", function () {\r
135409     return 10;\r
135410 });\r
135411 _self.__defineGetter__("APP_BROWSER", function () {\r
135412     return 11;\r
135413 });\r
135414 _self.__defineGetter__("APP_JAVA", function () {\r
135415     return 12;\r
135416 });\r
135417 \r
135418 module.exports = _self;\r
135419
135420 });
135421 define('ripple/platform/webworks.handset/2.0.0/client/io/dir', function (require, exports, module) {
135422 /*
135423  * Copyright 2011 Research In Motion Limited.
135424  *
135425  * Licensed under the Apache License, Version 2.0 (the "License");
135426  * you may not use this file except in compliance with the License.
135427  * You may obtain a copy of the License at
135428  *
135429  *     http://www.apache.org/licenses/LICENSE-2.0
135430  *
135431  * Unless required by applicable law or agreed to in writing, software
135432  * distributed under the License is distributed on an "AS IS" BASIS,
135433  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135434  * See the License for the specific language governing permissions and
135435  * limitations under the License.
135436  */
135437 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
135438     dir = require('ripple/platform/webworks.core/2.0.0/client/io/dir'),
135439     utils = require('ripple/utils'),
135440     _uri = "blackberry/io/dir/",
135441     FILE = "file://",
135442     _self = {};
135443
135444 function _prunePrefix(path) {
135445     return path.replace(new RegExp("^" + FILE), '');
135446 }
135447
135448 utils.mixin({
135449     getFreeSpaceForRoot: function (path) {
135450         return transport.call(_uri + "getFreeSpaceForRoot", {
135451             post: {path: _prunePrefix(path)}
135452         });
135453     },
135454     getRootDirs: function () {
135455         return transport.call(_uri + "getRootDirs", {}).map(function (dir) {
135456             return FILE + dir;
135457         });
135458     }
135459 }, _self);
135460
135461 utils.mixin(dir, _self);
135462
135463 module.exports = _self;
135464
135465 });
135466 define('ripple/platform/webworks.handset/2.0.0/client/menu', function (require, exports, module) {
135467 /*
135468  *  Copyright 2011 Research In Motion Limited.
135469  *
135470  * Licensed under the Apache License, Version 2.0 (the "License");
135471  * you may not use this file except in compliance with the License.
135472  * You may obtain a copy of the License at
135473  *
135474  * http://www.apache.org/licenses/LICENSE-2.0
135475  *
135476  * Unless required by applicable law or agreed to in writing, software
135477  * distributed under the License is distributed on an "AS IS" BASIS,
135478  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135479  * See the License for the specific language governing permissions and
135480  * limitations under the License.
135481  */
135482 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
135483     MenuItem = require('ripple/platform/webworks.handset/2.0.0/client/MenuItem'),
135484     utils = require('ripple/utils'),
135485     onSelect,
135486     _items = {},
135487     _uri = "blackberry/ui/menu/",
135488     _self;
135489
135490 _self = {
135491     addMenuItem: function (menuItem) {
135492         _items[menuItem.id] = menuItem;
135493
135494         transport.call(_uri + "addMenuItem", {
135495             get: {"item": menuItem}
135496         });
135497
135498         if (utils.count(_items) === 1) {
135499             transport.poll(_uri + "onSelect", {}, function (response) {
135500                 var item = _items[response];
135501
135502                 if (item && item.callback) {
135503                     item.callback();
135504                 }
135505
135506                 return !!utils.count(_items);
135507             });
135508         }
135509     },
135510
135511     clearMenuItems: function () {
135512         _items = {};
135513         transport.call(_uri + "clearMenuItems");
135514     },
135515
135516     getMenuItems: function () {
135517         return utils.map(_items, function (item) {
135518             var menuItem = new MenuItem(item.isSeparator, item.ordinal, item.caption, item.callback);
135519             menuItem.id = item.id;
135520             menuItem.isDefault = item.isDefault;
135521             return menuItem;
135522         });
135523     },
135524
135525     hasMenuItem: function (menuItem) {
135526         return !!_items[menuItem.id];
135527     },
135528
135529     open: function () {
135530         transport.call(_uri + "open", {async: true});
135531     },
135532
135533     removeMenuItem: function (menuItem) {
135534         delete _items[menuItem.id];
135535         transport.call(_uri + "removeMenuItem", {
135536             get: {item: menuItem}
135537         });
135538     },
135539
135540     setDefaultMenuItem: function (menuItem) {
135541         utils.forEach(_items, function (item) {
135542             item.isDefault = false;
135543         });
135544
135545         _items[menuItem.id].isDefault = true;
135546
135547         transport.call(_uri + "setDefaultMenuItem", {
135548             get: {id: menuItem.id}
135549         });
135550     }
135551 };
135552
135553 module.exports = _self;
135554
135555 });
135556 define('ripple/platform/webworks.handset/2.0.0/client/messaging', function (require, exports, module) {
135557 /*
135558  *  Copyright 2011 Research In Motion Limited.
135559  *
135560  * Licensed under the Apache License, Version 2.0 (the "License");
135561  * you may not use this file except in compliance with the License.
135562  * You may obtain a copy of the License at
135563  *
135564  * http://www.apache.org/licenses/LICENSE-2.0
135565  *
135566  * Unless required by applicable law or agreed to in writing, software
135567  * distributed under the License is distributed on an "AS IS" BASIS,
135568  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135569  * See the License for the specific language governing permissions and
135570  * limitations under the License.
135571  */
135572 module.exports = {};
135573
135574 });
135575 define('ripple/platform/webworks.handset/2.0.0/client/pim', function (require, exports, module) {
135576 /*
135577  *  Copyright 2011 Research In Motion Limited.
135578  *
135579  * Licensed under the Apache License, Version 2.0 (the "License");
135580  * you may not use this file except in compliance with the License.
135581  * You may obtain a copy of the License at
135582  *
135583  * http://www.apache.org/licenses/LICENSE-2.0
135584  *
135585  * Unless required by applicable law or agreed to in writing, software
135586  * distributed under the License is distributed on an "AS IS" BASIS,
135587  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135588  * See the License for the specific language governing permissions and
135589  * limitations under the License.
135590  */
135591 module.exports = {};
135592
135593 });
135594 define('ripple/platform/webworks.handset/2.0.0/client/push', function (require, exports, module) {
135595 /*
135596  *  Copyright 2011 Research In Motion Limited.
135597  *
135598  * Licensed under the Apache License, Version 2.0 (the "License");
135599  * you may not use this file except in compliance with the License.
135600  * You may obtain a copy of the License at
135601  *
135602  * http://www.apache.org/licenses/LICENSE-2.0
135603  *
135604  * Unless required by applicable law or agreed to in writing, software
135605  * distributed under the License is distributed on an "AS IS" BASIS,
135606  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135607  * See the License for the specific language governing permissions and
135608  * limitations under the License.
135609  */
135610 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
135611     _self,
135612     _uri = "blackberry/push/onPush",
135613     callbacks = {},
135614     PushData = require('ripple/platform/webworks.handset/2.0.0/client/PushData');
135615
135616 _self = {
135617     openPushListener: function (callback, port, bbTransport, maxQueueCap) {
135618         callbacks["onPush" + port] = callback;
135619
135620         transport.poll(_uri, {
135621             get: {
135622                 port: port,
135623                 bbTransport: bbTransport,
135624                 maxQueueCap: maxQueueCap
135625             }
135626         }, function (response) {
135627             var func = callbacks["onPush" + port];
135628
135629             if (func) {
135630                 func(new PushData(response, port));
135631             }
135632
135633             return !!func;
135634         });
135635     },
135636
135637     closePushListener: function (port) {
135638         delete callbacks["onPush" + port];
135639     }
135640 };
135641
135642 module.exports = _self;
135643
135644 });
135645 define('ripple/platform/webworks.handset/2.0.0/client/sms', function (require, exports, module) {
135646 /*
135647  *  Copyright 2011 Research In Motion Limited.
135648  *
135649  * Licensed under the Apache License, Version 2.0 (the "License");
135650  * you may not use this file except in compliance with the License.
135651  * You may obtain a copy of the License at
135652  *
135653  * http://www.apache.org/licenses/LICENSE-2.0
135654  *
135655  * Unless required by applicable law or agreed to in writing, software
135656  * distributed under the License is distributed on an "AS IS" BASIS,
135657  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135658  * See the License for the specific language governing permissions and
135659  * limitations under the License.
135660  */
135661 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
135662     _uri = "blackberry/message/sms/",
135663     onReceive,
135664     _self;
135665
135666 _self = {
135667     addReceiveListener: function (callback) {
135668         onReceive = callback;
135669         transport.poll(_uri + "onReceive", {}, function (response) {
135670             if (onReceive) {
135671                 onReceive(response.body, response.from, response.time);
135672             }
135673             return !!onReceive;
135674         });
135675     },
135676
135677     removeReceiveListener: function () {
135678         if (onReceive) {
135679             onReceive = null;
135680             return true;
135681         }
135682
135683         return false;
135684     },
135685
135686     send: function (message, address) {
135687         transport.call(_uri + "send", {
135688             get: {
135689                 message: message,
135690                 address: address
135691             },
135692             async: true
135693         });
135694     }
135695 };
135696
135697 _self.__defineGetter__("isListeningForMessage", function () {
135698     return transport.call(_uri + "isListeningForMessage", {async: false});
135699 });
135700
135701 _self.__defineSetter__("isListeningForMessage", function (value) {
135702     transport.call(_uri + "isListeningForMessage", {
135703         async: false,
135704         get: {isListeningForMessage: value}
135705     });
135706 });
135707
135708 module.exports = _self;
135709
135710 });
135711 define('ripple/platform/webworks.handset/2.0.0/client/system', function (require, exports, module) {
135712 /*
135713  *  Copyright 2011 Research In Motion Limited.
135714  *
135715  * Licensed under the Apache License, Version 2.0 (the "License");
135716  * you may not use this file except in compliance with the License.
135717  * You may obtain a copy of the License at
135718  *
135719  * http://www.apache.org/licenses/LICENSE-2.0
135720  *
135721  * Unless required by applicable law or agreed to in writing, software
135722  * distributed under the License is distributed on an "AS IS" BASIS,
135723  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135724  * See the License for the specific language governing permissions and
135725  * limitations under the License.
135726  */
135727 var utils = require('ripple/utils'),
135728     transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
135729     system = require('ripple/platform/webworks.core/2.0.0/client/system'),
135730     _uri = "blackberry/system/",
135731     _self;
135732
135733 _self = {
135734     setHomeScreenBackground: function (filePath) {
135735         transport.call(_uri + "setHomeScreenBackground", {
135736             get: {filePath: filePath},
135737             async: true
135738         });
135739     },
135740 };
135741
135742 (function () {
135743     // HACK: can't type check if system[key] is a function, sets off getters
135744     // also can't use utils.mixin or forEach for the same reason
135745     function get(i) {
135746         return function () {
135747             return system[i];
135748         };
135749     }
135750
135751     for (var key in system) {
135752         if (system.hasOwnProperty(key)) {
135753             _self.__defineGetter__(key, get(key));
135754         }
135755     }
135756 }());
135757
135758 module.exports = _self;
135759
135760 });
135761 define('ripple/platform/webworks.handset/2.0.0/client/systemEvent', function (require, exports, module) {
135762 /*
135763  *  Copyright 2011 Research In Motion Limited.
135764  *
135765  * Licensed under the Apache License, Version 2.0 (the "License");
135766  * you may not use this file except in compliance with the License.
135767  * You may obtain a copy of the License at
135768  *
135769  * http://www.apache.org/licenses/LICENSE-2.0
135770  *
135771  * Unless required by applicable law or agreed to in writing, software
135772  * distributed under the License is distributed on an "AS IS" BASIS,
135773  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135774  * See the License for the specific language governing permissions and
135775  * limitations under the License.
135776  */
135777 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
135778     utils = require('ripple/utils'),
135779     _self,
135780         _callbacks = {};
135781
135782 function _poll(evt, args, callback) {
135783     _callbacks[evt + args.key] = callback;
135784
135785     transport.poll("blackberry/system/event/" + evt, {get: args}, function () {
135786         var func = _callbacks[evt + args.key];
135787
135788         if (func) {
135789             func();
135790         }
135791
135792         return !!func;
135793     });
135794 }
135795
135796 _self = {
135797     onCoverageChange: function (callback) {
135798         _poll("onCoverageChange", {}, callback);
135799     },
135800
135801     onHardwareKey: function (key, callback) {
135802         _poll("onHardwareKey", {key: key}, callback);
135803     }
135804 };
135805
135806 _self.__defineGetter__("KEY_BACK", function () {
135807     return 0;
135808 });
135809 _self.__defineGetter__("KEY_MENU", function () {
135810     return 1;
135811 });
135812 _self.__defineGetter__("KEY_CONVENIENCE_1", function () {
135813     return 2;
135814 });
135815 _self.__defineGetter__("KEY_CONVENIENCE_2", function () {
135816     return 3;
135817 });
135818 _self.__defineGetter__("KEY_STARTCALL", function () {
135819     return 4;
135820 });
135821 _self.__defineGetter__("KEY_ENDCALL", function () {
135822     return 5;
135823 });
135824 _self.__defineGetter__("KEY_VOLUMEDOWN", function () {
135825     return 6;
135826 });
135827 _self.__defineGetter__("KEY_VOLUMEUP", function () {
135828     return 7;
135829 });
135830
135831 module.exports = _self;
135832
135833 });
135834 define('ripple/platform/webworks.handset/2.0.0/server/Task', function (require, exports, module) {
135835 /*
135836  *  Copyright 2011 Research In Motion Limited.
135837  *
135838  * Licensed under the Apache License, Version 2.0 (the "License");
135839  * you may not use this file except in compliance with the License.
135840  * You may obtain a copy of the License at
135841  *
135842  * http://www.apache.org/licenses/LICENSE-2.0
135843  *
135844  * Unless required by applicable law or agreed to in writing, software
135845  * distributed under the License is distributed on an "AS IS" BASIS,
135846  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135847  * See the License for the specific language governing permissions and
135848  * limitations under the License.
135849  */
135850 var select = require('ripple/platform/webworks.core/2.0.0/select'),
135851     db = require('ripple/db'),
135852     utils = require('ripple/utils'),
135853     _KEY = "blackberry-pim-task",
135854     _self;
135855
135856 function _get() {
135857     return db.retrieveObject(_KEY) || {};
135858 }
135859
135860 function _save(tasks) {
135861     db.saveObject(_KEY, tasks);
135862 }
135863
135864 _self = {
135865     save: function (get, post) {
135866         var tasks = _get(),
135867             properties = post.task,
135868             id = properties.uid;
135869
135870         if (tasks[id]) {
135871             utils.mixin(properties, tasks[id]);
135872         } else {
135873             tasks[id] = properties;
135874         }
135875
135876         _save(tasks);
135877
135878         return {code: 1};
135879     },
135880
135881     remove: function (get, post) {
135882         var tasks = _get(),
135883             id = get.id;
135884
135885         delete tasks[id];
135886
135887         _save(tasks);
135888
135889         return {code: 1};
135890     },
135891
135892     find: function (get, post) {
135893         var tasks = _get(),
135894             match = select.from(tasks);
135895
135896         if (post.orderBy) {
135897             match.orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc");
135898         }
135899
135900         if (post.maxReturn) {
135901             match.max(post.maxReturn);
135902         }
135903
135904         return {code: 1, data: match.where(post.filter)};
135905     }
135906 };
135907
135908 module.exports = _self;
135909
135910 });
135911 define('ripple/platform/webworks.handset/2.0.0/server/app', function (require, exports, module) {
135912 /*
135913  *  Copyright 2011 Research In Motion Limited.
135914  *
135915  * Licensed under the Apache License, Version 2.0 (the "License");
135916  * you may not use this file except in compliance with the License.
135917  * You may obtain a copy of the License at
135918  *
135919  * http://www.apache.org/licenses/LICENSE-2.0
135920  *
135921  * Unless required by applicable law or agreed to in writing, software
135922  * distributed under the License is distributed on an "AS IS" BASIS,
135923  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135924  * See the License for the specific language governing permissions and
135925  * limitations under the License.
135926  */
135927 var event = require('ripple/event'),
135928     app = require('ripple/app'),
135929     notifications = require('ripple/notifications'),
135930     constants = require('ripple/constants'),
135931     ui = require('ripple/ui'),
135932     _isForeground = true,
135933     _self;
135934
135935 _self = {
135936     event: require('ripple/platform/webworks.handset/2.0.0/server/appEvent'),
135937
135938     exit: function () {
135939         event.trigger("AppExit");
135940         return {code: 1};
135941     },
135942
135943     author: function () {
135944         return {code: 1, data: app.getInfo().author};
135945     },
135946
135947     authorEmail: function () {
135948         return {code: 1, data: app.getInfo().authorEmail};
135949     },
135950
135951     authorURL: function () {
135952         return {code: 1, data: app.getInfo().authorURL};
135953     },
135954
135955     copyright: function () {
135956         return {code: 1, data: app.getInfo().copyright};
135957     },
135958
135959     description: function () {
135960         return {code: 1, data: app.getInfo().description};
135961     },
135962
135963     isForeground: function () {
135964         return {code: 1, data: _isForeground};
135965     },
135966
135967     id: function () {
135968         return {code: 1, data: app.getInfo().id};
135969     },
135970
135971     license: function () {
135972         return {code: 1, data: app.getInfo().license};
135973     },
135974
135975     licenseURL: function () {
135976         return {code: 1, data: app.getInfo().licenseURL};
135977     },
135978
135979     name: function () {
135980         return {code: 1, data: app.getInfo().name};
135981     },
135982
135983     version: function () {
135984         return {code: 1, data: app.getInfo().version};
135985     },
135986
135987     requestBackground: function () {
135988         ui.showOverlay("background-window", function (background) {
135989             var button = background.children["background-return"];
135990
135991             if (button) {
135992                 button.addEventListener("click", _self.requestForeground);
135993             }
135994             _isForeground = false;
135995             event.trigger("AppRequestBackground");
135996         });
135997
135998         return {code: 1};
135999     },
136000
136001     requestForeground: function () {
136002         ui.hideOverlay("background-window", function (background) {
136003             var button = background.children["background-return"];
136004
136005             if (button) {
136006                 button.removeEventListener("click", _self.requestForeground);
136007             }
136008             _isForeground = true;
136009             event.trigger("AppRequestForeground");
136010         });
136011
136012         return {code: 1};
136013     },
136014
136015     setHomeScreenIcon: function (args) {
136016         if (args.uri) {
136017             var msg = "The application set the home screen" +
136018                (args.hover ? " hover " : " ") +
136019                "icon to " + args.uri;
136020
136021             notifications.openNotification("normal", msg);
136022             return {code: 1};
136023         }
136024         else {
136025             return {code: 0};
136026         }
136027     },
136028
136029     setHomeScreenName: function (args) {
136030         if (args.text) {
136031             var msg = "The application set the home screen name to " + args.text;
136032             notifications.openNotification("normal", msg);
136033             return {code: 1};
136034         }
136035         else {
136036             return {code: 1};
136037         }
136038     },
136039
136040     removeBannerIndicator: function () {
136041         event.trigger("BannerUpdated", ["", 0]);
136042         return {code: 1};
136043     },
136044
136045     showBannerIndicator: function (args) {
136046         event.trigger("BannerUpdated", [args.icon, args.count]);
136047         return {code: 1};
136048     },
136049
136050 };
136051
136052 module.exports = _self;
136053
136054 });
136055 define('ripple/platform/webworks.handset/2.0.0/server/appEvent', function (require, exports, module) {
136056 /*
136057  *  Copyright 2011 Research In Motion Limited.
136058  *
136059  * Licensed under the Apache License, Version 2.0 (the "License");
136060  * you may not use this file except in compliance with the License.
136061  * You may obtain a copy of the License at
136062  *
136063  * http://www.apache.org/licenses/LICENSE-2.0
136064  *
136065  * Unless required by applicable law or agreed to in writing, software
136066  * distributed under the License is distributed on an "AS IS" BASIS,
136067  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136068  * See the License for the specific language governing permissions and
136069  * limitations under the License.
136070  */
136071 var event = require('ripple/event'),
136072     notifications = require('ripple/notifications'),
136073     _bg,
136074     _fg,
136075     _exit;
136076
136077 event.on("AppRequestBackground", function () {
136078     var baton = _bg;
136079     _bg = null;
136080     return baton && baton.pass({code: 1});
136081 });
136082
136083 event.on("AppRequestForeground", function () {
136084     var baton = _fg;
136085     _fg = null;
136086     return baton && baton.pass({code: 1});
136087 });
136088
136089 event.on("AppExit", function () {
136090     var baton = _exit;
136091     _exit = null;
136092     notifications.openNotification("normal", "blackberry.app.exit() as called, in the real world your app will exit, here... you get this notification");
136093     return baton && baton.pass({code: 1});
136094 });
136095
136096 module.exports = {
136097     onBackground: function (get, post, baton) {
136098         baton.take();
136099         _bg = baton;
136100         return {code: 1};
136101     },
136102
136103     onForeground: function (get, post, baton) {
136104         baton.take();
136105         _fg = baton;
136106         return {code: 1};
136107     },
136108
136109     onExit: function (get, post, baton) {
136110         baton.take();
136111         _exit = baton;
136112         return {code: 1};
136113     }
136114 };
136115
136116 });
136117 define('ripple/platform/webworks.handset/2.0.0/server/appointment', function (require, exports, module) {
136118 /*
136119  *  Copyright 2011 Research In Motion Limited.
136120  *
136121  * Licensed under the Apache License, Version 2.0 (the "License");
136122  * you may not use this file except in compliance with the License.
136123  * You may obtain a copy of the License at
136124  *
136125  * http://www.apache.org/licenses/LICENSE-2.0
136126  *
136127  * Unless required by applicable law or agreed to in writing, software
136128  * distributed under the License is distributed on an "AS IS" BASIS,
136129  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136130  * See the License for the specific language governing permissions and
136131  * limitations under the License.
136132  */
136133 var db = require('ripple/db'),
136134     select = require('ripple/platform/webworks.core/2.0.0/select'),
136135     _self;
136136
136137 function _get() {
136138     return db.retrieveObject("webworks-pim-appointment-list") || {};
136139 }
136140
136141 function _do(func) {
136142     var appointments = _get();
136143     func(appointments);
136144     db.saveObject("webworks-pim-appointment-list", appointments);
136145 }
136146
136147 _self = {
136148     find: function (get, post) {
136149         var appointments = _get(),
136150             data = select.from(appointments)
136151                     .orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc")
136152                     .max(post.maxReturn)
136153                     .where(post.filter);
136154
136155         return {code: 1, data: data};
136156     },
136157
136158     remove: function (get) {
136159         _do(function (appointments) {
136160             if (!appointments[get.uid]) {
136161                 throw "attempting to delete a non existant appointment with uid: " + get.uid;
136162             }
136163             delete appointments[get.uid];
136164         });
136165
136166         return {code: 1};
136167     },
136168
136169     save: function (get, post) {
136170         _do(function (appointments) {
136171             appointments[post.appointment.uid] = post.appointment;
136172         });
136173
136174         return {code: 1};
136175     }
136176 };
136177
136178 module.exports = _self;
136179
136180 });
136181 define('ripple/platform/webworks.handset/2.0.0/server/audioPlayer', function (require, exports, module) {
136182 /*
136183  *  Copyright 2011 Research In Motion Limited.
136184  *
136185  * Licensed under the Apache License, Version 2.0 (the "License");
136186  * you may not use this file except in compliance with the License.
136187  * You may obtain a copy of the License at
136188  *
136189  * http://www.apache.org/licenses/LICENSE-2.0
136190  *
136191  * Unless required by applicable law or agreed to in writing, software
136192  * distributed under the License is distributed on an "AS IS" BASIS,
136193  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136194  * See the License for the specific language governing permissions and
136195  * limitations under the License.
136196  */
136197 //create my dom collection node in UI
136198
136199 var utils = require('ripple/utils'),
136200     constants = require('ripple/constants'),
136201     notifications = require('ripple/notifications'),
136202     Player = require('ripple/platform/webworks.handset/2.0.0/client/AudioPlayer'),
136203     _handlers = {
136204         loadstart: {},
136205         canplaythrough: {},
136206         durationchange: {},
136207         ended: {},
136208         error: {},
136209         play: {},
136210         pause: {},
136211         volumechange: {},
136212         close: {}
136213     },
136214     extract = {
136215         time: function (audio) {
136216             return audio.currentTime;
136217         },
136218         duration: function (audio) {
136219             return audio.duration;
136220         },
136221         error: function (audio) {
136222             return audio.error;
136223         },
136224         nothing: function (audio) {
136225             return null;
136226         }
136227     },
136228     container;
136229
136230 container = utils.createElement("section", {
136231     id: "webworks-audio-players"
136232 });
136233
136234 document.getElementById("ui").appendChild(container);
136235
136236 function _errClosed(method) {
136237     notifications.openNotification("error",
136238        "attempted to call " + method + " on a player that is already closed. This is a very bad thing to do :)");
136239     return false;
136240 }
136241
136242 function _removeHandler(type, id) {
136243     var audio = document.getElementById(id);
136244
136245     if (audio && _handlers[type][id]) {
136246         audio.removeEventListener(type, _handlers[type][id]);
136247         delete _handlers[type][id];
136248     }
136249 }
136250
136251 function _addHandler(type, id, callback) {
136252     var audio = document.getElementById(id);
136253
136254     if (audio) {
136255         _removeHandler(type, id);
136256         audio.addEventListener(type, callback);
136257         _handlers[type][id] = callback;
136258     }
136259 }
136260
136261 function proxyEvent(from, map) {
136262     var audio = document.getElementById(map.id);
136263
136264     if (audio) {
136265         map.baton.take();
136266         _addHandler(from, map.id, function () {
136267             _removeHandler(from, map.id);
136268             map.baton.pass({code: 1, data: {
136269                 event: map.target,
136270                 eventData: map.data(this)
136271             }});
136272         });
136273     }
136274     else {
136275         return {code: -1, data: {event: "EVENT_ERROR", eventData: 5}};
136276     }
136277 }
136278
136279 module.exports = {
136280
136281     create: function (args) {
136282         var id = Math.uuid(),
136283             audio = utils.createElement("audio", {
136284                 id: id
136285             });
136286
136287         audio.setAttribute("src", args.locator);
136288
136289         if (args.type) {
136290             audio.setAttribute("type", args.type);
136291         }
136292
136293         container.appendChild(audio);
136294         audio.load();
136295
136296         if (audio.error) {
136297             throw "there was a problem opening the audio file";
136298         }
136299
136300         return {code: 1, data: id};
136301     },
136302
136303     play: function (args) {
136304         var audio = document.getElementById(args.id),
136305             playing;
136306
136307         if (audio) {
136308             audio.play();
136309             audio.rimState = Player.STARTED;
136310             playing = !!!audio.error;
136311         }
136312         else {
136313             playing = _errClosed("play");
136314         }
136315
136316         return {code: 1, data: playing};
136317     },
136318
136319     pause: function (args) {
136320         var audio = document.getElementById(args.id),
136321             paused;
136322
136323         if (audio) {
136324             audio.pause();
136325             paused = !!!audio.error;
136326         } else {
136327             paused = _errClosed("pause");
136328         }
136329
136330         return {code: 1, data: paused};
136331     },
136332
136333     close: function (args) {
136334         var audio = document.getElementById(args.id),
136335             callback = _handlers["close"][args.id],
136336             closed = true;
136337
136338         if (audio) {
136339             if (callback) {
136340                 callback();
136341             }
136342             container.removeChild(audio);
136343         }
136344         else {
136345             closed = _errClosed("close");
136346         }
136347
136348         return {code: 1, data: closed};
136349     },
136350
136351     onStart: function (args, post, baton) {
136352         return proxyEvent("play", {
136353             id: args.id,
136354             baton: baton,
136355             target: "EVENT_START",
136356             data: extract.time
136357         });
136358     },
136359
136360     onStopped: function (args, post, baton) {
136361         return proxyEvent("pause", {
136362             id: args.id,
136363             baton: baton,
136364             target: "EVENT_STOPPED",
136365             data: extract.time
136366         });
136367     },
136368
136369     onBufferingStarted: function (args, post, baton) {
136370         return proxyEvent("loadstart", {
136371             id: args.id,
136372             baton: baton,
136373             target: "EVENT_BUFFERING_STARTED",
136374             data: extract.time
136375         });
136376     },
136377
136378     onBufferingStopped: function (args, post, baton) {
136379         return proxyEvent("canplaythrough", {
136380             id: args.id,
136381             baton: baton,
136382             target: "EVENT_BUFFERING_STOPPED",
136383             data: extract.time
136384         });
136385     },
136386
136387     onDurationUpdated: function (args, post, baton) {
136388         return proxyEvent("durationchange", {
136389             id: args.id,
136390             baton: baton,
136391             target: "EVENT_DURATION_UPDATED",
136392             data: extract.duration
136393         });
136394     },
136395
136396     onEnd: function (args, post, baton) {
136397         return proxyEvent("ended", {
136398             id: args.id,
136399             baton: baton,
136400             target: "EVENT_END_OF_MEDIA",
136401             data: extract.duration
136402         });
136403     },
136404
136405     onError: function (args, post, baton) {
136406         return proxyEvent("error", {
136407             id: args.id,
136408             baton: baton,
136409             target: "EVENT_ERROR",
136410             data: extract.error
136411         });
136412     },
136413
136414     onVolumeChange: function (args, post, baton) {
136415         return proxyEvent("volumechange", {
136416             id: args.id,
136417             baton: baton,
136418             target: "EVENT_VOLUME_CHANGED",
136419             data: extract.nothing
136420         });
136421     },
136422
136423     onClose: function (args, post, baton) {
136424         return proxyEvent("close", {
136425             id: args.id,
136426             baton: baton,
136427             target: "EVENT_CLOSED",
136428             data: extract.nothing
136429         });
136430     },
136431
136432     getDuration: function (args) {
136433         var audio = document.getElementById(args.id),
136434             duration;
136435
136436         if (audio) {
136437             duration = audio.duration;
136438         }
136439         else {
136440             _errClosed("getDuration");
136441             duration = -1;
136442         }
136443
136444         return {code: 1, data: duration};
136445     },
136446
136447     getMediaTime: function (args) {
136448         var audio = document.getElementById(args.id),
136449             time;
136450
136451         if (audio) {
136452             time = audio.currentTime;
136453         }
136454         else {
136455             _errClosed("getMediaTime");
136456             time = -1;
136457         }
136458
136459         return {code: 1, data: time};
136460     },
136461
136462     setMediaTime: function (args) {
136463         var audio = document.getElementById(args.id);
136464
136465         if (audio) {
136466             audio.currentTime = args.value;
136467         }
136468         else {
136469             _errClosed("setMediaTime");
136470         }
136471
136472         return {code: 1};
136473     },
136474
136475     getVolumeLevel: function (args) {
136476         var audio = document.getElementById(args.id),
136477             level;
136478
136479         if (audio) {
136480             level = audio.volume * 100;
136481         }
136482         else {
136483             _errClosed("getVolumeLevel");
136484             level = -1;
136485         }
136486
136487         return {code: 1, data: level};
136488     },
136489
136490     setVolumeLevel: function (args) {
136491         var audio = document.getElementById(args.id);
136492
136493         if (audio) {
136494             audio.volume = args.value / 100;
136495         }
136496         else {
136497             _errClosed("setVolumeLevel");
136498         }
136499
136500         return {code: 1};
136501     },
136502
136503     getState: function (args) {
136504         var audio = document.getElementById(args.id),
136505             state = audio ? audio.rimState || Player.PREFETCHED : Player.CLOSED;
136506         return {code: 1, data: state};
136507     }
136508 };
136509
136510 });
136511 define('ripple/platform/webworks.handset/2.0.0/server/category', function (require, exports, module) {
136512 /*
136513  *  Copyright 2011 Research In Motion Limited.
136514  *
136515  * Licensed under the Apache License, Version 2.0 (the "License");
136516  * you may not use this file except in compliance with the License.
136517  * You may obtain a copy of the License at
136518  *
136519  * http://www.apache.org/licenses/LICENSE-2.0
136520  *
136521  * Unless required by applicable law or agreed to in writing, software
136522  * distributed under the License is distributed on an "AS IS" BASIS,
136523  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136524  * See the License for the specific language governing permissions and
136525  * limitations under the License.
136526  */
136527 var db = require('ripple/db'),
136528     _KEY = "blackberry-pim-category",
136529     _self;
136530
136531 function _get() {
136532     return db.retrieveObject(_KEY) || [];
136533 }
136534
136535 function _save(category) {
136536     var categories = _get();
136537     if (!categories.some(function (item) {
136538         return item === category;
136539     })) {
136540         categories.push(category);
136541         db.saveObject(_KEY, categories);
136542     }
136543 }
136544
136545 function _remove(category) {
136546     var categories = _get(),
136547         index = categories.indexOf(category);
136548
136549     if (index >= 0) {
136550         categories.splice(index, 1);
136551         db.saveObject(_KEY, categories);
136552     }
136553 }
136554
136555 _self = {
136556     addCategory: function (args) {
136557         _save(args.categoryName);
136558         return {code: 1};
136559     },
136560     deleteCategory: function (args) {
136561         _remove(args.categoryName);
136562         return {code: 1};
136563     },
136564     getCategories: function () {
136565         return {code: 1, data: _get()};
136566     }
136567 };
136568
136569 module.exports = _self;
136570
136571 });
136572 define('ripple/platform/webworks.handset/2.0.0/server/contact', function (require, exports, module) {
136573 /*
136574  *  Copyright 2011 Research In Motion Limited.
136575  *
136576  * Licensed under the Apache License, Version 2.0 (the "License");
136577  * you may not use this file except in compliance with the License.
136578  * You may obtain a copy of the License at
136579  *
136580  * http://www.apache.org/licenses/LICENSE-2.0
136581  *
136582  * Unless required by applicable law or agreed to in writing, software
136583  * distributed under the License is distributed on an "AS IS" BASIS,
136584  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136585  * See the License for the specific language governing permissions and
136586  * limitations under the License.
136587  */
136588 var select = require('ripple/platform/webworks.core/2.0.0/select'),
136589     db = require('ripple/db'),
136590     utils = require('ripple/utils'),
136591     _KEY = "blackberry-pim-contacts",
136592     _self;
136593
136594 function _defaultContacts() {
136595     var id1 = Math.uuid(null, 16),
136596         id2 = Math.uuid(null, 16),
136597         id3 = Math.uuid(null, 16),
136598         id4 = Math.uuid(null, 16),
136599         contacts = {};
136600
136601     contacts[id1] = {
136602         uuid: id1,
136603         firstName: "Leonardo",
136604         homePhone: "4567892345",
136605         email1: "leo@underground.com"
136606     };
136607     contacts[id2] = {
136608         uuid: id2,
136609         firstName: "Raphael",
136610         homePhone: "4563457890",
136611         email1: "raph@underground.com"
136612     };
136613     contacts[id3] = {
136614         uuid: id3,
136615         firstName: "Michelangelo",
136616         homePhone: "4563453425",
136617         email1: "mike@underground.com"
136618     };
136619     contacts[id4] = {
136620         uuid: id4,
136621         firstName: "Donatello",
136622         homePhone: "4563453425",
136623         email1: "don@undergound.com"
136624     };
136625
136626     return contacts;
136627 }
136628
136629 function _get() {
136630     return db.retrieveObject(_KEY) || _defaultContacts();
136631 }
136632
136633 function _save(contacts) {
136634     db.saveObject(_KEY, contacts);
136635 }
136636
136637 _self = {
136638     save: function (get, post) {
136639         var contacts = _get();
136640
136641         contacts[post.contact.uid] = post.contact;
136642         _save(contacts);
136643         return {code: 1};
136644     },
136645     remove: function (get, post) {
136646         var contacts = _get(),
136647             id = get.id;
136648
136649         delete contacts[id];
136650         _save(contacts);
136651         return {code: 1};
136652     },
136653     find: function (get, post) {
136654         var contacts = _get(),
136655             match = select.from(contacts);
136656
136657         if (post.orderBy) {
136658             match.orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc");
136659         }
136660
136661         if (post.maxReturn) {
136662             match.max(post.maxReturn);
136663         }
136664
136665         return {code: 1, data: match.where(post.fieldFilter)};
136666     }
136667 };
136668
136669 module.exports = _self;
136670
136671 });
136672 define('ripple/platform/webworks.handset/2.0.0/server/identity/phone', function (require, exports, module) {
136673 /*
136674  *  Copyright 2011 Research In Motion Limited.
136675  *
136676  * Licensed under the Apache License, Version 2.0 (the "License");
136677  * you may not use this file except in compliance with the License.
136678  * You may obtain a copy of the License at
136679  *
136680  * http://www.apache.org/licenses/LICENSE-2.0
136681  *
136682  * Unless required by applicable law or agreed to in writing, software
136683  * distributed under the License is distributed on an "AS IS" BASIS,
136684  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136685  * See the License for the specific language governing permissions and
136686  * limitations under the License.
136687  */
136688 var _lines = [
136689         {id: 1, number: 12345678910, label: "rogers", type: 1},
136690         {id: 2, number: 10987654321, label: "mystery", type: 0}
136691     ],
136692     _self;
136693
136694 function _filterLines(args) {
136695
136696     var result = _lines;
136697
136698     if (args && typeof args.id === "number") {
136699         result = _lines.filter(function (line) {
136700             return line.id === args.id;
136701         });
136702
136703         if (result.length === 0) {
136704             throw "invalid line id: " + args.id;
136705         }
136706     }
136707
136708     return result;
136709 }
136710
136711 _self = {
136712     getLineIds: function () {
136713         var lines = _lines.map(function (line) {
136714             return line.id;
136715         });
136716         return {
136717             code: 1,
136718             data: lines
136719         };
136720     },
136721     getLineLabel: function (args) {
136722         return {
136723             code: 1,
136724             data: _filterLines(args)[0].label
136725         };
136726     },
136727     getLineNumber: function (args) {
136728         return {
136729             code: 1,
136730             data: _filterLines(args)[0].number
136731         };
136732     },
136733     getLineType: function (args) {
136734         return {
136735             code: 1,
136736             data: _filterLines(args)[0].type
136737         };
136738     }
136739 };
136740
136741 module.exports = _self;
136742
136743 });
136744 define('ripple/platform/webworks.handset/2.0.0/server/identity', function (require, exports, module) {
136745 /*
136746  *  Copyright 2011 Research In Motion Limited.
136747  *
136748  * Licensed under the Apache License, Version 2.0 (the "License");
136749  * you may not use this file except in compliance with the License.
136750  * You may obtain a copy of the License at
136751  *
136752  * http://www.apache.org/licenses/LICENSE-2.0
136753  *
136754  * Unless required by applicable law or agreed to in writing, software
136755  * distributed under the License is distributed on an "AS IS" BASIS,
136756  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136757  * See the License for the specific language governing permissions and
136758  * limitations under the License.
136759  */
136760 var _self,
136761     Service = require('ripple/platform/webworks.handset/2.0.0/client/identity/Service'),
136762     Transport = require('ripple/platform/webworks.handset/2.0.0/client/identity/Transport'),
136763     utils = require('ripple/utils'),
136764     platform = require('ripple/platform'),
136765     deviceSettings = require('ripple/deviceSettings'),
136766     _transportTypes = [
136767         {name: "TCP Cellular", type: "TCP Cellular"},
136768         {name: "Wap", type: "Wap"},
136769         {name: "Wap 2.0", type: "Wap 2.0"},
136770         {name: "MDS", type: "MDS"},
136771         {name: "BIS B", type: "Bis B"},
136772         {name: "Unite!", type: "Unite!"},
136773         {name: "TCP Wifi", type: "TCP Wifi"},
136774     ],
136775     _services = [
136776         new Service(),
136777         new Service()
136778     ];
136779
136780 function _isTransportAvailable(transport) {
136781     return deviceSettings.retrieveAsBoolean("transports." + transport.type);
136782 }
136783
136784 utils.mixin({
136785     name: "Super Dave Osborne",
136786     emailAddress: "dave@stunt.com",
136787     isDefault: true,
136788     type: Service.TYPE_EMAIL
136789 }, _services[0]);
136790
136791 utils.mixin({
136792     name: "Fred Penner",
136793     emailAddress: "fred@fredpenner.com",
136794     isDefault: false,
136795     type: Service.TYPE_CONTACT
136796 }, _services[1]);
136797
136798 _self = {
136799     getDefaultService: function () {
136800         var serices = _services.filter(function (service) {
136801             return service.isDefault === true;
136802         });
136803         return {code: 1, data: serices};
136804     },
136805     getServiceList: function () {
136806         return {code: 1, data: _services};
136807     },
136808     getTransportList: function () {
136809         var transports = _transportTypes.filter(function (transport) {
136810             return _isTransportAvailable(transport);
136811         }).map(function (transport) {
136812             return new Transport(transport.name, transport.type);
136813         });
136814         return {code: 1, data: transports};
136815     },
136816     IMEI: function () {
136817         return {code: 1, data: deviceSettings.retrieve("identity.IMEI")};
136818     },
136819     IMSI: function () {
136820         return {code: 1, data: deviceSettings.retrieve("identity.IMSI")};
136821     },
136822     PIN: function () {
136823         return {code: 1, data: deviceSettings.retrieve("identity.PIN")};
136824     },
136825     phone: require('ripple/platform/webworks.handset/2.0.0/server/identity/phone')
136826 };
136827
136828 module.exports = _self;
136829
136830 });
136831 define('ripple/platform/webworks.handset/2.0.0/server/invoke', function (require, exports, module) {
136832 /*
136833  *  Copyright 2011 Research In Motion Limited.
136834  *
136835  * Licensed under the Apache License, Version 2.0 (the "License");
136836  * you may not use this file except in compliance with the License.
136837  * You may obtain a copy of the License at
136838  *
136839  * http://www.apache.org/licenses/LICENSE-2.0
136840  *
136841  * Unless required by applicable law or agreed to in writing, software
136842  * distributed under the License is distributed on an "AS IS" BASIS,
136843  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136844  * See the License for the specific language governing permissions and
136845  * limitations under the License.
136846  */
136847 var notifications = require('ripple/notifications'),
136848     constants = require('ripple/constants'),
136849     type = "normal",
136850     name = {
136851         "0": "Address Book",
136852         "1": "Bluetooth Config",
136853         "2": "Calculator",
136854         "3": "Calendar",
136855         "camera://": "Camera",
136856         "camera://video": "Video Camera",
136857         "map://": "Maps",
136858         "6": "Memopad",
136859         "7": "Messages",
136860         "8": "Phone",
136861         "9": "Search",
136862         "10": "Tasks",
136863         "11": "Browser",
136864         "http://": "Browser",
136865         "12": "Java",
136866     };
136867
136868 module.exports = {
136869     invoke: function (opts) {
136870         var app = name[opts.appType];
136871         if (app === undefined && opts.appType && opts.appType.match(/^http/i)) {
136872             app = "Browser";
136873         }
136874
136875         notifications.openNotification(type,
136876            "Requested to launch: " + app + " application.");
136877         return {code: 1};
136878     }
136879 };
136880
136881 });
136882 define('ripple/platform/webworks.handset/2.0.0/server/io/dir', function (require, exports, module) {
136883 /*
136884  * Copyright 2011 Research In Motion Limited.
136885  *
136886  * Licensed under the Apache License, Version 2.0 (the "License");
136887  * you may not use this file except in compliance with the License.
136888  * You may obtain a copy of the License at
136889  *
136890  *     http://www.apache.org/licenses/LICENSE-2.0
136891  *
136892  * Unless required by applicable law or agreed to in writing, software
136893  * distributed under the License is distributed on an "AS IS" BASIS,
136894  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136895  * See the License for the specific language governing permissions and
136896  * limitations under the License.
136897  */
136898 var cache = require('ripple/platform/webworks.core/2.0.0/fsCache'),
136899     dir = require('ripple/platform/webworks.core/2.0.0/server/io/dir'),
136900     utils = require('ripple/utils'),
136901     _self = {};
136902
136903 function _packet(data) {
136904     return {
136905         code: 1,
136906         data: data
136907     };
136908 }
136909
136910 utils.mixin({
136911     getFreeSpaceForRoot: function (get, post, baton) {
136912         return _packet(cache.dir.getFreeSpaceForRoot(post.path));
136913     },
136914     getRootDirs: function (get, post, baton) {
136915         return _packet(cache.dir.getRootDirs());
136916     }
136917 }, _self);
136918
136919 utils.mixin(dir, _self);
136920
136921 module.exports = _self;
136922
136923 });
136924 define('ripple/platform/webworks.handset/2.0.0/server/memo', function (require, exports, module) {
136925 /*
136926  *  Copyright 2011 Research In Motion Limited.
136927  *
136928  * Licensed under the Apache License, Version 2.0 (the "License");
136929  * you may not use this file except in compliance with the License.
136930  * You may obtain a copy of the License at
136931  *
136932  * http://www.apache.org/licenses/LICENSE-2.0
136933  *
136934  * Unless required by applicable law or agreed to in writing, software
136935  * distributed under the License is distributed on an "AS IS" BASIS,
136936  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136937  * See the License for the specific language governing permissions and
136938  * limitations under the License.
136939  */
136940 var db = require('ripple/db'),
136941     select = require('ripple/platform/webworks.core/2.0.0/select'),
136942     _self;
136943
136944 function _get() {
136945     return db.retrieveObject("webworks-pim-memo-list") || {};
136946 }
136947
136948 function _do(func) {
136949     var memos = _get();
136950     func(memos);
136951     db.saveObject("webworks-pim-memo-list", memos);
136952 }
136953
136954 _self = {
136955     find: function (get, post) {
136956         var memos = select.from(_get())
136957                     .orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc")
136958                     .max(post.maxReturn)
136959                     .where(post.filter);
136960         return {code: 1, data: memos};
136961     },
136962     remove: function (get, post) {
136963         _do(function (memos) {
136964             if (!memos[get.uid]) {
136965                 throw "attempting to delete a non existant memo with uid: " + get.uid;
136966             }
136967             delete memos[get.uid];
136968         });
136969         return {code: 1};
136970     },
136971     save: function (get, post) {
136972         _do(function (memos) {
136973             memos[post.memo.uid] = post.memo;
136974         });
136975         return {code: 1};
136976     }
136977 };
136978
136979 module.exports = _self;
136980
136981 });
136982 define('ripple/platform/webworks.handset/2.0.0/server/menu', function (require, exports, module) {
136983 /*
136984  *  Copyright 2011 Research In Motion Limited.
136985  *
136986  * Licensed under the Apache License, Version 2.0 (the "License");
136987  * you may not use this file except in compliance with the License.
136988  * You may obtain a copy of the License at
136989  *
136990  * http://www.apache.org/licenses/LICENSE-2.0
136991  *
136992  * Unless required by applicable law or agreed to in writing, software
136993  * distributed under the License is distributed on an "AS IS" BASIS,
136994  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136995  * See the License for the specific language governing permissions and
136996  * limitations under the License.
136997  */
136998 var _menuItems = {},
136999     event = require('ripple/event'),
137000     events = require('ripple/platform/webworks.core/2.0.0/client/events'),
137001     ui = require('ripple/ui'),
137002     devices = require('ripple/devices'),
137003     utils = require('ripple/utils'),
137004     tooltip = require('ripple/ui/plugins/tooltip'),
137005     _self,
137006     isMenuOpen = false,
137007     _baton,
137008     menuWindow = document ? document.getElementById("menu-window") : undefined;
137009
137010 if (menuWindow) {
137011     menuWindow.addEventListener("click", function () {
137012         _self.close();
137013     });
137014 }
137015
137016 event.on("LayoutChanged", function () {
137017     if (isMenuOpen) {
137018         _self.close();
137019         //Used to resize menu on orientation change
137020         _self.open();
137021     }
137022 });
137023
137024 event.on("HardwareKeyDefault", function (key) {
137025     if (key === 1 || key === "1") { //menu button key
137026         if (isMenuOpen) {
137027             _self.close();
137028         }
137029         else {
137030             _self.open();
137031         }
137032     }
137033 });
137034
137035 event.on("MenuItemSelected", function (menuItem) {
137036     var baton = _baton;
137037     _baton = null;
137038     return baton && baton.pass({code: 1, data: menuItem});
137039 });
137040
137041 event.on("MenuItemChanged", function (menuItem) {
137042     _menuItems[menuItem.id] = menuItem;
137043 });
137044
137045 _self = {
137046
137047     onSelect : function (args, post, baton) {
137048         baton.take();
137049         _baton = baton;
137050     },
137051
137052     addMenuItem: function (args) {
137053         if (!args) {
137054             throw "item not found";
137055         }
137056         _menuItems[args.item.id] = args.item;
137057         event.trigger("MenuChanged", [_menuItems]);
137058         return {code: 1};
137059     },
137060
137061     clearMenuItems: function () {
137062         _menuItems = {};
137063         event.trigger("MenuChanged", [utils.copy(_menuItems)]);
137064         return {code: 1};
137065     },
137066
137067     open: function () {
137068         function _return() {
137069             return {code: 1};
137070         }
137071
137072         if (utils.count(_menuItems) === 0) {
137073             _return();
137074         }
137075
137076         ui.showOverlay("menu-window", function (menu) {
137077             var container = document.getElementById("viewport-container"),
137078                 height = window.getComputedStyle(container, null).getPropertyValue("height"),
137079                 width = window.getComputedStyle(container, null).getPropertyValue("width"),
137080                 menuButtons = document.getElementById("menu-buttons"),
137081                 sorted,
137082                 menuItem;
137083
137084             if (!menuButtons) {
137085                 _return();
137086             }
137087
137088             menu.setAttribute("style", "display:block;height:" + height + "; width:" + width + ";");
137089             isMenuOpen = true;
137090
137091             sorted = utils.map(_menuItems, function (item) {
137092                 return item;
137093             }).sort(function (a, b) {
137094                 return a.ordinal - b.ordinal;
137095             });
137096
137097             menuButtons.innerHTML = "";
137098             sorted.forEach(function (item) {
137099                 if (!item.isSeparator) {
137100                     if (item.isDefault) {
137101                         menuItem = utils.createElement("div", {
137102                             "class": "overlay-menu-item-default",
137103                             "id": "default-menu-item"
137104                         });
137105                     }
137106                     else {
137107                         menuItem = utils.createElement("div", {
137108                             "class": "overlay-menu-item"
137109                         });
137110                     }
137111                     menuItem.innerHTML = item.caption;
137112
137113                     menuItem.addEventListener("click", function () {
137114                         _baton.pass({code: 1, data: item.id});
137115                     });
137116                 }
137117                 else {
137118                     menuItem = utils.createElement("hr", {});
137119                 }
137120                 menuButtons.appendChild(menuItem);
137121                 tooltip.create("#default-menu-item", "Default Item");
137122             });
137123         }, true);
137124
137125         event.trigger("MenuOpened", []);
137126
137127         _return();
137128     },
137129
137130     close: function () {
137131         ui.hideOverlay("menu-window", function (menu) {
137132             var menuButtons = document.getElementById("menu-buttons");
137133             menuButtons.innerHTML = "";
137134             isMenuOpen = false;
137135             menu.setAttribute("style", "display:none;");
137136
137137         });
137138         return {code: 1};
137139     },
137140
137141     removeMenuItem: function (args) {
137142         delete _menuItems[args.item.id];
137143         event.trigger("MenuChanged", [_menuItems]);
137144         return {code: 1};
137145     },
137146
137147     setDefaultMenuItem: function (args) {
137148
137149         utils.forEach(_menuItems, function (item) {
137150             item.isDefault = false;
137151         });
137152
137153         _menuItems[args.id].isDefault = true;
137154
137155         event.trigger("DefaultItemChanged", [_menuItems[args.id]]);
137156         return {code: 1};
137157     }
137158 };
137159
137160 module.exports = _self;
137161
137162 });
137163 define('ripple/platform/webworks.handset/2.0.0/server/message', function (require, exports, module) {
137164 /*
137165  *  Copyright 2011 Research In Motion Limited.
137166  *
137167  * Licensed under the Apache License, Version 2.0 (the "License");
137168  * you may not use this file except in compliance with the License.
137169  * You may obtain a copy of the License at
137170  *
137171  * http://www.apache.org/licenses/LICENSE-2.0
137172  *
137173  * Unless required by applicable law or agreed to in writing, software
137174  * distributed under the License is distributed on an "AS IS" BASIS,
137175  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137176  * See the License for the specific language governing permissions and
137177  * limitations under the License.
137178  */
137179 var db = require('ripple/db'),
137180     utils = require('ripple/utils'),
137181     select = require('ripple/platform/webworks.core/2.0.0/select'),
137182     Message = require('ripple/platform/webworks.handset/2.0.0/client/Message'),
137183     _self;
137184
137185 function _get() {
137186     return db.retrieveObject("webworks-message-list") || {};
137187 }
137188
137189 function _do(func) {
137190     var messages = _get();
137191     func(messages);
137192     db.saveObject("webworks-message-list", messages);
137193 }
137194
137195 _self = {
137196     find: function (get, post) {
137197         var data = select
137198                 .from(_get())
137199                 .max(post.maxReturn)
137200                 .where(post.filter);
137201         return {code: 1, data: data};
137202     },
137203
137204     remove: function (get, post) {
137205         _do(function (messages) {
137206             if (!messages[get.uid]) {
137207                 throw "attempting to delete a non existant message with uid: " + get.uid;
137208             }
137209             delete messages[get.uid];
137210         });
137211         return {code: 1};
137212     },
137213
137214     save: function (get, post) {
137215         _do(function (messages) {
137216             var orig = messages[post.message.uid],
137217                 updated = utils.copy(post.message);
137218
137219             updated.folder = orig ? orig.folder : Message.FOLDER_DRAFT;
137220             updated.status = orig ? orig.status : Message.STATUS_DRAFT;
137221
137222             messages[post.message.uid] = updated;
137223         });
137224         return {code: 1};
137225     },
137226
137227     send: function (get, post) {
137228         _do(function (messages) {
137229             var updated = utils.copy(get.message);
137230
137231             updated.folder = Message.FOLDER_SENT;
137232             updated.status = Message.STATUS_SENT;
137233
137234             messages[updated.uid] = updated;
137235         });
137236         return {code: 1};
137237     }
137238 };
137239
137240 module.exports = _self;
137241
137242 });
137243 define('ripple/platform/webworks.handset/2.0.0/server/phone', function (require, exports, module) {
137244 /*
137245  *  Copyright 2011 Research In Motion Limited.
137246  *
137247  * Licensed under the Apache License, Version 2.0 (the "License");
137248  * you may not use this file except in compliance with the License.
137249  * You may obtain a copy of the License at
137250  *
137251  * http://www.apache.org/licenses/LICENSE-2.0
137252  *
137253  * Unless required by applicable law or agreed to in writing, software
137254  * distributed under the License is distributed on an "AS IS" BASIS,
137255  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137256  * See the License for the specific language governing permissions and
137257  * limitations under the License.
137258  */
137259 var PhoneCall = require('ripple/platform/webworks.handset/2.0.0/client/PhoneCall'),
137260     PhoneLogs = require('ripple/platform/webworks.handset/2.0.0/client/PhoneLogs'),
137261     CallLog = require('ripple/platform/webworks.handset/2.0.0/client/CallLog'),
137262     select = require('ripple/platform/webworks.core/2.0.0/select'),
137263     event = require('ripple/event'),
137264     utils = require('ripple/utils'),
137265     db = require('ripple/db'),
137266     _KEY = "blackberry-phone-logs",
137267     _onPhoneEventListeners = {},
137268     _activeCalls = {},
137269     _onCallLogAdded,
137270     _onCallLogRemoved,
137271     _onCallLogUpdated,
137272     _onCallLogReset,
137273     _self;
137274
137275 function _defaultLogs() {
137276     var n1 = new CallLog(),
137277         n2 = new CallLog(),
137278         m1 = new CallLog(),
137279         m2 = new CallLog();
137280
137281     n1.number = "12344567";
137282     n1.name = "larry";
137283     n1.type = CallLog.TYPE_PLACED_CALL;
137284     n1.status = CallLog.STATUS_NORMAL;
137285
137286     n2.number = "14567890";
137287     n2.name = "curly";
137288     n2.type = CallLog.TYPE_RECEIVED_CALL;
137289     n2.status = CallLog.STATUS_NORMAL;
137290
137291     m1.number = "17659800";
137292     m1.name = "moe";
137293     m1.type = CallLog.TYPE_MISSED_CALL_UNOPENED;
137294     m1.status = CallLog.STATUS_NORMAL;
137295
137296     m2.number = "14567896";
137297     m2.name = "snarf";
137298     m2.type = CallLog.TYPE_MISSED_CALL_OPENED;
137299     m2.status = CallLog.STATUS_NORMAL;
137300
137301     return {
137302         normal: [n1, n2],
137303         missed: [m1, m2]
137304     };
137305 }
137306
137307 function _getLogs(folderID) {
137308     var logs = db.retrieveObject(_KEY) || _defaultLogs();
137309     return folderID === undefined || folderID === null ?
137310         logs : logs[folderID !== PhoneLogs.FOLDER_NORMAL_CALLS ? "missed" : "normal"];
137311 }
137312
137313 function _saveLogs(logs) {
137314     db.saveObject(_KEY, logs);
137315 }
137316
137317 function _isMissedCall(log) {
137318     return (log.type === CallLog.TYPE_MISSED_CALL_UNOPENED ||
137319             log.type === CallLog.TYPE_MISSED_CALL_OPENED) ? true : false;
137320 }
137321
137322 function _isNormalCall(log) {
137323     return (log.type === CallLog.TYPE_RECEIVED_CALL ||
137324             log.type === CallLog.TYPE_PLACED_CALL) ? true : false;
137325 }
137326
137327 event.on("PhoneEvent", function (type, callId, error) {
137328     var baton = _onPhoneEventListeners[type];
137329     delete _onPhoneEventListeners[type];
137330
137331     return baton && baton.pass({code: 1, data: {callId: callId, error: error}});
137332 });
137333
137334 event.on("PhoneCallLogAdded", function (log) {
137335     var logs = _getLogs(),
137336         baton = _onCallLogAdded;
137337
137338     logs[_isMissedCall(log) ? "missed" : "normal"].push(log);
137339     _saveLogs(logs);
137340
137341     _onCallLogAdded = null;
137342     return baton && baton.pass({code: 1, data: {log: log}});
137343 });
137344
137345 event.on("PhoneCallLogRemoved", function (log) {
137346     // TODO: make this be the only one responsible for deletion (instead of triggering internally)
137347     var baton = _onCallLogRemoved;
137348     _onCallLogRemoved = null;
137349     return baton && baton.pass({code: 1, data: {log: log}});
137350 });
137351
137352 event.on("PhoneCallLogUpdated", function (newLog, oldLog) {
137353     // TODO: implement way to update with just this event
137354     var baton = _onCallLogUpdated;
137355     _onCallLogUpdated = null;
137356     return baton && baton.pass({code: 1, data: {
137357         newLog: newLog,
137358         oldLog: oldLog
137359     }});
137360 });
137361
137362 event.on("PhoneCallLogReset", function () {
137363     _saveLogs(_defaultLogs());
137364     var baton = _onCallLogReset;
137365     _onCallLogReset = null;
137366     return baton && baton.pass({code: 1});
137367 });
137368
137369 event.on("PhoneCallInitiated", function (call) {
137370     _activeCalls[call.id] = call;
137371 });
137372
137373 event.on("PhoneCallEnded", function (call) {
137374     delete _activeCalls[call.id];
137375 });
137376
137377 _self = {
137378     logs: {
137379         onCallLogAdded: function (get, post, baton) {
137380             baton.take();
137381             _onCallLogAdded = baton;
137382         },
137383
137384         onCallLogRemoved: function (get, post, baton) {
137385             baton.take();
137386             _onCallLogRemoved = baton;
137387         },
137388
137389         onCallLogUpdated: function (get, post, baton) {
137390             baton.take();
137391             _onCallLogUpdated = baton;
137392         },
137393
137394         onCallLogReset: function (get, post, baton) {
137395             baton.take();
137396             _onCallLogReset = baton;
137397         },
137398
137399         callAt: function (get) {
137400             var logs = _getLogs(get.folderID !== null && get.folderID !== undefined ?
137401                                         get.folderID : PhoneLogs.FOLDER_MISSED_CALLS);
137402             return {code: 1, data: logs.length > get.index ? logs[get.index] : null};
137403         },
137404
137405         deleteCallAt: function (get) {
137406             var logs = _getLogs(),
137407                 subLog = _getLogs(get.folderID),
137408                 deleted = false,
137409                 type, log;
137410
137411             if (subLog.length > get.index &&
137412                (type = _isNormalCall(subLog[get.index]) ? "normal" : "missed") &&
137413                (log = logs[type].splice(get.index, 1))) {
137414                 event.trigger("PhoneCallLogRemoved", [log]);
137415                 _saveLogs(logs);
137416                 deleted = true;
137417             }
137418
137419             return {code: 1, data: deleted};
137420         },
137421
137422         find: function (get, post) {
137423             var data = select.from(_getLogs(post.folderID !== null && post.folderID !== undefined ?
137424                                         post.folderID : PhoneLogs.FOLDER_MISSED_CALLS))
137425                     .orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc")
137426                     .max(post.maxReturn)
137427                     .where(post.filter, select.ops.phone);
137428             return {code: 1, data: data};
137429         },
137430
137431         numberOfCalls: function (get) {
137432             return {code: 1, data: _getLogs(get.folderID !== null && get.folderID !== undefined ?
137433                                         get.folderID : PhoneLogs.FOLDER_MISSED_CALLS).length};
137434         }
137435     },
137436
137437     onPhoneEvent: function (get, post, baton) {
137438         baton.take();
137439         _onPhoneEventListeners[get.eventType] = baton;
137440     },
137441
137442     activeCalls: function () {
137443         var data = utils.map(_activeCalls, function (callItem) {
137444             var call = new PhoneCall(callItem.onhold);
137445             call.outgoing = callItem.outgoing;
137446             call.recipientName = callItem.recipient.name;
137447             call.recipientNumber = callItem.recipient.number;
137448             return call;
137449         });
137450         return {code: 1, data: data};
137451     },
137452
137453     inActiveCall: function () {
137454         return {code: 1, data: utils.count(_activeCalls) > 0 ? true : false};
137455     }
137456 };
137457
137458 module.exports = _self;
137459
137460 });
137461 define('ripple/platform/webworks.handset/2.0.0/server/push', function (require, exports, module) {
137462 /*
137463  *  Copyright 2011 Research In Motion Limited.
137464  *
137465  * Licensed under the Apache License, Version 2.0 (the "License");
137466  * you may not use this file except in compliance with the License.
137467  * You may obtain a copy of the License at
137468  *
137469  * http://www.apache.org/licenses/LICENSE-2.0
137470  *
137471  * Unless required by applicable law or agreed to in writing, software
137472  * distributed under the License is distributed on an "AS IS" BASIS,
137473  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137474  * See the License for the specific language governing permissions and
137475  * limitations under the License.
137476  */
137477 var event = require('ripple/event'),
137478     utils = require('ripple/utils'),
137479     _handlers = {},
137480     _self;
137481
137482 function listenersChanged() {
137483     var ports = utils.map(_handlers, function (handler) {
137484         return handler.port;
137485     });
137486     event.trigger("PushListenersChanged", [ports]);
137487 }
137488
137489 event.on("Push", function (data, port) {
137490     var handler = _handlers["port_" + port];
137491     delete _handlers["port_" + port];
137492     window.setTimeout(function () {
137493         if (!_handlers["port_" + port]) {
137494             //doesn't look like they are coming back ;)
137495             listenersChanged();
137496         }
137497     }, 100);
137498     return handler && handler.baton.pass({code: 1, data: data});
137499 });
137500
137501 _self = {
137502
137503     onPush: function (args, post, baton) {
137504         if (!args.port) {
137505             throw "no port specified";
137506         }
137507         else if (typeof args.port !== 'number') {
137508             throw "port is not a number";
137509         }
137510         baton.take();
137511         _handlers["port_" + args.port] = {
137512             port: args.port,
137513             baton: baton
137514         };
137515         listenersChanged();
137516     }
137517 };
137518
137519 module.exports = _self;
137520
137521 });
137522 define('ripple/platform/webworks.handset/2.0.0/server/sms', function (require, exports, module) {
137523 /*
137524  *  Copyright 2011 Research In Motion Limited.
137525  *
137526  * Licensed under the Apache License, Version 2.0 (the "License");
137527  * you may not use this file except in compliance with the License.
137528  * You may obtain a copy of the License at
137529  *
137530  * http://www.apache.org/licenses/LICENSE-2.0
137531  *
137532  * Unless required by applicable law or agreed to in writing, software
137533  * distributed under the License is distributed on an "AS IS" BASIS,
137534  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137535  * See the License for the specific language governing permissions and
137536  * limitations under the License.
137537  */
137538 var _listener,
137539     _isListening = false,
137540     notifications = require('ripple/notifications'),
137541     constants = require('ripple/constants'),
137542     event = require('ripple/event'),
137543     _console = require('ripple/console'),
137544     _onReceive,
137545     _self;
137546
137547 event.on("MessageReceived", function (message) {
137548     if (!_isListening || message.type !== 'sms') {
137549         return;
137550     }
137551
137552     var baton = _onReceive;
137553     _onReceive = null;
137554     _isListening = false;
137555     return baton && baton.pass({code: 1, data: message});
137556 });
137557
137558 _self = {
137559     onReceive: function (args, post, baton) {
137560         baton.take();
137561         _onReceive = baton;
137562         _isListening = !!_onReceive;
137563     },
137564
137565     send: function (args) {
137566         var msg = "To " + args.address + ": " + args.message;
137567         notifications.openNotification("normal", msg);
137568         _console.log(msg);
137569         return {code: 1};
137570     },
137571
137572     isListeningForMessage: function (get, post, baton) {
137573         if (get && typeof get.isListeningForMessage === "boolean") {
137574             _isListening = get.isListeningForMessage;
137575         }
137576
137577         return {code: 1, data: _isListening};
137578     }
137579 };
137580
137581 module.exports = _self;
137582
137583 });
137584 define('ripple/platform/webworks.handset/2.0.0/server/systemEvent', function (require, exports, module) {
137585 /*
137586  *  Copyright 2011 Research In Motion Limited.
137587  *
137588  * Licensed under the Apache License, Version 2.0 (the "License");
137589  * you may not use this file except in compliance with the License.
137590  * You may obtain a copy of the License at
137591  *
137592  * http://www.apache.org/licenses/LICENSE-2.0
137593  *
137594  * Unless required by applicable law or agreed to in writing, software
137595  * distributed under the License is distributed on an "AS IS" BASIS,
137596  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137597  * See the License for the specific language governing permissions and
137598  * limitations under the License.
137599  */
137600 var event = require('ripple/event'),
137601     _onCoverageChange,
137602     _onHardwareKey = {};
137603
137604 event.on("CoverageChange", function () {
137605     var baton = _onCoverageChange;
137606     _onCoverageChange = null;
137607     return baton && baton.pass({code: 1});
137608 });
137609
137610 event.on("HardwareKey", function (key) {
137611     var baton = _onHardwareKey["key_" + key];
137612     delete _onHardwareKey["key_" + key];
137613
137614     if (baton) {
137615         baton.pass({code: 1});
137616     }
137617     else {
137618         event.trigger("HardwareKeyDefault", [key]);
137619     }
137620 });
137621
137622 module.exports = {
137623     onCoverageChange: function (args, post, baton) {
137624         baton.take();
137625         _onCoverageChange = baton;
137626     },
137627
137628     onHardwareKey: function (args, post, baton) {
137629         baton.take();
137630         _onHardwareKey["key_" + args.key] = baton;
137631     }
137632 };
137633
137634 });
137635 define('ripple/platform/webworks.handset/2.0.0/server', function (require, exports, module) {
137636 /*
137637  *  Copyright 2011 Research In Motion Limited.
137638  *
137639  * Licensed under the Apache License, Version 2.0 (the "License");
137640  * you may not use this file except in compliance with the License.
137641  * You may obtain a copy of the License at
137642  *
137643  * http://www.apache.org/licenses/LICENSE-2.0
137644  *
137645  * Unless required by applicable law or agreed to in writing, software
137646  * distributed under the License is distributed on an "AS IS" BASIS,
137647  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137648  * See the License for the specific language governing permissions and
137649  * limitations under the License.
137650  */
137651 var utils = require('ripple/utils'),
137652     platform = "ripple/platform/webworks.handset/2.0.0/server/",
137653     core = "ripple/platform/webworks.core/2.0.0/server/",
137654     systemEvent = require(platform + 'systemEvent'),
137655     system = {};
137656
137657 // ugh, thanks to the spec...
137658 system.event = systemEvent;
137659 utils.mixin(require(core + "system"), system);
137660
137661 module.exports = {
137662     blackberry: {
137663         invoke: require(platform + "invoke"),
137664         system: system,
137665         app: require(platform + "app"),
137666         identity: require(platform + "identity"),
137667         message: {
137668             sms: require(platform + "sms"),
137669             message: require(platform + "message")
137670         },
137671         push: require(platform + "push"),
137672         pim: {
137673             Task: require(platform + "Task"),
137674             category: require(platform + "category"),
137675             memo: require(platform + "memo"),
137676             appointment: require(platform + "appointment"),
137677             contact: require(platform + "contact")
137678         },
137679         audio: {
137680             player: require(platform + "audioPlayer")
137681         },
137682         ui: {
137683             menu: require(platform + "menu"),
137684             dialog: require(core + "dialog")
137685         },
137686         phone: require(platform + "phone"),
137687         io: {
137688             dir: require(platform + "io/dir"),
137689             file: require(core + "io/file")
137690         }
137691     }
137692 };
137693
137694 });
137695 define('ripple/platform/webworks.handset/2.0.0/spec/device', function (require, exports, module) {
137696 /*
137697  *  Copyright 2011 Research In Motion Limited.
137698  *
137699  * Licensed under the Apache License, Version 2.0 (the "License");
137700  * you may not use this file except in compliance with the License.
137701  * You may obtain a copy of the License at
137702  *
137703  * http://www.apache.org/licenses/LICENSE-2.0
137704  *
137705  * Unless required by applicable law or agreed to in writing, software
137706  * distributed under the License is distributed on an "AS IS" BASIS,
137707  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137708  * See the License for the specific language governing permissions and
137709  * limitations under the License.
137710  */
137711 var event = require('ripple/event');
137712
137713 module.exports = {
137714     "transports": {
137715         "TCP Cellular": {
137716             "name": "Cellular TCP",
137717             "control": {
137718                 "type": "checkbox",
137719                 "value": true
137720             }
137721         },
137722         "Wap": {
137723             "name": "WAP",
137724             "control": {
137725                 "type": "checkbox",
137726                 "value": false
137727             }
137728         },
137729         "Wap 2.0": {
137730             "name": "WAP 2.0",
137731             "control": {
137732                 "type": "checkbox",
137733                 "value": false
137734             }
137735         },
137736         "MDS": {
137737             "name": "MDS",
137738             "control": {
137739                 "type": "checkbox",
137740                 "value": true
137741             }
137742         },
137743         "Bis B": {
137744             "name": "BIS B",
137745             "control": {
137746                 "type": "checkbox",
137747                 "value": true
137748             }
137749         },
137750         "Unite!": {
137751             "name": "Unite",
137752             "control": {
137753                 "type": "checkbox",
137754                 "value": false
137755             }
137756         },
137757         "TCP Wifi": {
137758             "name": "Wifi TCP",
137759             "control": {
137760                 "type": "checkbox",
137761                 "value": true
137762             }
137763         }
137764     },
137765     "identity": {
137766         "IMEI": {
137767             "name": "IMEI",
137768             "control": {
137769                 "type": "text",
137770                 "value": "123456786543210"
137771             }
137772         },
137773         "IMSI": {
137774             "name": "IMSI",
137775             "control": {
137776                 "type": "text",
137777                 "value": "310150123456789"
137778             }
137779         },
137780         "PIN": {
137781             "name": "PIN",
137782             "control": {
137783                 "type": "text",
137784                 "value": "43A8C489"
137785             }
137786         }
137787     },
137788     "system": {
137789         "isMassStorageActive": {
137790             "name": "Mass Storage Is Connected",
137791             "control": {
137792                 "type": "checkbox",
137793                 "value": true
137794             }
137795         },
137796         "hasDataCoverage": {
137797             "name": "Has Data Coverage",
137798             "control": {
137799                 "type": "checkbox",
137800                 "value": true
137801             },
137802             "callback": function (setting) {
137803                 event.trigger("CoverageChange");
137804                 require('ripple/bus').send("network", setting);
137805             }
137806         },
137807         "lag": {
137808             "name": "Lag the network",
137809             "control": {
137810                 type: "checkbox",
137811                 value: false
137812             },
137813             "callback": function (setting) {
137814                 require('ripple/bus').send("lag", setting);
137815             }
137816         },
137817         "network": {
137818             "name": "Data Network",
137819             "control": {
137820                 "type": "select",
137821                 "value": "3GPP"
137822             },
137823             "options": {
137824                 "3GPP" : "3GPP",
137825                 "CDMA": "CDMA",
137826                 "iDEN": "iDEN",
137827                 "Wi-Fi": "Wi-Fi"
137828             },
137829             "callback": function (setting) {
137830                 event.trigger("CoverageChange");
137831             }
137832         }
137833     }
137834 };
137835
137836 });
137837 define('ripple/platform/webworks.handset/2.0.0/spec/events', function (require, exports, module) {
137838 /*
137839  *  Copyright 2011 Research In Motion Limited.
137840  *
137841  * Licensed under the Apache License, Version 2.0 (the "License");
137842  * you may not use this file except in compliance with the License.
137843  * You may obtain a copy of the License at
137844  *
137845  * http://www.apache.org/licenses/LICENSE-2.0
137846  *
137847  * Unless required by applicable law or agreed to in writing, software
137848  * distributed under the License is distributed on an "AS IS" BASIS,
137849  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137850  * See the License for the specific language governing permissions and
137851  * limitations under the License.
137852  */
137853 var _self,
137854     utils = require('ripple/utils'),
137855     event = require('ripple/event'),
137856     events = require('ripple/platform/webworks.core/2.0.0/spec/events');
137857
137858 _self = {
137859     "system.event.onExit": {
137860         callback: function () {
137861             event.trigger("AppExit");
137862         }
137863     },
137864     "system.event.onCoverageChange": {
137865         callback: function () {
137866             event.trigger("CoverageChange");
137867         }
137868     },
137869     "system.event.onHardwareKey": {
137870         args: [
137871             "Back",
137872             "Menu",
137873             "Convenience 1",
137874             "Convenience 2",
137875             "Start Call",
137876             "End Call",
137877             "Volume Down",
137878             "Volume Up"
137879         ],
137880         callback: function (key) {
137881             event.trigger("HardwareKey", [key]);
137882         }
137883     }
137884 };
137885
137886 utils.mixin(events, _self);
137887
137888 module.exports = _self;
137889
137890 });
137891 define('ripple/platform/webworks.handset/2.0.0/spec/ui', function (require, exports, module) {
137892 /*
137893  *  Copyright 2011 Research In Motion Limited.
137894  *
137895  * Licensed under the Apache License, Version 2.0 (the "License");
137896  * you may not use this file except in compliance with the License.
137897  * You may obtain a copy of the License at
137898  *
137899  * http://www.apache.org/licenses/LICENSE-2.0
137900  *
137901  * Unless required by applicable law or agreed to in writing, software
137902  * distributed under the License is distributed on an "AS IS" BASIS,
137903  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137904  * See the License for the specific language governing permissions and
137905  * limitations under the License.
137906  */
137907 module.exports = {
137908     plugins: [
137909         "accelerometer",
137910         "deviceSettings",
137911         "geoView",
137912         "platformEvents",
137913         "widgetConfig",
137914         "messaging",
137915         "push",
137916         "phone",
137917         "build"
137918     ]
137919 };
137920
137921 });
137922 define('ripple/platform/webworks.handset/2.0.0/spec', function (require, exports, module) {
137923 /*
137924  *  Copyright 2011 Research In Motion Limited.
137925  *
137926  * Licensed under the Apache License, Version 2.0 (the "License");
137927  * you may not use this file except in compliance with the License.
137928  * You may obtain a copy of the License at
137929  *
137930  * http://www.apache.org/licenses/LICENSE-2.0
137931  *
137932  * Unless required by applicable law or agreed to in writing, software
137933  * distributed under the License is distributed on an "AS IS" BASIS,
137934  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137935  * See the License for the specific language governing permissions and
137936  * limitations under the License.
137937  */
137938 module.exports = {
137939
137940     id: "webworks.handset",
137941     version: "2.0.0",
137942     name: "WebWorks",
137943
137944     persistencePrefix: "rim-handset-",
137945
137946     ui: require('ripple/platform/webworks.handset/2.0.0/spec/ui'),
137947     device: require('ripple/platform/webworks.handset/2.0.0/spec/device'),
137948     config: require('ripple/platform/webworks.core/2.0.0/spec/config'),
137949     events: require('ripple/platform/webworks.handset/2.0.0/spec/events'),
137950
137951     initialize: function () {},
137952
137953     objects: {
137954         XMLHttpRequest: {
137955             path: "webworks.handset/2.0.0/XMLHttpRequest"
137956         },
137957         Coordinates: {
137958             path: "w3c/1.0/Coordinates"
137959         },
137960         Position: {
137961             path: "w3c/1.0/Position"
137962         },
137963         PositionError: {
137964             path: "w3c/1.0/PositionError"
137965         },
137966         navigator: {
137967             path: "w3c/1.0/navigator",
137968             children: {
137969                 geolocation: {
137970                     path: "w3c/1.0/geolocation"
137971                 }
137972             }
137973         },
137974         blackberry: {
137975             path: "webworks.handset/2.0.0/client/blackberry",
137976             children: {
137977                 pim: {
137978                     path: "webworks.handset/2.0.0/client/pim",
137979                     feature: "blackberry.pim.category|blackberry.pim.Task|blackberry.pim.Recurrence|blackberry.pim.Reminder|blackberry.pim.Appointment|blackberry.pim.Address|blackberry.pim.Attendee|blackberry.pim.Memo|blackberry.pim.Contact",
137980                     children: {
137981                         category: {
137982                             path: "webworks.handset/2.0.0/client/category",
137983                             feature: "blackberry.pim.category"
137984                         },
137985                         Task: {
137986                             path: "webworks.handset/2.0.0/client/Task",
137987                             feature: "blackberry.pim.Task"
137988                         },
137989                         Recurrence: {
137990                             path: "webworks.handset/2.0.0/client/Recurrence",
137991                             feature: "blackberry.pim.Recurrence"
137992                         },
137993                         Reminder: {
137994                             path: "webworks.handset/2.0.0/client/Reminder",
137995                             feature: "blackberry.pim.Reminder"
137996                         },
137997                         Appointment: {
137998                             path: "webworks.handset/2.0.0/client/Appointment",
137999                             feature: "blackberry.pim.Appointment"
138000                         },
138001                         Address: {
138002                             path: "webworks.handset/2.0.0/client/Address",
138003                             feature: "blackberry.pim.Address"
138004                         },
138005                         Attendee: {
138006                             path: "webworks.handset/2.0.0/client/Attendee",
138007                             feature: "blackberry.pim.Attendee"
138008                         },
138009                         Memo: {
138010                             path: "webworks.handset/2.0.0/client/Memo",
138011                             feature: "blackberry.pim.Memo"
138012                         },
138013                         Contact: {
138014                             path: "webworks.handset/2.0.0/client/Contact",
138015                             feature: "blackberry.pim.Contact"
138016                         }
138017                     }
138018                 },
138019                 phone: {
138020                     children: {
138021                         Phone: {
138022                             path: "webworks.handset/2.0.0/client/Phone",
138023                             feature: "blackberry.phone.Phone"
138024                         },
138025                         PhoneLogs: {
138026                             path: "webworks.handset/2.0.0/client/PhoneLogs",
138027                             feature: "blackberry.phone.PhoneLogs|blackberry.phone.Find",
138028                             children: {
138029                                 CallLog: {
138030                                     path: "webworks.handset/2.0.0/client/CallLog"
138031                                 }
138032                             }
138033                         },
138034                         Find: {
138035                             children: {
138036                                 FilterExpression: {
138037                                     path: "webworks.handset/2.0.0/client/FilterExpression",
138038                                     feature: "blackberry.phone.Find"
138039                                 }
138040                             }
138041                         }
138042                     }
138043                 },
138044                 message: {
138045                     path: "webworks.handset/2.0.0/client/messaging",
138046                     feature: "blackberry.message.sms|blackberry.message",
138047                     children: {
138048                         sms: {
138049                             path: "webworks.handset/2.0.0/client/sms",
138050                             feature: "blackberry.message.sms"
138051                         },
138052                         Message: {
138053                             path: "webworks.handset/2.0.0/client/Message",
138054                             feature: "blackberry.message"
138055                         }
138056                     }
138057                 },
138058                 transport: {
138059                     path: "webworks.core/2.0.0/client/transport"
138060                 },
138061                 events: {
138062                     path: "webworks.core/2.0.0/client/events"
138063                 },
138064                 app: {
138065                     path: "webworks.handset/2.0.0/client/app",
138066                     feature: "blackberry.app",
138067                     children: {
138068                         event: {
138069                             path: "webworks.handset/2.0.0/client/appEvent",
138070                             feature: "blackberry.app.event"
138071                         }
138072                     }
138073                 },
138074                 invoke: {
138075                     path: "webworks.handset/2.0.0/client/invoke",
138076                     feature: "blackberry.invoke",
138077                     children: {
138078                         AddressBookArguments: {
138079                             path: "webworks.handset/2.0.0/client/AddressBookArguments",
138080                             feature: "blackberry.invoke.AddressBookArguments"
138081                         },
138082                         BrowserArguments: {
138083                             path: "webworks.handset/2.0.0/client/BrowserArguments",
138084                             feature: "blackberry.invoke.BrowserArguments"
138085                         },
138086                         CameraArguments: {
138087                             path: "webworks.handset/2.0.0/client/CameraArguments",
138088                             feature: "blackberry.invoke.CameraArguments"
138089                         },
138090                         CalendarArguments: {
138091                             path: "webworks.handset/2.0.0/client/CalendarArguments",
138092                             feature: "blackberry.invoke.CalendarArguments"
138093                         },
138094                         JavaArguments: {
138095                             path: "webworks.handset/2.0.0/client/JavaArguments",
138096                             feature: "blackberry.invoke.JavaArguments"
138097                         },
138098                         MapsArguments: {
138099                             path: "webworks.handset/2.0.0/client/MapsArguments",
138100                             feature: "blackberry.invoke.MapsArguments"
138101                         },
138102                         MemoArguments: {
138103                             path: "webworks.handset/2.0.0/client/MemoArguments",
138104                             feature: "blackberry.invoke.MemoArguments"
138105                         },
138106                         MessageArguments: {
138107                             path: "webworks.handset/2.0.0/client/MessageArguments",
138108                             feature: "blackberry.invoke.MessageArguments"
138109                         },
138110                         PhoneArguments: {
138111                             path: "webworks.handset/2.0.0/client/PhoneArguments",
138112                             feature: "blackberry.invoke.PhoneArguments"
138113                         },
138114                         SearchArguments: {
138115                             path: "webworks.handset/2.0.0/client/SearchArguments",
138116                             feature: "blackberry.invoke.SearchArguments"
138117                         },
138118                         TaskArguments: {
138119                             path: "webworks.handset/2.0.0/client/TaskArguments",
138120                             feature: "blackberry.invoke.TaskArguments"
138121                         }
138122                     }
138123                 },
138124                 identity: {
138125                     path: "webworks.handset/2.0.0/client/identity",
138126                     feature: "blackberry.identity",
138127                     children: {
138128                         Transport: {
138129                             path: "webworks.handset/2.0.0/client/identity/Transport",
138130                             feature: "blackberry.identity"
138131                         },
138132                         Service: {
138133                             path: "webworks.handset/2.0.0/client/identity/Service",
138134                             feature: "blackberry.identity"
138135                         },
138136                         phone: {
138137                             path: "webworks.handset/2.0.0/client/identity/phone",
138138                             feature: "blackberry.identity.phone"
138139                         }
138140                     }
138141                 },
138142                 system: {
138143                     path: "webworks.handset/2.0.0/client/system",
138144                     feature: "blackberry.system",
138145                     children: {
138146                         event: {
138147                             path: "webworks.handset/2.0.0/client/systemEvent",
138148                             feature: "blackberry.system.event"
138149                         }
138150                     }
138151                 },
138152                 ui: {
138153                     children: {
138154                         dialog: {
138155                             path: "webworks.core/2.0.0/client/dialog",
138156                             feature: "blackberry.ui.dialog"
138157                         },
138158                         menu: {
138159                             path: "webworks.handset/2.0.0/client/menu",
138160                             children: {
138161                                 MenuItem: {
138162                                     path: "webworks.handset/2.0.0/client/MenuItem"
138163                                 }
138164                             }
138165                         }
138166                     }
138167                 },
138168                 utils: {
138169                     path: "webworks.core/2.0.0/client/utils",
138170                     feature: "blackberry.utils"
138171                 },
138172                 find: {
138173                     feature: "blackberry.find",
138174                     children: {
138175                         FilterExpression: {
138176                             path: "webworks.handset/2.0.0/client/FilterExpression",
138177                             feature: "blackberry.find"
138178                         }
138179                     }
138180                 },
138181                 push: {
138182                     path: "webworks.handset/2.0.0/client/push",
138183                     feature: "blackberry.push"
138184                 },
138185                 audio: {
138186                     path: "webworks.handset/2.0.0/client/audio",
138187                     feature: "blackberry.audio",
138188                     children: {
138189                         Player: {
138190                             path: "webworks.handset/2.0.0/client/AudioPlayer",
138191                             feature: "blackberry.audio.Player"
138192                         }
138193                     }
138194                 },
138195                 io: {
138196                     children: {
138197                         dir: {
138198                             path: "webworks.handset/2.0.0/client/io/dir",
138199                             feature: "blackberry.io.dir"
138200                         },
138201                         file: {
138202                             path: "webworks.core/2.0.0/client/io/file",
138203                             feature: "blackberry.io.file"
138204                         }
138205                     }
138206                 }
138207             }
138208         }
138209     }
138210 };
138211
138212 });
138213 define('ripple/platform/webworks.tablet/2.0.0/XMLHttpRequest', function (require, exports, module) {
138214 /*
138215  *  Copyright 2011 Research In Motion Limited.
138216  *
138217  * Licensed under the Apache License, Version 2.0 (the "License");
138218  * you may not use this file except in compliance with the License.
138219  * You may obtain a copy of the License at
138220  *
138221  * http://www.apache.org/licenses/LICENSE-2.0
138222  *
138223  * Unless required by applicable law or agreed to in writing, software
138224  * distributed under the License is distributed on an "AS IS" BASIS,
138225  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138226  * See the License for the specific language governing permissions and
138227  * limitations under the License.
138228  */
138229
138230 var xhr = require("ripple/platform/webworks.core/2.0.0/XMLHttpRequest");
138231 module.exports = xhr.create("ripple/platform/webworks.tablet/2.0.0/server");
138232
138233 });
138234 define('ripple/platform/webworks.tablet/2.0.0/client/BrowserArguments', function (require, exports, module) {
138235 /*
138236  *  Copyright 2011 Research In Motion Limited.
138237  *
138238  * Licensed under the Apache License, Version 2.0 (the "License");
138239  * you may not use this file except in compliance with the License.
138240  * You may obtain a copy of the License at
138241  *
138242  * http://www.apache.org/licenses/LICENSE-2.0
138243  *
138244  * Unless required by applicable law or agreed to in writing, software
138245  * distributed under the License is distributed on an "AS IS" BASIS,
138246  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138247  * See the License for the specific language governing permissions and
138248  * limitations under the License.
138249  */
138250 //blackberry.invoke.BrowserArguments ( url : String ,  [transport : blackberry.identity.Transport ] )
138251 module.exports = function (url, transport) {
138252     return {
138253         url: url
138254     };
138255 };
138256
138257 });
138258 define('ripple/platform/webworks.tablet/2.0.0/client/CameraArguments', function (require, exports, module) {
138259 /*
138260  *  Copyright 2011 Research In Motion Limited.
138261  *
138262  * Licensed under the Apache License, Version 2.0 (the "License");
138263  * you may not use this file except in compliance with the License.
138264  * You may obtain a copy of the License at
138265  *
138266  * http://www.apache.org/licenses/LICENSE-2.0
138267  *
138268  * Unless required by applicable law or agreed to in writing, software
138269  * distributed under the License is distributed on an "AS IS" BASIS,
138270  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138271  * See the License for the specific language governing permissions and
138272  * limitations under the License.
138273  */
138274 //blackberry.invoke.CameraArguments ( )
138275 var _self = function () {
138276     return {
138277         //readwrite  property  Number   view
138278         view: 0
138279     };
138280 };
138281
138282 //const Number  VIEW_CAMERA  = 0
138283 _self.__defineGetter__("VIEW_CAMERA", function () {
138284     return 0;
138285 });
138286 //const Number  VIEW_RECORDER  = 1
138287 _self.__defineGetter__("VIEW_RECORDER", function () {
138288     return 1;
138289 });
138290
138291 module.exports = _self;
138292
138293 });
138294 define('ripple/platform/webworks.tablet/2.0.0/client/app', function (require, exports, module) {
138295 /*
138296  *  Copyright 2011 Research In Motion Limited.
138297  *
138298  * Licensed under the Apache License, Version 2.0 (the "License");
138299  * you may not use this file except in compliance with the License.
138300  * You may obtain a copy of the License at
138301  *
138302  * http://www.apache.org/licenses/LICENSE-2.0
138303  *
138304  * Unless required by applicable law or agreed to in writing, software
138305  * distributed under the License is distributed on an "AS IS" BASIS,
138306  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138307  * See the License for the specific language governing permissions and
138308  * limitations under the License.
138309  */
138310 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
138311     _uri = "blackberry/app/",
138312     _self;
138313
138314 _self = {
138315     exit: function () {
138316         transport.call(_uri + "exit", {async: true});
138317     }
138318 };
138319
138320 _self.__defineGetter__("author", function () {
138321     return transport.call(_uri + "author");
138322 });
138323
138324 _self.__defineGetter__("authorEmail", function () {
138325     return transport.call(_uri + "authorEmail");
138326 });
138327
138328 _self.__defineGetter__("authorURL", function () {
138329     return transport.call(_uri + "authorURL");
138330 });
138331
138332 _self.__defineGetter__("copyright", function () {
138333     return transport.call(_uri + "copyright");
138334 });
138335
138336 _self.__defineGetter__("description", function () {
138337     return transport.call(_uri + "description");
138338 });
138339
138340 _self.__defineGetter__("id", function () {
138341     return transport.call(_uri + "id");
138342 });
138343
138344 _self.__defineGetter__("license", function () {
138345     return transport.call(_uri + "license");
138346 });
138347
138348 _self.__defineGetter__("licenseURL", function () {
138349     return transport.call(_uri + "licenseURL");
138350 });
138351
138352 _self.__defineGetter__("name", function () {
138353     return transport.call(_uri + "name");
138354 });
138355
138356 _self.__defineGetter__("version", function () {
138357     return transport.call(_uri + "version");
138358 });
138359
138360 module.exports = _self;
138361
138362 });
138363 define('ripple/platform/webworks.tablet/2.0.0/client/appEvent', function (require, exports, module) {
138364 /*
138365  *  Copyright 2011 Research In Motion Limited.
138366  *
138367  * Licensed under the Apache License, Version 2.0 (the "License");
138368  * you may not use this file except in compliance with the License.
138369  * You may obtain a copy of the License at
138370  *
138371  * http://www.apache.org/licenses/LICENSE-2.0
138372  *
138373  * Unless required by applicable law or agreed to in writing, software
138374  * distributed under the License is distributed on an "AS IS" BASIS,
138375  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138376  * See the License for the specific language governing permissions and
138377  * limitations under the License.
138378  */
138379 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
138380     _callbacks = {},
138381     _self;
138382
138383 function _poll(evt, handler) {
138384     _callbacks[evt] = handler;
138385
138386     transport.poll("blackberry/app/event/" + evt, {}, function () {
138387         var func = _callbacks[evt];
138388
138389         if (func) {
138390             func();
138391         }
138392
138393         return !!func;
138394     });
138395 }
138396
138397 _self = {
138398     onBackground: function (handler) {
138399         _poll("onBackground", handler);
138400     },
138401
138402     onForeground: function (handler) {
138403         _poll("onForeground", handler);
138404     },
138405
138406     onSwipeDown: function (handler) {
138407         _poll("onSwipeDown", handler);
138408     },
138409
138410     onSwipeStart: function (handler) {
138411         _poll("onSwipeStart", handler);
138412     }
138413 };
138414
138415 module.exports = _self;
138416
138417 });
138418 define('ripple/platform/webworks.tablet/2.0.0/client/identity', function (require, exports, module) {
138419 /*
138420  *  Copyright 2011 Research In Motion Limited.
138421  *
138422  * Licensed under the Apache License, Version 2.0 (the "License");
138423  * you may not use this file except in compliance with the License.
138424  * You may obtain a copy of the License at
138425  *
138426  * http://www.apache.org/licenses/LICENSE-2.0
138427  *
138428  * Unless required by applicable law or agreed to in writing, software
138429  * distributed under the License is distributed on an "AS IS" BASIS,
138430  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138431  * See the License for the specific language governing permissions and
138432  * limitations under the License.
138433  */
138434 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
138435     _uri = "blackberry/identity/",
138436     _self = {};
138437
138438 _self.__defineGetter__("PIN", function () {
138439     return transport.call(_uri + "PIN");
138440 });
138441
138442 module.exports = _self;
138443
138444 });
138445 define('ripple/platform/webworks.tablet/2.0.0/client/invoke', function (require, exports, module) {
138446 /*\r
138447  *  Copyright 2011 Research In Motion Limited.\r
138448  *\r
138449  * Licensed under the Apache License, Version 2.0 (the "License");\r
138450  * you may not use this file except in compliance with the License.\r
138451  * You may obtain a copy of the License at\r
138452  *\r
138453  * http://www.apache.org/licenses/LICENSE-2.0\r
138454  *\r
138455  * Unless required by applicable law or agreed to in writing, software\r
138456  * distributed under the License is distributed on an "AS IS" BASIS,\r
138457  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
138458  * See the License for the specific language governing permissions and\r
138459  * limitations under the License.\r
138460  */\r
138461 var _uri = "blackberry/invoke/invoke",\r
138462     APP_TYPE = "appType",\r
138463     APP_URL_CAMERA = "camera://",\r
138464     APP_URL_CAMERA_VIDEO = "camera://video",\r
138465     APP_URL_MAP = "map://",\r
138466     APP_URL_MUSIC = "music://",\r
138467     APP_URL_PHOTOS = "photos://",\r
138468     APP_URL_VIDEOS = "videos://",\r
138469     APP_URL_APPWORLD = "appworld://",\r
138470     APP_URL_UPDATE = "update://",\r
138471     APP_TYPE_ERROR = "appType not supported",\r
138472     APP_BROWSER_ERROR = "Protocol specified in the url is not supported.",\r
138473     transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
138474     _self;\r
138475 \r
138476 _self = {\r
138477     invoke: function (appType, args) {\r
138478         var get = {};\r
138479 \r
138480         switch (appType) {\r
138481 \r
138482         //Camera\r
138483         case 4:\r
138484             if (!args || args.view === 1) {\r
138485                 get.appType = APP_URL_CAMERA_VIDEO;\r
138486             } else {\r
138487                 get.appType = APP_URL_CAMERA;\r
138488             }\r
138489             break;\r
138490 \r
138491         //Maps\r
138492         case 5:\r
138493             get.appType = APP_URL_MAP;\r
138494             break;\r
138495 \r
138496         //Browser\r
138497         case 11:\r
138498 \r
138499             if (!args) {\r
138500                 get.appType = "http://";\r
138501             }\r
138502             else {\r
138503                 get.appType = args.url.split("://");\r
138504 \r
138505                 if (get.appType.length === 1) {\r
138506                     get.appType = "http://" + get.appType[0];\r
138507                 }\r
138508                 else if (get.appType.length === 2) {\r
138509                     if (get.appType[0].indexOf("http") !== 0) {\r
138510                         throw APP_BROWSER_ERROR;\r
138511                     }\r
138512                     else {\r
138513                         get.appType = args.url;\r
138514                     }\r
138515                 }\r
138516             }\r
138517             break;\r
138518 \r
138519         //Music\r
138520         case 13:\r
138521             get.appType = APP_URL_MUSIC;\r
138522             break;\r
138523 \r
138524         //Photos\r
138525         case 14:\r
138526             get.appType = APP_URL_PHOTOS;\r
138527             break;\r
138528 \r
138529         //Videos\r
138530         case 15:\r
138531             get.appType = APP_URL_VIDEOS;\r
138532             break;\r
138533 \r
138534         //AppWorld\r
138535         case 16:\r
138536             get.appType = APP_URL_APPWORLD;\r
138537             break;\r
138538 \r
138539         //Update\r
138540         case 17:\r
138541             get.appType = APP_URL_UPDATE;\r
138542             break;\r
138543 \r
138544         default:\r
138545             throw APP_TYPE_ERROR;\r
138546         }\r
138547 \r
138548         transport.call(_uri, {\r
138549             get: get,\r
138550             async: true\r
138551         });\r
138552     }\r
138553 };\r
138554 \r
138555 _self.__defineGetter__("APP_CAMERA", function () {\r
138556     return 4;\r
138557 });\r
138558 _self.__defineGetter__("APP_MAPS", function () {\r
138559     return 5;\r
138560 });\r
138561 _self.__defineGetter__("APP_BROWSER", function () {\r
138562     return 11;\r
138563 });\r
138564 _self.__defineGetter__("APP_MUSIC", function () {\r
138565     return 13;\r
138566 });\r
138567 _self.__defineGetter__("APP_PHOTOS", function () {\r
138568     return 14;\r
138569 });\r
138570 _self.__defineGetter__("APP_VIDEOS", function () {\r
138571     return 15;\r
138572 });\r
138573 _self.__defineGetter__("APP_APPWORLD", function () {\r
138574     return 16;\r
138575 });\r
138576 \r
138577 module.exports = _self;\r
138578
138579 });
138580 define('ripple/platform/webworks.tablet/2.0.0/client/io/dir', function (require, exports, module) {
138581 /*
138582  * Copyright 2011 Research In Motion Limited.
138583  *
138584  * Licensed under the Apache License, Version 2.0 (the "License");
138585  * you may not use this file except in compliance with the License.
138586  * You may obtain a copy of the License at
138587  *
138588  *     http://www.apache.org/licenses/LICENSE-2.0
138589  *
138590  * Unless required by applicable law or agreed to in writing, software
138591  * distributed under the License is distributed on an "AS IS" BASIS,
138592  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138593  * See the License for the specific language governing permissions and
138594  * limitations under the License.
138595  */
138596 var dir = require('ripple/platform/webworks.core/2.0.0/client/io/dir'),
138597     utils = require('ripple/utils'),
138598     _self = {};
138599
138600 utils.mixin({
138601     appDirs: {
138602         "app": {
138603             "storage" : {
138604                 "path" : "file:///accounts/1000/appdata/emulatedapp/data"
138605             }
138606         },
138607         "shared": {
138608             "bookmarks": {
138609                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/bookmarks"
138610             },
138611             "books": {
138612                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/books"
138613             },
138614             "camera": {
138615                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/camera"
138616             },
138617             "documents": {
138618                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/documents"
138619             },
138620             "downloads": {
138621                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/downloads"
138622             },
138623             "misc": {
138624                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/misc"
138625             },
138626             "music": {
138627                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/music"
138628             },
138629             "photos": {
138630                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/photos"
138631             },
138632             "print": {
138633                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/print"
138634             },
138635             "videos": {
138636                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/videos"
138637             },
138638             "voice": {
138639                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/voice"
138640             }
138641         }
138642     }
138643 }, _self);
138644
138645 utils.mixin(dir, _self);
138646
138647 module.exports = _self;
138648
138649 });
138650 define('ripple/platform/webworks.tablet/2.0.0/client/system', function (require, exports, module) {
138651 /*
138652  *  Copyright 2011 Research In Motion Limited.
138653  *
138654  * Licensed under the Apache License, Version 2.0 (the "License");
138655  * you may not use this file except in compliance with the License.
138656  * You may obtain a copy of the License at
138657  *
138658  * http://www.apache.org/licenses/LICENSE-2.0
138659  *
138660  * Unless required by applicable law or agreed to in writing, software
138661  * distributed under the License is distributed on an "AS IS" BASIS,
138662  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138663  * See the License for the specific language governing permissions and
138664  * limitations under the License.
138665  */
138666 var utils = require('ripple/utils'),
138667     transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
138668     system = require('ripple/platform/webworks.core/2.0.0/client/system'),
138669     _uri = "blackberry/system/";
138670
138671 system.__defineGetter__("scriptApiVersion", function () {
138672     return transport.call(_uri + "softwareVersion");
138673 });
138674
138675
138676 module.exports = system;
138677
138678 });
138679 define('ripple/platform/webworks.tablet/2.0.0/client/systemEvent', function (require, exports, module) {
138680 /*
138681  *  Copyright 2011 Research In Motion Limited.
138682  *
138683  * Licensed under the Apache License, Version 2.0 (the "License");
138684  * you may not use this file except in compliance with the License.
138685  * You may obtain a copy of the License at
138686  *
138687  * http://www.apache.org/licenses/LICENSE-2.0
138688  *
138689  * Unless required by applicable law or agreed to in writing, software
138690  * distributed under the License is distributed on an "AS IS" BASIS,
138691  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138692  * See the License for the specific language governing permissions and
138693  * limitations under the License.
138694  */
138695 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
138696     api = "blackberry/system/event/";
138697
138698 function _poll(evt, handler) {
138699     transport.poll(api + evt, {}, function (data, response) {
138700         if (handler) {
138701             handler(data);
138702         }
138703         return !!handler;
138704     });
138705 }
138706
138707 module.exports = {
138708     deviceBatteryLevelChange: function (handler) {
138709         _poll("deviceBatteryLevelChange", handler);
138710     },
138711     deviceBatteryStateChange: function (handler) {
138712         _poll("deviceBatteryStateChange", handler);
138713     }
138714 };
138715
138716 });
138717 define('ripple/platform/webworks.tablet/2.0.0/server/app', function (require, exports, module) {
138718 /*
138719  *  Copyright 2011 Research In Motion Limited.
138720  *
138721  * Licensed under the Apache License, Version 2.0 (the "License");
138722  * you may not use this file except in compliance with the License.
138723  * You may obtain a copy of the License at
138724  *
138725  * http://www.apache.org/licenses/LICENSE-2.0
138726  *
138727  * Unless required by applicable law or agreed to in writing, software
138728  * distributed under the License is distributed on an "AS IS" BASIS,
138729  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138730  * See the License for the specific language governing permissions and
138731  * limitations under the License.
138732  */
138733 var event = require('ripple/event'),
138734     app = require('ripple/app'),
138735     _self;
138736
138737 _self = {
138738     event: require('ripple/platform/webworks.tablet/2.0.0/server/appEvent'),
138739
138740     exit: function () {
138741         event.trigger("AppExit");
138742         return {code: 1};
138743     },
138744
138745     author: function () {
138746         return {code: 1, data: app.getInfo().author};
138747     },
138748
138749     authorEmail: function () {
138750         return {code: 1, data: app.getInfo().authorEmail};
138751     },
138752
138753     authorURL: function () {
138754         return {code: 1, data: app.getInfo().authorURL};
138755     },
138756
138757     copyright: function () {
138758         return {code: 1, data: app.getInfo().copyright};
138759     },
138760
138761     description: function () {
138762         return {code: 1, data: app.getInfo().description};
138763     },
138764
138765     id: function () {
138766         return {code: 1, data: app.getInfo().id};
138767     },
138768
138769     license: function () {
138770         return {code: 1, data: app.getInfo().license};
138771     },
138772
138773     licenseURL: function () {
138774         return {code: 1, data: app.getInfo().licenseURL};
138775     },
138776
138777     name: function () {
138778         return {code: 1, data: app.getInfo().name};
138779     },
138780
138781     version: function () {
138782         return {code: 1, data: app.getInfo().version};
138783     }
138784 };
138785
138786 module.exports = _self;
138787
138788 });
138789 define('ripple/platform/webworks.tablet/2.0.0/server/appEvent', function (require, exports, module) {
138790 /*
138791  *  Copyright 2011 Research In Motion Limited.
138792  *
138793  * Licensed under the Apache License, Version 2.0 (the "License");
138794  * you may not use this file except in compliance with the License.
138795  * You may obtain a copy of the License at
138796  *
138797  * http://www.apache.org/licenses/LICENSE-2.0
138798  *
138799  * Unless required by applicable law or agreed to in writing, software
138800  * distributed under the License is distributed on an "AS IS" BASIS,
138801  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138802  * See the License for the specific language governing permissions and
138803  * limitations under the License.
138804  */
138805 var event = require('ripple/event'),
138806     notifications = require('ripple/notifications'),
138807     _bg,
138808     _fg,
138809     _swipeDown,
138810     _swipeStart,
138811     _exit;
138812
138813 event.on("AppExit", function () {
138814     var baton = _exit;
138815     _exit = null;
138816     notifications.openNotification("normal", "blackberry.app.exit() as called, in the real world your app will exit, here... you get this notification");
138817     return baton && baton.pass({code: 1});
138818 });
138819
138820 event.on("AppRequestBackground", function () {
138821     var baton = _bg;
138822     _bg = null;
138823     return baton && baton.pass({code: 1});
138824 });
138825
138826 event.on("AppRequestForeground", function () {
138827     var baton = _fg;
138828     _fg = null;
138829     return baton && baton.pass({code: 1});
138830 });
138831
138832 event.on("AppSwipeDown", function () {
138833     var baton = _swipeDown;
138834     _swipeDown = null;
138835     return baton && baton.pass({code: 1});
138836 });
138837
138838 event.on("AppSwipeStart", function () {
138839     var baton = _swipeStart;
138840     _swipeStart = null;
138841     return baton && baton.pass({code: 1});
138842 });
138843
138844 module.exports = {
138845     onBackground: function (get, post, baton) {
138846         baton.take();
138847         _bg = baton;
138848         return {code: 1};
138849     },
138850
138851     onForeground: function (get, post, baton) {
138852         baton.take();
138853         _fg = baton;
138854         return {code: 1};
138855     },
138856
138857     onSwipeDown: function (get, post, baton) {
138858         baton.take();
138859         _swipeDown = baton;
138860         return {code: 1};
138861     },
138862
138863     onSwipeStart: function (get, post, baton) {
138864         baton.take();
138865         _swipeStart = baton;
138866         return {code: 1};
138867     }
138868 };
138869
138870 });
138871 define('ripple/platform/webworks.tablet/2.0.0/server/identity', function (require, exports, module) {
138872 /*
138873  *  Copyright 2011 Research In Motion Limited.
138874  *
138875  * Licensed under the Apache License, Version 2.0 (the "License");
138876  * you may not use this file except in compliance with the License.
138877  * You may obtain a copy of the License at
138878  *
138879  * http://www.apache.org/licenses/LICENSE-2.0
138880  *
138881  * Unless required by applicable law or agreed to in writing, software
138882  * distributed under the License is distributed on an "AS IS" BASIS,
138883  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138884  * See the License for the specific language governing permissions and
138885  * limitations under the License.
138886  */
138887 var deviceSettings = require('ripple/deviceSettings');
138888
138889 module.exports = {
138890     PIN: function () {
138891         return {code: 1, data: deviceSettings.retrieve("identity.PIN")};
138892     }
138893 };
138894
138895 });
138896 define('ripple/platform/webworks.tablet/2.0.0/server/invoke', function (require, exports, module) {
138897 /*
138898  *  Copyright 2011 Research In Motion Limited.
138899  *
138900  * Licensed under the Apache License, Version 2.0 (the "License");
138901  * you may not use this file except in compliance with the License.
138902  * You may obtain a copy of the License at
138903  *
138904  * http://www.apache.org/licenses/LICENSE-2.0
138905  *
138906  * Unless required by applicable law or agreed to in writing, software
138907  * distributed under the License is distributed on an "AS IS" BASIS,
138908  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138909  * See the License for the specific language governing permissions and
138910  * limitations under the License.
138911  */
138912 var notifications = require('ripple/notifications'),
138913     constants = require('ripple/constants'),
138914     type = "normal",
138915     name = {
138916         "camera://": "Camera",
138917         "camera://video": "Video Camera",
138918         "map://": "Maps",
138919         "http://": "Browser",
138920         "music://": "Music",
138921         "photos://": "Photos",
138922         "videos://": "Videos",
138923         "appworld://": "App World",
138924         "update://": "Update"
138925     };
138926
138927 module.exports = {
138928     invoke: function (opts) {
138929         var app = name[opts.appType];
138930         if (app === undefined && opts.appType && opts.appType.match(/^http/i)) {
138931             app = "Browser";
138932         }
138933
138934         notifications.openNotification(type,
138935            "Requested to launch: " + app + " application.");
138936         return {code: 1};
138937     }
138938 };
138939
138940 });
138941 define('ripple/platform/webworks.tablet/2.0.0/server/systemEvent', function (require, exports, module) {
138942 /*
138943  *  Copyright 2011 Research In Motion Limited.
138944  *
138945  * Licensed under the Apache License, Version 2.0 (the "License");
138946  * you may not use this file except in compliance with the License.
138947  * You may obtain a copy of the License at
138948  *
138949  * http://www.apache.org/licenses/LICENSE-2.0
138950  *
138951  * Unless required by applicable law or agreed to in writing, software
138952  * distributed under the License is distributed on an "AS IS" BASIS,
138953  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138954  * See the License for the specific language governing permissions and
138955  * limitations under the License.
138956  */
138957 var event = require('ripple/event'),
138958     _onBatteryStateChange,
138959     _onBatteryLevelChange,
138960     _states = {
138961         UNKNOWN: 0,
138962         FULL: 1,
138963         CHARGING: 2,
138964         UNPLUGGED: 3
138965     },
138966     _battery = {
138967         state: _states.UNKNOWN,
138968         charging: null,
138969         level: null
138970     };
138971
138972 function _getState() {
138973     return _battery.level === 100 ? _states.FULL :
138974            _battery.charging ? _states.CHARGING : _states.UNPLUGGED;
138975 }
138976
138977 function _pass(baton, data) {
138978     if (baton) {
138979         baton.pass({code: 1, data: data});
138980     }
138981 }
138982
138983 event.on("DeviceBatteryStateChanged", function (charging) {
138984     _battery.charging = charging;
138985     _battery.state = _getState();
138986     _pass(_onBatteryStateChange, _battery.state);
138987 });
138988
138989 event.on("DeviceBatteryLevelChanged", function (level) {
138990     level = parseInt(level, 10);
138991
138992     _battery.level = level;
138993     _pass(_onBatteryLevelChange, level);
138994
138995     if (level === 100) {
138996         _battery.state = _getState();
138997         _pass(_onBatteryStateChange, _battery.state);
138998     }
138999 });
139000
139001 module.exports = {
139002     deviceBatteryLevelChange: function (get, post, baton) {
139003         baton.take();
139004         _onBatteryLevelChange = baton;
139005     },
139006     deviceBatteryStateChange: function (get, post, baton) {
139007         baton.take();
139008         _onBatteryStateChange = baton;
139009     }
139010 };
139011
139012 });
139013 define('ripple/platform/webworks.tablet/2.0.0/server', function (require, exports, module) {
139014 /*
139015  *  Copyright 2011 Research In Motion Limited.
139016  *
139017  * Licensed under the Apache License, Version 2.0 (the "License");
139018  * you may not use this file except in compliance with the License.
139019  * You may obtain a copy of the License at
139020  *
139021  * http://www.apache.org/licenses/LICENSE-2.0
139022  *
139023  * Unless required by applicable law or agreed to in writing, software
139024  * distributed under the License is distributed on an "AS IS" BASIS,
139025  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139026  * See the License for the specific language governing permissions and
139027  * limitations under the License.
139028  */
139029 var utils = require('ripple/utils'),
139030     platform = "ripple/platform/webworks.tablet/2.0.0/server/",
139031     core = "ripple/platform/webworks.core/2.0.0/server/",
139032     systemEvent = require(platform + 'systemEvent'),
139033     system = {};
139034
139035 // ugh, thanks to the spec...
139036 system.event = systemEvent;
139037 utils.mixin(require(core + "system"), system);
139038
139039 module.exports = {
139040     blackberry: {
139041         identity: require(platform + "identity"),
139042         app: require(platform + "app"),
139043         invoke: require(platform + "invoke"),
139044         system: system,
139045         ui: {
139046             dialog: require(core + "dialog")
139047         },
139048         io: {
139049             dir: require(core + "io/dir"),
139050             file: require(core + "io/file")
139051         }
139052     }
139053 };
139054
139055 });
139056 define('ripple/platform/webworks.tablet/2.0.0/spec/device', function (require, exports, module) {
139057 /*
139058  *  Copyright 2011 Research In Motion Limited.
139059  *
139060  * Licensed under the Apache License, Version 2.0 (the "License");
139061  * you may not use this file except in compliance with the License.
139062  * You may obtain a copy of the License at
139063  *
139064  * http://www.apache.org/licenses/LICENSE-2.0
139065  *
139066  * Unless required by applicable law or agreed to in writing, software
139067  * distributed under the License is distributed on an "AS IS" BASIS,
139068  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139069  * See the License for the specific language governing permissions and
139070  * limitations under the License.
139071  */
139072 var event = require('ripple/event');
139073
139074 module.exports = {
139075     "transports": {
139076         "TCPCellular": {
139077             "name": "Cellular TCP",
139078             "control": {
139079                 "type": "checkbox",
139080                 "value": true
139081             }
139082         },
139083         "WAP": {
139084             "name": "WAP",
139085             "control": {
139086                 "type": "checkbox",
139087                 "value": false
139088             }
139089         },
139090         "WAP2": {
139091             "name": "WAP 2.0",
139092             "control": {
139093                 "type": "checkbox",
139094                 "value": false
139095             }
139096         },
139097         "MDS": {
139098             "name": "MDS",
139099             "control": {
139100                 "type": "checkbox",
139101                 "value": true
139102             }
139103         },
139104         "BISB": {
139105             "name": "BIS B",
139106             "control": {
139107                 "type": "checkbox",
139108                 "value": true
139109             }
139110         },
139111         "Unite": {
139112             "name": "Unite!",
139113             "control": {
139114                 "type": "checkbox",
139115                 "value": false
139116             }
139117         },
139118         "TCPWifi": {
139119             "name": "Wifi TCP",
139120             "control": {
139121                 "type": "checkbox",
139122                 "value": true
139123             }
139124         }
139125     },
139126     "identity": {
139127         "PIN": {
139128             "name": "PIN",
139129             "control": {
139130                 "type": "text",
139131                 "value": "43A8C489"
139132             }
139133         }
139134     },
139135     "battery": {
139136         "state": {
139137             "name": "Handset is Charging",
139138             "control": {
139139                 "type": "checkbox",
139140                 "value": true
139141             },
139142             "callback": function (setting) {
139143                 event.trigger("DeviceBatteryStateChanged", [setting]);
139144             }
139145         },
139146         "level":  {
139147             "name": "Charge Level (% remaining)",
139148             "control": {
139149                 "type": "select",
139150                 "value": 100
139151             },
139152             "options": (function () {
139153                 var i,
139154                     optionList = {};
139155
139156                 for (i = 0; i <= 100; i++) {
139157                     optionList[i] = i;
139158                 }
139159
139160                 return optionList;
139161             }()),
139162             "callback": function (setting) {
139163                 event.trigger("DeviceBatteryLevelChanged", [setting]);
139164             }
139165         }
139166     },
139167     "system": {
139168         "isMassStorageActive": {
139169             "name": "Mass Storage Is Connected",
139170             "control": {
139171                 "type": "checkbox",
139172                 "value": true
139173             }
139174         },
139175         "hasDataCoverage": {
139176             "name": "Has Data Coverage",
139177             "control": {
139178                 "type": "checkbox",
139179                 "value": true
139180             },
139181             "callback": function (setting) {
139182                 event.trigger("CoverageChange");
139183                 require('ripple/bus').send("network", setting);
139184             }
139185         },
139186         "lag": {
139187             "name": "Lag the network",
139188             "control": {
139189                 type: "checkbox",
139190                 value: false
139191             },
139192             "callback": function (setting) {
139193                 require('ripple/bus').send("lag", setting);
139194             }
139195         },
139196         "network": {
139197             "name": "Data Network",
139198             "control": {
139199                 "type": "select",
139200                 "value": "3GPP"
139201             },
139202             "options": {
139203                 "3GPP" : "3GPP",
139204                 "CDMA": "CDMA",
139205                 "iDEN": "iDEN",
139206                 "Wi-Fi": "Wi-Fi"
139207             },
139208             "callback": function (setting) {
139209                 event.trigger("CoverageChange");
139210             }
139211         }
139212     }
139213 };
139214
139215 });
139216 define('ripple/platform/webworks.tablet/2.0.0/spec/events', function (require, exports, module) {
139217 /*
139218  *  Copyright 2011 Research In Motion Limited.
139219  *
139220  * Licensed under the Apache License, Version 2.0 (the "License");
139221  * you may not use this file except in compliance with the License.
139222  * You may obtain a copy of the License at
139223  *
139224  * http://www.apache.org/licenses/LICENSE-2.0
139225  *
139226  * Unless required by applicable law or agreed to in writing, software
139227  * distributed under the License is distributed on an "AS IS" BASIS,
139228  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139229  * See the License for the specific language governing permissions and
139230  * limitations under the License.
139231  */
139232 var _self,
139233     utils = require('ripple/utils'),
139234     event = require('ripple/event'),
139235     events = require('ripple/platform/webworks.core/2.0.0/spec/events');
139236
139237 _self = {
139238     "app.event.onSwipeDown": {
139239         callback: function () {
139240             event.trigger("AppSwipeDown");
139241         }
139242     },
139243     "app.event.onSwipeStart": {
139244         callback: function () {
139245             event.trigger("AppSwipeStart");
139246         }
139247     }
139248 };
139249
139250 utils.mixin(events, _self);
139251
139252 module.exports = _self;
139253
139254 });
139255 define('ripple/platform/webworks.tablet/2.0.0/spec/ui', function (require, exports, module) {
139256 /*
139257  *  Copyright 2011 Research In Motion Limited.
139258  *
139259  * Licensed under the Apache License, Version 2.0 (the "License");
139260  * you may not use this file except in compliance with the License.
139261  * You may obtain a copy of the License at
139262  *
139263  * http://www.apache.org/licenses/LICENSE-2.0
139264  *
139265  * Unless required by applicable law or agreed to in writing, software
139266  * distributed under the License is distributed on an "AS IS" BASIS,
139267  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139268  * See the License for the specific language governing permissions and
139269  * limitations under the License.
139270  */
139271 module.exports = {
139272     plugins: [
139273         "accelerometer",
139274         "deviceSettings",
139275         "geoView",
139276         "platformEvents",
139277         "widgetConfig",
139278         "build"
139279     ]
139280 };
139281
139282 });
139283 define('ripple/platform/webworks.tablet/2.0.0/spec', function (require, exports, module) {
139284 /*
139285  *  Copyright 2011 Research In Motion Limited.
139286  *
139287  * Licensed under the Apache License, Version 2.0 (the "License");
139288  * you may not use this file except in compliance with the License.
139289  * You may obtain a copy of the License at
139290  *
139291  * http://www.apache.org/licenses/LICENSE-2.0
139292  *
139293  * Unless required by applicable law or agreed to in writing, software
139294  * distributed under the License is distributed on an "AS IS" BASIS,
139295  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139296  * See the License for the specific language governing permissions and
139297  * limitations under the License.
139298  */
139299 module.exports = {
139300
139301     id: "webworks.tablet",
139302     version: "2.0.0",
139303     name: "WebWorks-TabletOS",
139304
139305     persistencePrefix: "rim-tablet-",
139306
139307     ui: require('ripple/platform/webworks.tablet/2.0.0/spec/ui'),
139308     device: require('ripple/platform/webworks.tablet/2.0.0/spec/device'),
139309     config: require('ripple/platform/webworks.core/2.0.0/spec/config'),
139310     events: require('ripple/platform/webworks.tablet/2.0.0/spec/events'),
139311
139312     initialize: function () {},
139313
139314     objects: {
139315         XMLHttpRequest: {
139316             path: "webworks.tablet/2.0.0/XMLHttpRequest"
139317         },
139318         Coordinates: {
139319             path: "w3c/1.0/Coordinates"
139320         },
139321         Position: {
139322             path: "w3c/1.0/Position"
139323         },
139324         PositionError: {
139325             path: "w3c/1.0/PositionError"
139326         },
139327         navigator: {
139328             path: "w3c/1.0/navigator",
139329             children: {
139330                 geolocation: {
139331                     path: "w3c/1.0/geolocation"
139332                 }
139333             }
139334         },
139335         blackberry: {
139336             children: {
139337                 transport: {
139338                     path: "webworks.core/2.0.0/client/transport"
139339                 },
139340                 events: {
139341                     path: "webworks.core/2.0.0/client/events"
139342                 },
139343                 app: {
139344                     path: "webworks.tablet/2.0.0/client/app",
139345                     feature: "blackberry.app",
139346                     children: {
139347                         event: {
139348                             path: "webworks.tablet/2.0.0/client/appEvent",
139349                             feature: "blackberry.app.event"
139350                         }
139351                     }
139352                 },
139353                 invoke: {
139354                     path: "webworks.tablet/2.0.0/client/invoke",
139355                     feature: "blackberry.invoke",
139356                     children: {
139357                         BrowserArguments: {
139358                             path: "webworks.tablet/2.0.0/client/BrowserArguments",
139359                             feature: "blackberry.invoke.BrowserArguments"
139360                         },
139361                         CameraArguments: {
139362                             path: "webworks.tablet/2.0.0/client/CameraArguments",
139363                             feature: "blackberry.invoke.CameraArguments"
139364                         }
139365                     }
139366                 },
139367                 identity: {
139368                     path: "webworks.tablet/2.0.0/client/identity",
139369                     feature: "blackberry.identity"
139370                 },
139371                 system: {
139372                     path: "webworks.tablet/2.0.0/client/system",
139373                     children: {
139374                         event: {
139375                             path: "webworks.tablet/2.0.0/client/systemEvent"
139376                         }
139377                     }
139378                 },
139379                 ui: {
139380                     children: {
139381                         dialog: {
139382                             path: "webworks.core/2.0.0/client/dialog",
139383                             feature: "blackberry.ui.dialog"
139384                         }
139385                     }
139386                 },
139387                 utils: {
139388                     path: "webworks.core/2.0.0/client/utils",
139389                     feature: "blackberry.utils"
139390                 },
139391                 io: {
139392                     children: {
139393                         dir: {
139394                             path: "webworks.tablet/2.0.0/client/io/dir",
139395                             feature: "blackberry.io.dir"
139396                         },
139397                         file: {
139398                             path: "webworks.core/2.0.0/client/io/file",
139399                             feature: "blackberry.io.file"
139400                         }
139401                     }
139402                 }
139403             }
139404         }
139405     }
139406 };
139407
139408 });
139409 define('ripple/platform', function (require, exports, module) {
139410 /*
139411  *  Copyright 2011 Research In Motion Limited.
139412  *
139413  * Licensed under the Apache License, Version 2.0 (the "License");
139414  * you may not use this file except in compliance with the License.
139415  * You may obtain a copy of the License at
139416  *
139417  * http://www.apache.org/licenses/LICENSE-2.0
139418  *
139419  * Unless required by applicable law or agreed to in writing, software
139420  * distributed under the License is distributed on an "AS IS" BASIS,
139421  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139422  * See the License for the specific language governing permissions and
139423  * limitations under the License.
139424  */
139425 var _current,
139426     db = require('ripple/db'),
139427     utils = require('ripple/utils'),
139428     _console = require('ripple/console'),
139429     app = require('ripple/app'),
139430     event = require('ripple/event'),
139431     spec = require('ripple/platform/spec'),
139432     _self;
139433
139434 function _getRequestedPlatform() {
139435     var requestedPlatform = null,
139436         enableRippleArg = utils.queryString().enableripple,
139437         platform;
139438
139439     if (enableRippleArg) {
139440         enableRippleArg = enableRippleArg.split('-');
139441         platform = spec.get(enableRippleArg[0], enableRippleArg[1]);
139442         if (platform) {
139443             requestedPlatform = { name: platform.id, version: platform.version };
139444         }
139445     }
139446
139447     return requestedPlatform;
139448 }
139449
139450 function _validatePlatform(platform, defaultPlatform) {
139451     if (!platform ||
139452         !spec[platform.name] ||
139453         !spec[platform.name][platform.version] ||
139454         (spec[platform.name][platform.version] && !spec[platform.name][platform.version].objects)) {
139455         return defaultPlatform;
139456     }
139457     return platform;
139458 }
139459
139460 function _getPlatform() {
139461     return require('ripple/platform/' + _current.name + "/" + _current.version + "/spec");
139462 }
139463
139464 _self = {
139465     initialize: function () {
139466         var firstAvailablePlatform = utils.map(this.getList(), function (platform) {
139467             return utils.map(platform, function (details, version) {
139468                 return {name: details.id, version: version};
139469             })[0];
139470         })[0];
139471
139472         _current = _getRequestedPlatform() || db.retrieveObject("api-key") || firstAvailablePlatform;
139473         _current = _validatePlatform(_current, firstAvailablePlatform);
139474         db.saveObject("api-key", _current);
139475
139476         _console.prefix = _current.name;
139477     },
139478
139479     getList: function () {
139480         var platformList = {};
139481         utils.forEach(spec, function (platform, platformKey) {
139482             utils.forEach(platform, function (version, versionKey) {
139483                 platformList[platformKey] = platformList[platformKey] || {};
139484                 platformList[platformKey][versionKey] = {
139485                     "id": version.id,
139486                     "name": version.name,
139487                     "type": version.type,
139488                     "text": require('ripple/platform/' + platformKey + "/" + versionKey + "/spec").version
139489                 };
139490             });
139491         });
139492
139493         return platformList;
139494     },
139495
139496     getPersistencePrefix: function (id) {
139497         return _getPlatform().persistencePrefix + (id || app.getInfo().id) + "-";
139498     },
139499
139500     current: function () {
139501         return _getPlatform();
139502     },
139503
139504     changeEnvironment: function (platform, deviceId, callback) {
139505         var save = jWorkflow.order(function (prev, baton) {
139506                 baton.take();
139507                 db.saveObject("api-key", platform, null, baton.pass);
139508             }).andThen(function (prev, baton) {
139509                 baton.take();
139510                 db.save("device-key", deviceId, null, baton.pass);
139511             }).andThen(function (prev, baton) {
139512                 //remove the persisted value for the layout
139513                 baton.take();
139514                 db.save("layout", null, null, baton.pass);
139515             }).andThen(function () {
139516                 event.trigger("PlatformChangedEvent", [], true);
139517                 _console.prefix = null;
139518                 _console.log("Emulator :: loading platform " + platform.name);
139519             });
139520
139521         save.start(callback);
139522     }
139523 };
139524
139525 module.exports = _self;
139526
139527 });
139528 define('ripple/resizer', function (require, exports, module) {
139529 /*
139530  *  Copyright 2011 Research In Motion Limited.
139531  *
139532  * Licensed under the Apache License, Version 2.0 (the "License");
139533  * you may not use this file except in compliance with the License.
139534  * You may obtain a copy of the License at
139535  *
139536  * http://www.apache.org/licenses/LICENSE-2.0
139537  *
139538  * Unless required by applicable law or agreed to in writing, software
139539  * distributed under the License is distributed on an "AS IS" BASIS,
139540  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139541  * See the License for the specific language governing permissions and
139542  * limitations under the License.
139543  */
139544 var db = require('ripple/db'),
139545     exception = require('ripple/exception'),
139546     utils = require('ripple/utils'),
139547     devices = require('ripple/devices'),
139548     constants = require('ripple/constants'),
139549     event = require('ripple/event'),
139550     _win,
139551     _doc,
139552     _self;
139553
139554 function _validateLayoutType(layoutType) {
139555     return (layoutType === "landscape" || layoutType === "portrait");
139556 }
139557
139558 function _validateOrientation(orientation) {
139559     return (orientation === "landscape" || orientation === "portrait");
139560 }
139561
139562 function _getContainers() {
139563     return {
139564         device: {
139565             div: document.getElementById("device-container"),
139566             containerClass: document.getElementById("device-container").getAttribute("class") || ""
139567         },
139568         viewport: {
139569             div: document.getElementById("viewport-container"),
139570             containerClass: document.getElementById("viewport-container").getAttribute("class") || ""
139571         },
139572         "menu-button": {
139573             div: document.getElementById(constants.COMMON.MENU_BUTTON),
139574             containerClass: document.getElementById(constants.COMMON.MENU_BUTTON).getAttribute("class") || ""
139575         },
139576         "back-button": {
139577             div: document.getElementById(constants.COMMON.BACK_BUTTON),
139578             containerClass: document.getElementById(constants.COMMON.BACK_BUTTON).getAttribute("class") || ""
139579         }
139580     };
139581 }
139582
139583 function _setContainers(containers, device, orientation) {
139584     var suffix = {
139585             portrait:  "-wrapper" + (device.skin ? "-" + device.skin : ""),
139586             landscape: "-wrapper-landscape" + (device.skin ? "-" + device.skin : "")
139587         };
139588
139589     utils.forEach(containers, function (container, key) {
139590         container.div.setAttribute("class", container.containerClass.replace(/\s.*$/, "") + " " + key + suffix[orientation]);
139591     });
139592 }
139593
139594 function _getDimensions(device, orientation) {
139595     return {
139596         deviceWidth: orientation === "portrait" ? device.screen.width : device.screen.height,
139597         deviceHeight: orientation === "portrait" ? device.screen.height : device.screen.width,
139598         paddingLeft: device.viewPort[orientation].paddingLeft,
139599         paddingTop: device.viewPort[orientation].paddingTop,
139600         viewPort: {
139601             width: device.viewPort[orientation].width,
139602             height: device.viewPort[orientation].height
139603         }
139604     };
139605 }
139606
139607 function _formatSkin(containers, dimensions) {
139608     var scaleFactor = dimensions.deviceWidth / dimensions.viewPort.width,
139609     scaleString = "scale(" + scaleFactor + ")";
139610
139611     containers.device.div.style.width = (dimensions.deviceWidth + 4) + "px";
139612     containers.device.div.style.height = (dimensions.deviceHeight + 4) + "px";
139613     containers.viewport.div.style.width = dimensions.viewPort.width + "px";
139614     containers.viewport.div.style.height = dimensions.viewPort.height + "px";
139615     containers.viewport.div.style.padding = "0";
139616
139617     jQuery('#viewport-container').css('-webkit-transform', scaleString);
139618     jQuery('#viewport-container').css('-webkit-transform-origin', 'left top');
139619 }
139620
139621 function _setOrientation(layout) {
139622     _win.orientation = window.orientation = layout === "portrait" ? 0 : 90;
139623 }
139624
139625 function _upDateHWKeyPanelPosition(orientation, scaleFactor) {
139626     var left = 0;
139627
139628     if (orientation === 'portrait') {
139629         if (db.retrieve("layout") === "portrait") {
139630             left = 350 + $('#device-layout').width()*scaleFactor;
139631         } else {
139632             left = 470 + $('#device-layout').height()*scaleFactor;
139633         }
139634     } else {
139635         if (db.retrieve("layout") === "portrait") {
139636             left = 490 + $('#device-layout').height()*scaleFactor;
139637         } else {
139638             left = 350 + $('#device-layout').width()*scaleFactor;
139639         }
139640     }
139641
139642     $("#hwkeys-panel").css("top", "40px");
139643     $("#hwkeys-panel").css("left", left+"px");
139644 }
139645
139646 function _getTransformString(orientation, scaleFactor) {
139647     var transformString = "",
139648     offset;
139649
139650     if (orientation === "landscape") {
139651         if (db.retrieve("layout") === "portrait") {
139652             offset = devices.getCurrentDevice().screen.height * scaleFactor + 170;
139653             transformString = "translate("+ offset + "px, 0px) rotate(90deg) scale("+ scaleFactor +")";
139654         } else {
139655             transformString = "translate(0px,0px) rotate(0deg) scale("+ scaleFactor +")";
139656         }
139657     } else {
139658         if (db.retrieve("layout") === "portrait") {
139659             transformString = "translate(0px,0px) rotate(0deg) scale("+ scaleFactor +")";
139660         } else {
139661             offset = devices.getCurrentDevice().screen.width * scaleFactor + 150;
139662             transformString = "translate("+ offset + "px, 0px) rotate(90deg) scale("+ scaleFactor +")";
139663         }
139664     }
139665
139666     return transformString;
139667 }
139668
139669
139670 _self = {
139671     init: function (win, doc) {
139672         _win = win;
139673         _doc = doc;
139674
139675         var layout = db.retrieve("layout") || "portrait";
139676
139677         _setOrientation(layout);
139678
139679         _win.onorientationchange = undefined;
139680     },
139681     // TODO: redo/refactor this in general, seems bloated, also devices REQUIRE viewport schemas which they shouldnt
139682     resize: function (device) {
139683         var layout = db.retrieve("layout"),
139684             orientation = "portrait",
139685             containers, dimensions;
139686
139687         if (layout && layout === "landscape" && device.viewPort.landscape) {
139688             orientation = "landscape";
139689         }
139690
139691         containers = _getContainers();
139692         _setContainers(containers, device, orientation);
139693
139694         dimensions = _getDimensions(device, orientation);
139695         if (!device.skin) {
139696             _formatSkin(containers, dimensions);
139697         }
139698
139699         event.trigger("ScreenChangeDimensions", [dimensions.viewPort.width, dimensions.viewPort.height]);
139700     },
139701
139702     changeLayoutType: function (layoutType) {
139703         var orientation = db.retrieve("deviceOrientation") || "portrait";
139704         if (!_validateLayoutType(layoutType)) {
139705             exception.raise(exception.types.LayoutType, "unknown layout type requested!");
139706         }
139707
139708         db.save("layout", layoutType);
139709         _self.resize(devices.getCurrentDevice());
139710         _self.rotateDevice(orientation);
139711
139712         if (!_win) return;
139713         _setOrientation(layoutType);
139714     },
139715
139716     scaleDevice: function (scaleFactor) {
139717         var orientation = db.retrieve("deviceOrientation") || "portrait",
139718         transformString = _getTransformString(orientation, scaleFactor);
139719         _upDateHWKeyPanelPosition(orientation, scaleFactor);
139720         db.save("deviceScaleFactor", scaleFactor);
139721         jQuery('#device-layout').css('-webkit-transform-origin', '0% 0%');
139722         jQuery('#device-layout').css('-webkit-transform',  transformString);
139723     },
139724
139725     rotateDevice: function (orientation) {
139726         if (!_validateOrientation(orientation)) {
139727             exception.raise(exception.types.OrientationType, "unknown orientation type requested!");
139728         }
139729
139730         db.save("deviceOrientation", orientation);
139731         jQuery('#device-layout').css('-webkit-transform-origin', '0% 0%');
139732         jQuery('#device-layout').css('-webkit-transform',
139733                 _getTransformString(orientation, db.retrieve("deviceScaleFactor")));
139734         _upDateHWKeyPanelPosition(orientation, db.retrieve("deviceScaleFactor"))
139735         if (!_win) return;
139736         if (_win.onorientationchange) {
139737             _win.onorientationchange();
139738         }
139739
139740         var evt = _doc.createEvent("Event");
139741         evt.initEvent("orientationchange", true, true);
139742         _win.dispatchEvent(evt);
139743     }
139744 };
139745
139746 module.exports = _self;
139747
139748 });
139749 define('ripple/sensorSettings', function (require, exports, module) {
139750 /*
139751  *  Copyright 2012 Intel Corporation.
139752  *
139753  * Licensed under the Apache License, Version 2.0 (the "License");
139754  * you may not use this file except in compliance with the License.
139755  * You may obtain a copy of the License at
139756  *
139757  * http://www.apache.org/licenses/LICENSE-2.0
139758  *
139759  * Unless required by applicable law or agreed to in writing, software
139760  * distributed under the License is distributed on an "AS IS" BASIS,
139761  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139762  * See the License for the specific language governing permissions and
139763  * limitations under the License.
139764  */
139765 var _PERSISTENCE_KEY = "sensorsettings",
139766     db = require('ripple/db'),
139767     platform = require('ripple/platform'),
139768     _currentSensorSettings = {},
139769     _self;
139770
139771 function _default(key) {
139772     var keys = key.split("."),
139773         defaults = platform.current().sensor;
139774
139775     if (keys.length === 1)
139776         return defaults[key];
139777
139778     return keys.length === 2 &&
139779            defaults[keys[0]] &&
139780            defaults[keys[0]][keys[1]] &&
139781            defaults[keys[0]][keys[1]].control ?
139782            defaults[keys[0]][keys[1]].control.value : undefined;
139783 }
139784
139785 _self = {
139786     initialize: function () {
139787         _currentSensorSettings = db.retrieveObject(_PERSISTENCE_KEY) || {};
139788     },
139789     register: function (key, obj) {
139790         _currentSensorSettings[key] = obj;
139791     },
139792
139793     persist: function (key, obj) {
139794         if (key) {
139795             _currentSensorSettings[key] = obj;
139796         }
139797
139798         db.saveObject(_PERSISTENCE_KEY, _currentSensorSettings);
139799     },
139800
139801     retrieve: function (key) {
139802         return _currentSensorSettings.hasOwnProperty(key) ?
139803                _currentSensorSettings[key] : _default(key);
139804     },
139805
139806     retrieveAsInt: function (key) {
139807         return parseInt(_self.retrieve(key), 10);
139808     },
139809
139810     retrieveAsBoolean: function (key) {
139811         return !!_self.retrieve(key);
139812     }
139813 };
139814
139815 module.exports = _self;
139816
139817 });
139818 define('ripple/touchEventEmulator', function (require, exports, module) {
139819 /*
139820  *  Copyright 2011 Research In Motion Limited.
139821  *
139822  * Licensed under the Apache License, Version 2.0 (the "License");
139823  * you may not use this file except in compliance with the License.
139824  * You may obtain a copy of the License at
139825  *
139826  * http://www.apache.org/licenses/LICENSE-2.0
139827  *
139828  * Unless required by applicable law or agreed to in writing, software
139829  * distributed under the License is distributed on an "AS IS" BASIS,
139830  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139831  * See the License for the specific language governing permissions and
139832  * limitations under the License.
139833  */
139834 var emulatorBridge = require('ripple/emulatorBridge'),
139835     utils = require('ripple/utils'),
139836     _isMouseDown, self;
139837
139838 // NOTE: missing view, detail, touches, targetTouches, scale and rotation
139839 function _initTouchEvent(type, canBubble, cancelable, eventData) {
139840     var touchEvent = emulatorBridge.document().createEvent("Event");
139841     touchEvent.initEvent(type, canBubble, cancelable);
139842     utils.mixin(eventData, touchEvent);
139843     return touchEvent;
139844 }
139845
139846 function _raiseTouchEvent(mouseEvent) {
139847     var type = "",
139848         simulatedEvent,
139849         touchObj,
139850         eventData;
139851
139852     switch (mouseEvent.type) {
139853     case "mousedown":
139854         type = "touchstart";
139855         _isMouseDown = true;
139856         break;
139857     case "mousemove":
139858         if (!_isMouseDown) {
139859             return;
139860         }
139861         type = "touchmove";
139862         break;
139863     case "mouseup":
139864         type = "touchend";
139865         _isMouseDown = false;
139866         break;
139867     default:
139868         return;
139869     }
139870
139871     touchObj = {
139872         clientX: mouseEvent.pageX,
139873         clientY: mouseEvent.pageY,
139874         identifier: "",
139875         pageX: mouseEvent.pageX,
139876         pageY: mouseEvent.pageY,
139877         screenX: mouseEvent.pageX,
139878         screenY: mouseEvent.pageY,
139879         target: mouseEvent.target
139880     };
139881
139882     eventData = {
139883         altKey: mouseEvent.altKey,
139884         ctrlKey: mouseEvent.ctrlKey,
139885         shiftKey: mouseEvent.shiftKey,
139886         metaKey: mouseEvent.metaKey,
139887         changedTouches: [touchObj],
139888         targetTouches: [touchObj],
139889         touches: [touchObj]
139890     };
139891
139892     utils.mixin(touchObj, eventData);
139893
139894     simulatedEvent = _initTouchEvent(type, true, true, eventData);
139895
139896     mouseEvent.target.dispatchEvent(simulatedEvent);
139897
139898     if (typeof mouseEvent.target["on" + type] === "function") {
139899         mouseEvent.target["on" + type].apply(mouseEvent.target, [simulatedEvent]);
139900     }
139901 }
139902
139903 function _marshalEvents(win, doc) {
139904     utils.forEach(["mousedown", "mousemove", "mouseup"],
139905         function (event) {
139906             doc.addEventListener(event, _raiseTouchEvent, true);
139907         });
139908
139909     //win.Node.prototype.ontouchstart = null;
139910     //win.Node.prototype.ontouchend = null;
139911     //win.Node.prototype.ontouchmove = null;
139912 }
139913
139914 self = module.exports = {
139915     mask: function (win, doc) {
139916         _marshalEvents(win, doc);
139917     }
139918 };
139919
139920 });
139921 define('ripple/ui/plugins/HWKeys', function (require, exports, module) {
139922 /*
139923  *  Copyright 2012 Intel Corporation
139924  *
139925  * Licensed under the Apache License, Version 2.0 (the "License");
139926  * you may not use this file except in compliance with the License.
139927  * You may obtain a copy of the License at
139928  *
139929  * http://www.apache.org/licenses/LICENSE-2.0
139930  *
139931  * Unless required by applicable law or agreed to in writing, software
139932  * distributed under the License is distributed on an "AS IS" BASIS,
139933  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139934  * See the License for the specific language governing permissions and
139935  * limitations under the License.
139936  */
139937
139938 var db = require('ripple/db'),
139939     event = require('ripple/event');
139940
139941
139942 function initHWKey() {
139943     var left = 0,
139944         orientation = db.retrieve('deviceOrientation'),
139945         scaleFactor = db.retrieve('deviceScaleFactor');
139946
139947     if (orientation === 'portrait') {
139948         if (db.retrieve("layout") === "portrait") {
139949             left = 350 + $('#device-layout').width()*scaleFactor;
139950         } else {
139951             left = 470 + $('#device-layout').height()*scaleFactor;
139952         }
139953     } else {
139954         if (db.retrieve("layout") === "portrait") {
139955             left = 490 + $('#device-layout').height()*scaleFactor;
139956         } else {
139957             left = 350 + $('#device-layout').width()*scaleFactor;
139958         }
139959     }
139960
139961     $("#hwkeys-panel").css("top", "40px");
139962     $("#hwkeys-panel").css("left", left+"px");
139963     $("#hwkeys-panel").draggable({ cursor: 'move', containment: [0, 52, 1480, 800]});
139964
139965     jQuery("#hwkey-menu-btn").bind("click", function () {
139966         event.trigger("tizenhwkeyEvent", ["menu"], true);
139967     });
139968     jQuery("#hwkey-back-btn").bind("click", function () {
139969         event.trigger("tizenhwkeyEvent", ["back"], true);
139970     });
139971 }
139972
139973 module.exports = {
139974     initialize: function () {
139975         initHWKey();
139976     }
139977 };
139978
139979 });
139980 define('ripple/ui/plugins/about-dialog', function (require, exports, module) {
139981 /*
139982  *  Copyright 2011 Research In Motion Limited.
139983  *
139984  * Licensed under the Apache License, Version 2.0 (the "License");
139985  * you may not use this file except in compliance with the License.
139986  * You may obtain a copy of the License at
139987  *
139988  * http://www.apache.org/licenses/LICENSE-2.0
139989  *
139990  * Unless required by applicable law or agreed to in writing, software
139991  * distributed under the License is distributed on an "AS IS" BASIS,
139992  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139993  * See the License for the specific language governing permissions and
139994  * limitations under the License.
139995  */
139996 var bus = require('ripple/bus');
139997
139998 module.exports = {
139999     initialize: function () {
140000         $("#about-dialog").dialog({
140001             resizable: false,
140002             draggable: false,
140003             modal: true,
140004             autoOpen: false,
140005             position: 'center',
140006             minWidth: '464',
140007             minHeight: '262'
140008         });
140009     },
140010     show: function () {
140011         //TODO: Restore this line once framework issue is resolved
140012         //var port =  window.stagewebview ? stagewebview.serverPort : "9900";
140013         var port = "9910";
140014
140015         bus.send("version", null, function (resp) {
140016             $("#about-dialog-ripple-ui-version").html("(v" + resp + ")");
140017         });
140018
140019         bus.ajax(
140020             "GET",
140021             "http://127.0.0.1:" + port + "/ripple/about",
140022             null,
140023             function (resp) {
140024                 $("#about-dialog-ripple-build-deploy-version").html("(v" + resp.data.version + ")");
140025             },
140026             function (error) {
140027                 var version = error.data;
140028                 
140029                 if (error.code === 0 || error.code === 404) {
140030                     version = "The service is not running";
140031                 }
140032                 $("#about-dialog-ripple-build-deploy-version").html("(" + version + ")");
140033             }
140034         );
140035
140036         $("#about-dialog").dialog("open");
140037     }
140038 };
140039
140040 });
140041 define('ripple/ui/plugins/accelerometer', function (require, exports, module) {
140042 /*
140043  * Copyright (c) 2010 Epic Train Hack
140044  * Copyright (c) 2011 Research In Motion Limited
140045  * Contributors: Wolfram Kriesing, Dan Silivestru, Brent Lintner
140046  *
140047  * 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:
140048  *
140049  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
140050  *
140051  * 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.
140052  */
140053 var ui = require('ripple/ui'),
140054     goodVibrations = require('ripple/ui/plugins/goodVibrations'),
140055     accelerometer = require('ripple/accelerometer'),
140056     event = require('ripple/event'),
140057     Rotation = require('ripple/platform/w3c/1.0/Rotation'),
140058     Acceleration = require('ripple/platform/w3c/1.0/Acceleration'),
140059     _mouseDown,
140060     _shiftKeyDown,
140061     _offsets = {
140062         x: 0,
140063         y: 0,
140064         z: -9.81,
140065     },
140066     _oldX,
140067     _oldY,
140068     _oldAlphaX,
140069     _shape =
140070         //
140071         // The front side
140072         //
140073         // x, y, z      x, y, z         x, y, z
140074         // for some strange reason for y -100 is top, 100 is bottom
140075         "-30,30,10,     30,30,10,       30,60,10,       100,100,100,-1,0;" + // top left, top right, bottom right - of the right triangle
140076         "-30,30,10,     30,60,10,       -30,60,10,      100,100,100,-1,0;" + // top left, right bottom, left bottom - of the left triangle
140077         // front side "the phone display"
140078         "-20,-50,11,    20,-50,11,      20,20,11,       100,100,100,-1,0;" +
140079         "-20,-50,11,    20,20,11,       -20,20,11,      100,100,100,-1,0;" +
140080         // below the display
140081         "-30,30,10,     30,20,10,       30,30,10,       0,0,0,-1,0;" +
140082         "-30,30,10,     -30,20,10,      30,20,10,       0,0,0,-1,0;" +
140083         // above the display
140084         "-30,-60,10,    30,-60,10,      30,-50,10,      0,0,0,-1,0;" +
140085         "-30,-60,10,    30,-50,10,      -30,-50,10,     0,0,0,-1,0;" +
140086         // left of the display
140087         "-30,-50,10,    -20,-50,10,     -20,20,10,      0,0,0,-1,0;" +
140088         "-30,-50,10,    -20,20,10,      -30,20,10,      0,0,0,-1,0;" +
140089         // right of the display
140090         "20,-50,10,     30,-50,10,      30,20,10,       0,0,0,-1,0;" +
140091         "20,-50,10,     30,20,10,       20,20,10,       0,0,0,-1,0;" +
140092
140093
140094         // back side, opposite side to the above one
140095         "-30,-60,-10,   30,60,-10,      30,-60,-10,     0,0,0,-1,0;" +
140096         "-30,-60,-10,   -30,60,-10,     30,60,-10,      0,00,-1,0;" +
140097         // right side
140098         "30,-60,-10,    30,60,-10,      30,60,10,       50,50,80,-1,0;" +
140099         "30,-60,-10,    30,60,10,       30,-60,10,      50,50,80,-1,0;" +
140100         // left side
140101         "-30,-60,-10,   -30,60,10,      -30,60,-10,     50,50,80,-1,0;" +
140102         "-30,-60,-10,   -30,-60,10,     -30,60,10,      50,50,80,-1,0;" +
140103
140104         // top
140105         "30,-60,-10,    -30,-60,10, -30,-60,-10,    50,80,50,-1,0;" +
140106         "30,-60,-10,    30,-60,10,      -30,-60,10, 50,80,50,-1,0;" +
140107         // bottom
140108         "30,60,-10, -30,60,-10,     -30,60,10,      80,50,50,-1,0;" +
140109         "30,60,-10, -30,60,10,      30,60,10,       80,50,50,-1,0";
140110
140111 function _shakeDevice() {
140112     window.setTimeout(goodVibrations.shakeDevice(8), 1);
140113     accelerometer.shake();
140114 }
140115
140116 function _updateAccelerometerPanel(motion) {
140117     jQuery("#accelerometer-x").html(Math.round(motion.accelerationIncludingGravity.x * 100) / 100);
140118     jQuery("#accelerometer-y").html(Math.round(motion.accelerationIncludingGravity.y * 100) / 100);
140119     jQuery("#accelerometer-z").html(Math.round(motion.accelerationIncludingGravity.z * 100) / 100);
140120     jQuery("#accelerometer-alpha").html(Math.round(motion.orientation.alpha));
140121     jQuery("#accelerometer-beta").html(Math.round(motion.orientation.beta));
140122     jQuery("#accelerometer-gamma").html(Math.round(motion.orientation.gamma));
140123 }
140124
140125 function _updateCanvas(a, b, g) {
140126     ThreeDee.loadMesh(_shape);
140127     g = g || 0;
140128     ThreeDee.rotate(0, g, 0);
140129     ThreeDee.rotate(b, 0, a);
140130     ThreeDee.backface();
140131     ThreeDee.shade();
140132     ThreeDee.zSort();
140133     Draw.initialize(document.querySelector("#accelerometer-canvas"));
140134     Draw.clear(0, 0, 480, 300);
140135     Draw.drawScene(ThreeDee.getTranslation(), 3);
140136 }
140137
140138 function _createCanvas() {
140139     var node = document.querySelector("#accelerometer-canvas"),
140140         x = 0, y = 0, z = -9.81,
140141         alpha = 0, beta = 0, gamma = 0,
140142         cosX, sinX, cosY, sinY,
140143         deltaAlpha = 360;
140144
140145     ThreeDee.setCenter(150, 100);
140146     ThreeDee.setLight(-300, -300, 800);
140147
140148     node.addEventListener("mousemove", function (e) {
140149         if (!_mouseDown)
140150             return;
140151
140152         if (!_shiftKeyDown) {
140153             _offsets.x = (_offsets.x + _oldX - e.offsetX) % 360;
140154             _offsets.y = (_offsets.y + _oldY - e.offsetY) % 360;
140155
140156             alpha = alpha || 0;
140157
140158             // enforce gamma in [-90,90] as per w3c spec
140159             gamma = -_offsets.x;
140160             if (gamma < -90) {
140161                 gamma = -90;
140162             }
140163             if (gamma > 90) {
140164                 gamma = 90;
140165             }
140166
140167             // enforce beta in [-180,180] as per w3c spec
140168             beta = -_offsets.y % 360;
140169             if (beta < -180) {
140170                 beta += 360;
140171             }
140172             else if (beta >= 180) {
140173                 beta -= 360;
140174             }
140175
140176             cosX = Math.cos((gamma) * (Math.PI / 180));
140177             sinX = Math.sin((gamma) * (Math.PI / 180));
140178             cosY = Math.cos((beta) * (Math.PI / 180));
140179             sinY = Math.sin((beta) * (Math.PI / 180));
140180             x = 9.81 * cosY * sinX;
140181             y = -9.81 * sinY;
140182             z = -9.81 * cosY * cosX;
140183
140184         }
140185         else {
140186             deltaAlpha = (deltaAlpha - (_oldAlphaX - e.offsetX) * 2.5) % 360;
140187             alpha = (360 - deltaAlpha) % 360;
140188         }
140189
140190         _oldX = e.offsetX;
140191         _oldY = e.offsetY;
140192         _oldAlphaX = e.offsetX;
140193
140194         _updateCanvas(deltaAlpha, -beta, gamma);
140195         accelerometer.setInfo({
140196             x: x,
140197             y: y,
140198             z: z,
140199             alpha: alpha,
140200             beta: beta,
140201             gamma: gamma
140202         });
140203
140204     });
140205
140206     node.addEventListener("mousedown", function (e) {
140207         _oldX = e.offsetX;
140208         _oldY = e.offsetY;
140209         if (_shiftKeyDown) {
140210             _oldAlphaX = _oldX;
140211         }
140212         _mouseDown = true;
140213     });
140214
140215     node.addEventListener("mouseup", function (e) {
140216         _mouseDown = false;
140217     });
140218
140219     node.addEventListener("dblclick", function (e) {   
140220         x = 0;
140221         y = 0;
140222         z = -9.81;
140223         alpha = 0;
140224         beta = 0;
140225         gamma = 0;
140226         deltaAlpha = 360;
140227         _resetAccelerometer();
140228     });
140229
140230     document.addEventListener("mouseup", function (e) {
140231         //Catch mouseup events that fire when outside canvas bounds
140232         _mouseDown = false;
140233     });
140234
140235     document.addEventListener("keydown", function (e) {
140236         if (e.keyCode === 16) { // Shift Key            
140237             _shiftKeyDown = true;
140238         }
140239     });
140240
140241     document.addEventListener("keyup", function (e) {
140242         if (e.keyCode === 16) { // Shift Key
140243             _shiftKeyDown = false;
140244         }
140245     });    
140246 }
140247
140248 function _resetAccelerometer() {    
140249     _updateCanvas(0, 0);
140250     _oldX = 0;
140251     _oldY = 0;
140252     _oldAlphaX = 0;
140253     _offsets = {
140254         x: 0,
140255         y: 0,
140256         z: -9.81,
140257     };
140258     accelerometer.setInfo({
140259         acceleration: new Acceleration(0, 0, 0),
140260         accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
140261         rotationRate: new Rotation(0, 0, 0),
140262         orientation: new Rotation(0, 0, 0),
140263         timestamp: new Date().getTime()
140264     });
140265 }
140266
140267 module.exports = {
140268     panel: {
140269         domId: "accelerometer-container",
140270         collapsed: true,
140271         pane: "left",
140272         titleName: "Accelerometer",
140273         display: true
140274     },
140275     initialize: function () {
140276         _createCanvas();
140277         
140278         _resetAccelerometer();
140279
140280         _updateAccelerometerPanel(accelerometer.getInfo());
140281
140282         jQuery("#accelerometer-shake").click(_shakeDevice);
140283
140284         event.on("AccelerometerInfoChangedEvent", _updateAccelerometerPanel, this);
140285     }
140286 };
140287
140288 });
140289 define('ripple/ui/plugins/application', function (require, exports, module) {
140290 /*
140291  *  Copyright 2012 Intel Corporation.
140292  *
140293  * Licensed under the Apache License, Version 2.0 (the "License");
140294  * you may not use this file except in compliance with the License.
140295  * You may obtain a copy of the License at
140296  *
140297  * http://www.apache.org/licenses/LICENSE-2.0
140298  *
140299  * Unless required by applicable law or agreed to in writing, software
140300  * distributed under the License is distributed on an "AS IS" BASIS,
140301  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140302  * See the License for the specific language governing permissions and
140303  * limitations under the License.
140304  */
140305
140306 var event = require('ripple/event'),
140307     utils = require('ripple/utils'),
140308     db = require('ripple/db'),
140309     dbinit = require('ripple/platform/tizen/2.0/dbinit'),
140310     DB_APPLICATION_KEY = "tizen1-db-application",
140311     _data = {
140312         appList: {},
140313         installedAppList: {}
140314     },
140315     _appInstalledTemplate,
140316     _apps,
140317     _installedAppList;
140318
140319 function _get() {
140320     _data = db.retrieveObject(DB_APPLICATION_KEY);
140321     if (_data === undefined) {
140322         _data = {
140323             appList: _apps,
140324             installedAppList: _installedAppList
140325         };
140326     }
140327 }
140328
140329 function _save() {
140330     db.saveObject(DB_APPLICATION_KEY, _data);
140331 }
140332
140333 function _loadInstalledAppList() {
140334     var html = "";
140335     jQuery("#application-installed-box").empty();
140336     utils.forEach(_data.installedAppList, function (item) {
140337         html += _appInstalledTemplate.replace(/#Name/g, item.name)
140338             .replace(/#ID/g, item.id)
140339             .replace(/#IconPath/, item.iconPath)
140340             .replace(/#Version/, item.version)
140341             .replace(/#Show/, item.show)
140342             .replace(/#Categories/, item.categories.join("<br>"))
140343             .replace(/#InstallDate/, item.installDate)
140344             .replace(/#Size/, item.size)
140345             .replace(/#PackageID/, item.packageId)
140346             .replace(/#SharedURI/, item.sharedURI)
140347             .replace(/#Operation/, item.operation)
140348             .replace(/#URI/, item.appControl.uri)
140349             .replace(/#MIME/, item.appControl.mime)
140350             .replace(/#category/, item.appControl.category)
140351             .replace(/#Data/, item.appControl.data);
140352     });
140353     jQuery("#application-installed-box").accordion("destroy");
140354     jQuery("#application-installed-box").html(html).accordion({
140355         active: false,
140356         collapsible: true,
140357         autoHeight: false
140358     });
140359 }
140360
140361 function _displayInfo(text) {
140362     var html = "<b>" + text + "</b>";
140363     document.getElementById("application-error").innerHTML = html;
140364 }
140365
140366 function _programChanged(status, id) {
140367     event.trigger("programChanged", [status, id]);
140368 }
140369
140370 function updateApp(id, updateFlag) {
140371     var item = _data.appList[id];
140372     if (!item) {
140373         return;
140374     }
140375     _data.installedAppList[id] = {
140376         id: item.id,
140377         name: item.name,
140378         iconPath: item.iconPath,
140379         version: item.version,
140380         show: item.show,
140381         categories: item.categories,
140382         installDate: new Date(),
140383         size: item.size,
140384         packageId: item.packageId,
140385         sharedURI: item.sharedURI,
140386         operation: item.operation,
140387         appControl: {
140388             uri: item.appControl.uri,
140389             mime: item.appControl.mime,
140390             category: item.appControl.category,
140391             data: item.appControl.data
140392         },
140393         type: item.type,
140394         value: item.value
140395     };
140396     _save();
140397     if (updateFlag) {
140398         _programChanged("updated", id);
140399     } else {
140400         _programChanged("installed", id);
140401     }
140402     _loadInstalledAppList();
140403 }
140404
140405 function removeApp(id) {
140406     delete _data.installedAppList[id];
140407     _save();
140408     _programChanged("uninstalled", id);
140409     _loadInstalledAppList();
140410 }
140411
140412 event.on("install-current-app", function (item) {
140413     _data.installedAppList[item.id] = {
140414         id: item.id,
140415         name: item.name,
140416         iconPath: item.iconPath,
140417         version: item.version,
140418         show: item.show,
140419         categories: item.categories,
140420         installDate: item.installDate,
140421         size: item.size,
140422         packageId: item.packageId,
140423         sharedURI: item.sharedURI,
140424         operation: item.operation,
140425         appControl: {
140426             uri: item.appControl.uri,
140427             mime: item.appControl.mime,
140428             category: item.appControl.category,
140429             data: item.appControl.data
140430         },
140431         type: item.type,
140432         value: item.value
140433     };
140434     _loadInstalledAppList();
140435 });
140436
140437 event.on("appServiceReplied", function () {
140438     _displayInfo("The application has been launched successfully");
140439 });
140440
140441 event.on("install-apps", function (ids) {
140442     utils.forEach(ids, function (id) {
140443         updateApp(id, false);
140444     });
140445 });
140446
140447 event.on("update-apps", function (ids) {
140448     utils.forEach(ids, function (id) {
140449         updateApp(id, true);
140450     });
140451 });
140452
140453 event.on("remove-apps", function (ids) {
140454     utils.forEach(ids, function (id) {
140455         removeApp(id);
140456     });
140457 });
140458
140459 module.exports = {
140460     initialize: function () {
140461         _apps = dbinit.Application.apps;
140462         _installedAppList = dbinit.Application.installedAppList;
140463         _appInstalledTemplate = jQuery("#application-installed-template").html();
140464         _get();
140465         _save();
140466         _loadInstalledAppList();
140467     }
140468 };
140469
140470 });
140471 define('ripple/ui/plugins/audioPlayer', function (require, exports, module) {
140472 /*
140473  *  Copyright 2011 Research In Motion Limited.
140474  *
140475  * Licensed under the Apache License, Version 2.0 (the "License");
140476  * you may not use this file except in compliance with the License.
140477  * You may obtain a copy of the License at
140478  *
140479  * http://www.apache.org/licenses/LICENSE-2.0
140480  *
140481  * Unless required by applicable law or agreed to in writing, software
140482  * distributed under the License is distributed on an "AS IS" BASIS,
140483  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140484  * See the License for the specific language governing permissions and
140485  * limitations under the License.
140486  */
140487 var event = require('ripple/event'),
140488     constants = require('ripple/constants'),
140489     audioObj = document.getElementById("multimedia-audio"),
140490     audioProgress = document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PROGRESS_ID);
140491
140492 module.exports = {
140493     initialize: function () {
140494         var audioObj = document.getElementById("multimedia-audio"),
140495             audioProgress = document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PROGRESS_ID);
140496
140497         if (audioObj) {
140498             event.on("MultimediaVolumeChanged", function (volume) {
140499                 audioObj.volume = parseFloat(volume / 10);
140500             });
140501
140502             audioObj.addEventListener("timeupdate", function () {
140503                 var s = parseInt(audioObj.currentTime % 60, 10),
140504                     m = parseInt((audioObj.currentTime / 60) % 60, 10);
140505
140506                 audioProgress.innerText = ((m > 9) ? m  : "0" + m) + ':' + ((s > 9) ? s  : "0" + s);
140507             }, false);
140508
140509             event.on("MultimediaAudioStateChanged", function (state) {
140510                 document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_STATE_FIELD_ID).innerText = state;
140511                 document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_FILE_FIELD_ID).innerText = audioObj.getAttribute("src");
140512             });
140513         }
140514     }
140515 };
140516
140517 });
140518 define('ripple/ui/plugins/build', function (require, exports, module) {
140519 /*
140520  *  Copyright 2011 Research In Motion Limited.
140521  *
140522  * Licensed under the Apache License, Version 2.0 (the "License");
140523  * you may not use this file except in compliance with the License.
140524  * You may obtain a copy of the License at
140525  *
140526  * http://www.apache.org/licenses/LICENSE-2.0
140527  *
140528  * Unless required by applicable law or agreed to in writing, software
140529  * distributed under the License is distributed on an "AS IS" BASIS,
140530  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140531  * See the License for the specific language governing permissions and
140532  * limitations under the License.
140533  */
140534 var tooltip = require('ripple/ui/plugins/tooltip'),
140535     settings = require('ripple/ui/plugins/settings-dialog'),
140536     bus = require('ripple/bus');
140537
140538 function handleBuild() {
140539     var node = $(this),
140540         action = node.attr('id').split("-")[2];
140541
140542     if (node.hasClass("not-ready")) {
140543         return;
140544     }
140545
140546     if (!settings.can(action)) {
140547         settings.show(action);
140548     }
140549     else {
140550         settings.perform(action);
140551     }
140552 }
140553
140554 function areServicesRunning(success, fail) {
140555     bus.ajax(
140556         "GET",
140557         "http://127.0.0.1:9910/ripple/about",
140558         null,
140559         function () {
140560             success();
140561         },
140562         function (error) {
140563             fail();
140564         }
140565     );
140566 }
140567
140568 function manageServices(action, callBack) {
140569     bus.send("services", action, function () {
140570         if (typeof callBack === "function") {
140571             callBack();
140572         }
140573     });
140574 }
140575
140576 module.exports = {
140577     panel: {
140578         domId: "build-container",
140579         collapsed: true,
140580         pane: "right"
140581     },
140582
140583     initialize: function () {
140584         $("#options-menu-build").click(handleBuild);
140585         $("#options-menu-sign").click(handleBuild);
140586         $("#options-menu-launch").click(handleBuild);
140587
140588         $('#options-menu-start-service').click(function () {
140589             manageServices("start", function (result) {
140590                 $('#options-menu-services-stop').show();
140591                 $('#options-menu-services-start').hide();
140592             });
140593         });
140594
140595         $('#options-menu-stop-service').click(function () {
140596             manageServices("stop", function (result) {
140597                 $('#options-menu-services-stop').hide();
140598                 $('#options-menu-services-start').show();
140599             });
140600         });
140601
140602         $("#options-menu-settings").click(function () {
140603             settings.show(); 
140604         });
140605
140606         if (settings.value("remoteInspector")) {
140607             $("#options-menu-build-warning").show();
140608             tooltip.create("#options-menu-build-warning", "Remote Web Inspector should be disabled when packaging for App World release");
140609         }
140610
140611         areServicesRunning(
140612             function () {
140613                 $('#options-menu-services-stop').show();
140614                 $('#options-menu-services-start').hide();
140615             }, 
140616             function () {
140617                 $('#options-menu-services-stop').hide();
140618                 $('#options-menu-services-start').show();
140619             }
140620         );
140621     }
140622 };
140623
140624 });
140625 define('ripple/ui/plugins/call', function (require, exports, module) {
140626 /*
140627  *  Copyright 2012 Intel Corporation
140628  *
140629  * Licensed under the Apache License, Version 2.0 (the "License");
140630  * you may not use this file except in compliance with the License.
140631  * You may obtain a copy of the License at
140632  *
140633  * http://www.apache.org/licenses/LICENSE-2.0
140634  *
140635  * Unless required by applicable law or agreed to in writing, software
140636  * distributed under the License is distributed on an "AS IS" BASIS,
140637  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140638  * See the License for the specific language governing permissions and
140639  * limitations under the License.
140640  */
140641 var event = require('ripple/event'),
140642     utils = require('ripple/utils'),
140643     db = require('ripple/db'),
140644     _exception = {
140645         "unknown":           "Unknown",
140646         "network":           "Network",
140647         "unreachable":       "Unreachable",
140648         "no-answer":         "No Answer",
140649         "bad-number":        "Bad Number",
140650         "number-not-in-use": "Number Not In Use",
140651         "media":             "Media",
140652         "no-sim":            "No Sim Card",
140653         "account-down":      "Account Down",
140654         "credit-down":       "Credit Down",
140655         "barred":            "Barred",
140656         "network-busy":      "Network Busy",
140657         "network-down":      "Network Down"
140658     },
140659     _status = {
140660         IDLE:       0,
140661         DIALED:     1,
140662         PLACED:     2,
140663         INPROGRESS: 3,
140664     },
140665     _statusInfo = [
140666         "Waiting...;Waiting",                                   // IDLE
140667         "Calling... ;Incomming call from simulator",               // DIALED
140668         "Incomming call from ;Calling simulator",                // PLACED
140669         "In conversation with ;In conversation with simulator"   // INPROGRESS
140670     ],
140671     _data = {
140672         status: _status.IDLE,
140673         isInException: false,
140674         isAutoAccept: false,
140675         autoAcceptTimerId: null,
140676         conversationStartTime: null
140677     },
140678     _contactMap = {
140679         "861012345678": "Guest"
140680     },
140681     _CONTACT_KEY = "tizen1-contact",
140682     _RECORDING_KEY = "tizen1-call-recording",
140683     _RECORDING_PATH = "music/",
140684     _record = {},
140685     _conversationSeconds = 0,
140686     _conversationTimer,
140687     _callingEffectTimer;
140688
140689 function _initContacts() {
140690     var data = db.retrieveObject(_CONTACT_KEY),
140691         contactsSelect = document.getElementById("call-local-phone-number"),
140692         displayName = null, number = null, index = 0, i;
140693         
140694     contactsSelect.innerHTML = "";
140695
140696     utils.forEach(data, function (addrBook) {
140697         utils.forEach(addrBook._contacts, function (contact) {
140698             if (contact.name && contact.name && contact.phoneNumbers &&
140699                 contact.phoneNumbers.length > 0) {
140700                 displayName = contact.name.firstName + ' ' + contact.name.lastName;
140701                 number = contact.phoneNumbers[0].number;
140702                 _contactMap[number] = displayName;
140703
140704                 contactsSelect.appendChild(utils.createElement("option", {
140705                     "innerText": displayName + ':' + number,
140706                     "value": index
140707                 }));
140708                 index++;
140709             }
140710         });
140711     });
140712
140713     if (displayName === null && number === null) {
140714         for (i in _contactMap) {
140715             displayName = _contactMap[i];
140716             number = i;
140717             contactsSelect.appendChild(utils.createElement("option", {
140718                 "innerText": displayName + ':' + number,
140719                 "value": index
140720             }));
140721         }
140722     }
140723 }
140724
140725 function _initEventWatchers() {
140726     event.on("DialerLaunched", function (remoteParty) {
140727         var localContact = document.getElementById("call-local-phone-number");
140728
140729         if (_data.status !== _status.IDLE) {
140730             return;
140731         }
140732
140733         localContact.appendChild(utils.createElement("option", {
140734             "innerText": remoteParty.displayName,
140735             "value": remoteParty.remoteParty,
140736             "selected": "selected"
140737         }));
140738         _localCall();
140739     });
140740 }
140741
140742 function _initExceptionTypes() {
140743     utils.forEach(_exception, function (value, key) {
140744         document.getElementById("call-exception-type").appendChild(utils.createElement("option", {
140745             "innerText": value,
140746             "value": key
140747         }));
140748     });
140749 }
140750
140751 function _initRecord() {
140752     var localPartString = jQuery("#call-local-phone-number option:selected").text() || "",
140753         localPartStringList = localPartString.split(":"),
140754         displayName;
140755
140756     if (localPartStringList.length > 1) {
140757         displayName = localPartStringList[0];
140758     }
140759     else {
140760         displayName = localPartString;
140761     }
140762
140763     _record = {};
140764     _record.serviceId = (new Date()).getTime() || 0;
140765     _record.callParticipants = [{
140766         id: localPartString + ':' + displayName,
140767         displayName: displayName,
140768         contactRef: null
140769     }];
140770     _record.forwardedFrom = null;
140771     _record.startTime = new Date();
140772     _record.recording = [];
140773 }
140774
140775
140776 function updateConvTime() {
140777     var timeObj = new Date(1970, 0, 1),
140778     timeString;
140779
140780     timeObj.setSeconds(_conversationSeconds);
140781     timeString = timeObj.toTimeString().substr(0, 8);
140782     jQuery("#ConvTimeString").text(timeString);
140783     jQuery("#ConvTimeString2").text(timeString);
140784     _conversationSeconds = _conversationSeconds + 1;
140785 }
140786
140787
140788 function CallingEffect() {
140789     var color = jQuery("#callingString").css('color');
140790     if (color === "rgb(255, 255, 255)") {
140791         jQuery("#callingString").css('color', "black");
140792         jQuery("#callingString2").css('color', "black");
140793     }
140794     else {
140795         jQuery("#callingString").css('color', "white");
140796         jQuery("#callingString2").css('color', "white");
140797     }
140798 }
140799
140800
140801 function _transferStatus() {
140802     var statusStringList = _statusInfo[_data.status].split(";"),
140803         localPartString = jQuery("#call-local-phone-number option:selected").text() || "",
140804         localPartStringList = localPartString.split(":"),
140805         localNumber = localPartStringList[0],
140806         localName = _contactMap[localNumber] || localNumber;
140807     jQuery("#status-text").show();
140808     jQuery("#remote-status-text").show();
140809     jQuery("#call-status").show();
140810     jQuery("#remote-call-status").show();
140811     jQuery("#remotePartyName").html(localName);
140812     jQuery("#call-local-call").show();
140813     window.clearInterval(_callingEffectTimer);
140814
140815     switch (_data.status) {
140816     case _status.DIALED:      // local call
140817         jQuery("#call-remote-text").html("Accept");
140818         jQuery("#end-remote-text").html("Reject");
140819         jQuery("#call-status").html("<span style='font-size: 22px;'>" + localName + "</span><br>" + 
140820                         "<span id='callingString' style='font-size: 14px;'>&nbsp;" + statusStringList[0] + 
140821                         "</span><br><br><br><button id='call-local-end-d' class='ui-corner-all' style='padding:2px;" +
140822                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
140823         jQuery("#call-local-end-d").bind("click", _localEnd);
140824         jQuery("#remote-call-status").html("<span style='font-size: 20px;'>Simulator Bot</span><br>" + 
140825                         "<span id='callingString2' style='font-size: 12px;'>&nbsp;Incoming call...</span>" +
140826                         "<br><br><br><button id='call-remote-decline-d' class='ui-corner-all' style='padding:2px;" +
140827                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:48%;'>Decline</button>&nbsp;&nbsp;" +
140828                         "<button id='call-remote-answer-d' class='ui-corner-all' style='padding:2px; border-width:1px; background-color:green; color:white; font-size:14px; font-weight:bold; width:48%;'>Answer</button>");
140829         jQuery("#call-remote-answer-d").bind("click", _remoteCall);
140830         jQuery("#call-remote-decline-d").bind("click", _remoteEnd);
140831         _callingEffectTimer = window.setInterval(CallingEffect, 800);
140832         break;
140833     case _status.PLACED:      // Remote Call
140834         jQuery("#call-local-text").html("Accept");
140835         jQuery("#end-local-text").html("Reject");
140836         jQuery("#call-status").html(statusStringList[0] + localName);
140837         jQuery("#remote-call-status").html(statusStringList[1]);
140838         jQuery("#remote-call-status").html("<span style='font-size: 22px;'>Simulator Bot</span><br>" + 
140839                         "<span id='callingString' style='font-size: 14px;'>&nbsp;Calling..." + 
140840                         "</span><br><br><br><button id='call-remote-end-d' class='ui-corner-all' style='padding:2px;" +
140841                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
140842         jQuery("#call-remote-end-d").bind("click", _remoteEnd);
140843         jQuery("#call-status").html("<span style='font-size: 22px;'>" + localName + "</span><br>" + 
140844                         "<span id='callingString2' style='font-size: 14px;'>&nbsp;Incoming call...</span>" +
140845                         "<br><br><br><button id='call-local-decline-d' class='ui-corner-all' style='padding:2px;" +
140846                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:48%;'>Decline</button>&nbsp;&nbsp;" +
140847                         "<button id='call-local-answer-d' class='ui-corner-all' style='padding:2px; border-width:1px;" +
140848                         " background-color:green; color:white; font-size:14px; font-weight:bold; width:48%;'>Answer</button>");
140849         jQuery("#call-local-answer-d").bind("click", _localCall);
140850         jQuery("#call-local-decline-d").bind("click", _localEnd);
140851         _callingEffectTimer = window.setInterval(CallingEffect, 800);
140852         break;
140853     case _status.INPROGRESS:
140854         jQuery("#call-status").html("<span style='font-size: 22px;'>" + localName + "</span><br>" + 
140855                         "<span id='ConvTimeString' style='font-size: 14px;'>" + "00:00:00" + 
140856                         "</span><br><br><br><button id='call-local-end-d-c' class='ui-corner-all' style='padding:2px;" +
140857                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
140858         jQuery("#remote-call-status").html("<span style='font-size: 22px;'>Simulator Robot</span><br>" + 
140859                         "<span id='ConvTimeString2' style='font-size: 14px;'>" + "00:00:00" + 
140860                         "</span><br><br><br><button id='call-remote-end-d-c' class='ui-corner-all' style='padding:2px;" +
140861                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
140862         jQuery("#call-local-end-d-c").bind("click", _localEnd);
140863         jQuery("#call-remote-end-d-c").bind("click", _remoteEnd);
140864         _conversationTimer = window.setInterval(updateConvTime, 1000);
140865         jQuery("#call-remote-text").html("Call");
140866         jQuery("#end-remote-text").html("End");
140867         jQuery("#call-local-text").html("Call");
140868         jQuery("#end-local-text").html("End");
140869         break;
140870     default:
140871         jQuery("#call-status").html(statusStringList[0]);
140872         jQuery("#call-status").html("default");
140873         jQuery("#remote-call-status").html(statusStringList[1]);
140874         jQuery("#remote-call-status").html("default");
140875         jQuery("#call-remote-text").html("Call");
140876         jQuery("#end-remote-text").html("End");
140877         jQuery("#call-local-text").html("Call");
140878         jQuery("#end-local-text").html("End");
140879         return;
140880     }
140881 }
140882
140883 function _startCall() {
140884     _data.conversationStartTime = new Date();
140885     event.trigger("CallInProgress", [true]);
140886     _data.status = _status.INPROGRESS;
140887     //_transferStatus();
140888 }
140889
140890 function _endCall(callEndReason) {
140891     if (_data.autoAcceptTimerId) {
140892         var path = _RECORDING_PATH + _record.serviceId + ".mp3";
140893
140894         _record.recording.push(path);
140895         db.saveObject(_RECORDING_KEY, path);
140896
140897         clearTimeout(_data.autoAcceptTimerId);
140898         _data.autoAcceptTimerId = null;
140899     }
140900
140901     _record.duration = _data.conversationStartTime ? ((new Date()) - _data.conversationStartTime) : 0;
140902     _data.conversationStartTime = null;
140903     
140904     _record.endReason = callEndReason;
140905
140906     if (_data.status === _status.PLACED) {
140907         _record.direction = "missed-new";
140908     }
140909
140910     event.trigger("CallRecorded", [_record]);
140911     event.trigger("CallInProgress", [false]);
140912
140913     _data.status = _status.IDLE;
140914     _transferStatus();
140915     _record = {};
140916
140917     _conversationSeconds = 0;
140918     window.clearInterval(_conversationTimer);
140919     jQuery("#call-status").hide();
140920     jQuery("#remote-call-status").hide();
140921
140922     jQuery("#status-text").hide();
140923     jQuery("#remote-status-text").hide();
140924 }
140925
140926 function _localCall() {
140927     if (_data.isInException) {
140928         return;
140929     }
140930
140931     switch (_data.status) {
140932     case _status.IDLE:    //local call
140933         _data.status = _status.DIALED;
140934         _initRecord();
140935         _record.direction = "dialed";
140936         break;
140937     case _status.PLACED:
140938         _data.status = _status.INPROGRESS;
140939         _record.direction = "received";
140940         if (_data.autoAcceptTimerId) {
140941             clearTimeout(_data.autoAcceptTimerId);
140942             _data.autoAcceptTimerId = null;
140943         }
140944         _startCall();
140945         break;
140946     default:
140947         return;
140948     }
140949
140950     _transferStatus();
140951
140952     if (_data.isInException) {
140953         _endCall(document.getElementById("call-exception-type").value);
140954     }
140955 }
140956
140957 function _localEnd() {
140958     switch (_data.status) {
140959     case _status.DIALED:     // Local Cancel
140960     case _status.INPROGRESS: // Local End
140961         _endCall("local");
140962         break;
140963     case _status.PLACED:
140964         _record.direction = "missed-new";
140965         _endCall("local");
140966         break;
140967     default:
140968         return;
140969     }
140970 }
140971
140972 function _remoteCall() {
140973     if (_data.isInException) {
140974         return;
140975     }
140976
140977     switch (_data.status) {
140978     case _status.IDLE:      // Remote Call
140979         _data.status = _status.PLACED; 
140980         _initRecord();
140981         if (_data.isAutoAccept) {
140982             _data.autoAcceptTimerId = setTimeout(_localCall, 2000);
140983         }
140984         break;
140985     case _status.DIALED:    // Remote Answer
140986         _startCall();
140987         break;
140988     default:
140989         return;
140990     }
140991
140992     _transferStatus();
140993
140994     if (_data.isInException) {
140995         _endCall(document.getElementById("call-exception-type").value);
140996     }
140997 }
140998
140999 function _remoteEnd() {
141000     switch (_data.status) {
141001     case _status.DIALED:     // Remote Reject
141002         _endCall("rejected");
141003         break;
141004     case _status.INPROGRESS: // Remote End
141005         _endCall("remote");
141006         break;
141007     case _status.PLACED:    // Remote Cancel
141008         _record.direction = "missed-new";
141009         _endCall("remote");
141010         break;
141011     default:
141012         return;
141013     }
141014 }
141015
141016 function _leaveMessage() {
141017     if (!this.checked && _data.autoAcceptTimerId) {
141018         clearTimeout(_data.autoAcceptTimerId);
141019         _data.autoAcceptTimerId = null;
141020     }
141021     _data.isAutoAccept = this.checked;
141022 }
141023
141024 function _exceptionStatus() {
141025     _data.isInException = this.checked;
141026     if (_data.isInException && (_data.status !== _status.IDLE)) {
141027         if (_data.status === _status.RECEIVED) {   // Remote Cancel
141028             _record.direction = "missed-new";
141029             _record.duration = 0;
141030         }
141031         _endCall(document.getElementById("call-exception-type").value);
141032     }
141033 }
141034
141035
141036 function _updateRemotePartyName() {
141037     jQuery("#remotePartyName").text(jQuery("#call-local-phone-number option:selected").text());
141038 }
141039
141040
141041 module.exports = {
141042     panel: {
141043         domId: "call-container",
141044         collapsed: true,
141045         pane: "left",
141046         titleName: "Call",
141047         display: true
141048     },
141049     initialize: function () {
141050         jQuery("#call-local-call").bind("click", _localCall);
141051         jQuery("#call-local-end").bind("click", _localEnd);
141052         jQuery("#call-remote-call").bind("click", _remoteCall);
141053         jQuery("#call-remote-end").bind("click", _remoteEnd);
141054         jQuery("#recording-status").bind("click", _leaveMessage);
141055         jQuery("#call-exception-status").bind("click", _exceptionStatus);
141056         jQuery("#call-exception-type").bind("click", null);
141057
141058         _initEventWatchers();
141059         _initContacts();
141060         jQuery("#remotePartyName").text(jQuery("#call-local-phone-number option:selected").text());
141061         jQuery("#call-local-phone-number").bind("change", _updateRemotePartyName);
141062         _initExceptionTypes();
141063     }
141064 };
141065
141066 });
141067 define('ripple/ui/plugins/camera', function (require, exports, module) {
141068 /*
141069  *  Copyright 2011 Research In Motion Limited.
141070  *
141071  * Licensed under the Apache License, Version 2.0 (the "License");
141072  * you may not use this file except in compliance with the License.
141073  * You may obtain a copy of the License at
141074  *
141075  * http://www.apache.org/licenses/LICENSE-2.0
141076  *
141077  * Unless required by applicable law or agreed to in writing, software
141078  * distributed under the License is distributed on an "AS IS" BASIS,
141079  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141080  * See the License for the specific language governing permissions and
141081  * limitations under the License.
141082  */
141083
141084 var ui = require('ripple/ui'),
141085     event = require('ripple/event'),
141086     video = document.getElementById('camera-video'),
141087     upload = document.getElementById('picture-upload'),
141088     select = document.getElementById('select-file'),
141089     take = document.getElementById('take-file'),
141090     pic = document.getElementById("camera-image");
141091
141092
141093 select.addEventListener('click', function () {
141094     upload.click();
141095 });
141096
141097 upload.addEventListener('change', function () {
141098     pic.src = window.webkitURL.createObjectURL(upload.files[0]);
141099     take.style.display = "inline";
141100 });
141101
141102 take.addEventListener('click', function () {
141103     console.log("captured-image: " + pic.src);
141104     event.trigger('captured-image', [pic.src, upload.files[0]]);
141105     module.exports.hide();
141106 });
141107
141108 module.exports = {
141109     show: function () {
141110         ui.showOverlay("camera-window");
141111         if (pic.src) {
141112             take.style.display = "inline";
141113         }
141114         else {
141115             take.style.display = "none";
141116         }
141117     },
141118     hide: function () {
141119         ui.hideOverlay("camera-window");
141120     }
141121 };
141122
141123 });
141124 define('ripple/ui/plugins/communication', function (require, exports, module) {
141125 /*
141126  *  Copyright 2011 Research In Motion Limited.
141127  *
141128  * Licensed under the Apache License, Version 2.0 (the "License");
141129  * you may not use this file except in compliance with the License.
141130  * You may obtain a copy of the License at
141131  *
141132  * http://www.apache.org/licenses/LICENSE-2.0
141133  *
141134  * Unless required by applicable law or agreed to in writing, software
141135  * distributed under the License is distributed on an "AS IS" BASIS,
141136  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141137  * See the License for the specific language governing permissions and
141138  * limitations under the License.
141139  */
141140
141141 var ui = require('ripple/ui'),
141142     event = require('ripple/event'),
141143     deviceSettings = require('ripple/deviceSettings'),
141144     db = require('ripple/db'),
141145     utils = require('ripple/utils'),
141146     _messageType = {
141147         sms: "SMS",
141148         mms: "MMS",
141149         email: "E-mail"
141150     },
141151     _attachments = [],
141152 /*
141153     _exception = {
141154         "":                  "Connection Issue",
141155         "unknown":           "Unknown",
141156         "network":           "Network",
141157         "unreachable":       "Unreachable",
141158         "no-answer":         "No Answer",
141159         "bad-number":        "Bad Number",
141160         "number-not-in-use": "Number Not In Use",
141161         "media":             "Media",
141162         "no-sim":            "No Sim Card",
141163         "account-down":      "Account Down",
141164         "credit-down":       "Credit Down",
141165         "barred":            "Barred",
141166         "network-busy":      "Network Busy",
141167         "network-down":      "Network Down"
141168     },
141169 */
141170     _status = {
141171         IDLE:       0,
141172         DIALED:     1,
141173         INPROGRESS: 2,
141174     },
141175     _data = {
141176         status: _status.IDLE,
141177 //        isInException: false,
141178         conversationStartTime: null
141179     },
141180     _contactNameArr = [],
141181     _contactNumArr = [],
141182     _CONTACT_KEY = "tizen1-contact",
141183     _record = {},
141184     _conversationSeconds = 0,
141185     _conversationTimer,
141186     _msgTimer,
141187     _audioPlayersStatus = [];
141188
141189 function _showMsg() {
141190     var messageName = jQuery("#communication-senderName").val(),
141191         messageContent = jQuery("#communication-messageContent").val(),
141192         disMsgName = jQuery(".communication-messageContainer tr:first-child td"),
141193         disMsgContent = jQuery(".communication-messageContainer tr:nth-child(2) td textarea");
141194
141195     ui.showOverlay("communication-window");
141196
141197     disMsgName.text(messageName ? messageName : "Unknown name");
141198     disMsgContent.val(messageContent ? messageContent : "");
141199
141200     jQuery("#communication-viewport").css("height", jQuery("#viewport-container").css("height"))
141201                                      .show("slide", {direction: "up"}, "fast");
141202     jQuery(".communication-callContainer").hide();
141203     jQuery(".communication-messageContainer").show();
141204 }
141205
141206 function _msgEventInitialize() {
141207     jQuery("#communication-messageRadioStatus").hide();
141208     jQuery("#communication-sendMessage").unbind("click").click(function () {
141209         var messageItem,
141210             number = jQuery("#communication-senderName").val(),
141211             text = jQuery("#communication-messageContent").val(),
141212             type = jQuery("#communication-msgType").val(),
141213             message = {
141214                 type: type,
141215                 body: text,
141216                 from: number,
141217                 time: new Date(),
141218                 attachments: _attachments
141219             };
141220
141221         if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === false &&
141222             (type === 'sms' || type === 'mms')) {
141223             jQuery("#communication-messageRadioStatus").html('cellular radio is off<br \>Turn it on from Network Management Panel.');
141224             jQuery("#communication-messageRadioStatus").show();
141225             setTimeout(function () {
141226                 jQuery("#communication-messageRadioStatus").hide();
141227             }, 3000);
141228             return;
141229         }
141230         if (deviceSettings.retrieve("WIFI_NETWORK.status") === false &&
141231             type === 'email') {
141232             jQuery("#communication-messageRadioStatus").html('wifi radio is off<br \>Turn it on from Network Management Panel.');
141233             jQuery("#communication-messageRadioStatus").show();
141234             setTimeout(function () {
141235                 jQuery("#communication-messageRadioStatus").hide();
141236             }, 3000);
141237             return;
141238         }
141239
141240         event.trigger("MessageReceived", [message]);
141241         _attachments = [];
141242         event.trigger("CommWinShow", [true]);
141243         _showMsg();
141244
141245         jQuery(".communication-messageContainer textarea").attr("disabled", "disabled");
141246         jQuery("#communication-messageOut td:nth-child(3)").text(jQuery("#communication-messageContent").val());
141247         messageItem = jQuery("#communication-messageOut").html();
141248         jQuery("#communication-messageDisplay").append(messageItem);
141249
141250         clearTimeout(_msgTimer);
141251         _msgTimer = setTimeout(function () {
141252             if (_data.status === _status.IDLE) {
141253                 ui.hideOverlay("communication-window");
141254                 event.trigger("CommWinShow", [false]);
141255             } else {
141256                 _showCall();
141257             }
141258         }, 5000);
141259     });
141260
141261     jQuery("#communication-clearMessage").unbind("click").click(function () {
141262             jQuery("#communication-messageDisplay").empty();
141263         });
141264
141265     event.on("LayoutChanged", function () {
141266         jQuery("#communication-viewport").css("height", jQuery("#viewport-container").css("height"));
141267
141268     });
141269     event.on("OutsideMessageReceived", function (message) {
141270         var i = 0,
141271             recipients = [],
141272             recipientsStatus = {},
141273             messageItem;
141274
141275         recipientsStatus.id = message.id;
141276         recipientsStatus.msg = message.msg;
141277         for (i in message.to) {
141278             recipientsStatus[message.to[i]] = true;
141279             recipients.push(message.to[i]);
141280         }
141281         for (i in message.cc) {
141282             recipientsStatus[message.cc[i]] = true;
141283             recipients.push(message.cc[i]);
141284         }
141285         for (i in message.bcc) {
141286             recipientsStatus[message.bcc[i]] = true;
141287             recipients.push(message.bcc[i]);
141288         }
141289
141290         event.trigger("MessageSent", [recipientsStatus]);
141291         jQuery("#communication-messageIn td:nth-child(1)").text(message.body);
141292         messageItem = jQuery("#communication-messageIn").html();
141293         jQuery("#communication-messageDisplay").append(messageItem);
141294     });
141295
141296     jQuery("#communication-ok").unbind("click").click(function () {
141297         if (_data.status === _status.IDLE) {
141298             ui.hideOverlay("communication-window");
141299             event.trigger("CommWinShow", [false]);
141300         } else {
141301             _showCall();
141302         }
141303         clearTimeout(_msgTimer);
141304     });
141305 }
141306
141307 function _msgInitialize() {
141308     _msgEventInitialize();
141309
141310     utils.forEach(_messageType, function (msgTypeText, msgType) {
141311         var typeNode = utils.createElement("option", {
141312                 "innerText": msgTypeText,
141313                 "value": msgType
141314             });
141315
141316         jQuery("#communication-msgType").append(typeNode);
141317     });
141318 }
141319
141320 function pauseAllAudioPlayer() {
141321     var audios = $("#document").contents().find("audio"),
141322         index;
141323     for (var index = 0; index < audios.length; index++) {
141324         if (audios[index].paused) {
141325             _audioPlayersStatus[index] = 0;
141326         }
141327         else {
141328             _audioPlayersStatus[index] = 1;
141329             audios[index].pause();
141330         }
141331     }
141332 }
141333
141334 function playAllAudioPlayer() {
141335     var audios = $("#document").contents().find("audio"),
141336         index;
141337     for (var index = 0; index < audios.length; index++) {
141338         if (_audioPlayersStatus[index] === 1) {
141339             audios[index].play();
141340         }
141341     }
141342     _audioPlayersStatus = [];
141343 }
141344
141345 function _showCall() {
141346     var callName = jQuery("#communication-callerName").val(),
141347         callNum = jQuery("#communication-callNum").val(),
141348         disCallName = jQuery(".communication-callContainer tr:first-child td"),
141349         disCallNum = jQuery(".communication-callContainer tr:nth-child(2) td");
141350
141351     ui.showOverlay("communication-window");
141352     event.trigger("CommWinShow", [true]);
141353
141354     disCallName.text(callName ? callName : "Unknown Name");
141355     disCallNum.text(callNum ? callNum : "Unknown Number");
141356
141357     jQuery("#communication-viewport").css("height", jQuery("#viewport-container").css("height"))
141358                                      .show("slide", {direction: "up"}, "fast");
141359     jQuery(".communication-callContainer").show();
141360     jQuery(".communication-messageContainer").hide();
141361     pauseAllAudioPlayer();
141362 }
141363
141364 function _initRecord() {
141365     var callerName = jQuery("#communication-callerName").val(),
141366         callerNum = jQuery("#communication-callNum").val(),
141367         displayName = callerName ? callerName : "Unknown",
141368         displayNum = callerNum ? callerNum : "Unknown";
141369
141370     _record = {};
141371     _record.type = "TEL";
141372     if ($("#is-videoCall").prop("checked") === true) {
141373         _record.features = ["CALL", "VIDEOCALL"];
141374     } else {
141375         _record.features = ["CALL", "VOICECALL"];
141376     }
141377     _record.remoteParties = [{
141378         remoteParty: displayNum,
141379         personId: displayName,
141380     }];
141381     _record.startTime = new Date();
141382 }
141383
141384 function _endCall(callEndReason) {
141385     _record.duration = _data.conversationStartTime ? _conversationSeconds : 0;
141386
141387     _data.conversationStartTime = null;
141388
141389     switch (callEndReason) {
141390     case 'rejected':
141391         _record.direction = "REJECTED";
141392         break;
141393     case 'remote':
141394         _record.direction = "RECEIVED";
141395         break;
141396     case 'local':
141397         _record.direction = "MISSEDNEW";
141398         break; 
141399     }
141400
141401     event.trigger("CallRecorded", [_record]);
141402     event.trigger("CallInProgress", [false]);
141403
141404     _data.status = _status.IDLE;
141405     _record = {};
141406
141407     _conversationSeconds = 0;
141408     window.clearInterval(_conversationTimer);
141409     ui.hideOverlay("communication-window");
141410     event.trigger("CommWinShow", [false]);
141411     playAllAudioPlayer();
141412 }
141413
141414 function _callEventInitialize() {
141415     jQuery("#communication-cellularStatus").hide();
141416     jQuery("#communication-callStart").unbind('click').click(
141417         function () {
141418             if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === false) {
141419                 jQuery("#communication-cellularStatus").show();
141420                 setTimeout(function () {
141421                     jQuery("#communication-cellularStatus").hide();
141422                 }, 3000);
141423
141424                 return;
141425             }
141426             if (_data.status === _status.IDLE) {
141427                 _data.status = _status.DIALED;
141428                 _initRecord();
141429                 _showCall();
141430                 jQuery("#callSettings tr:last-child td").text("Calling...");
141431                 jQuery("#communication-callStart > span").text("End Call");
141432                 jQuery("#callSettings input").attr("disabled", "disabled");
141433             } else {
141434                 _endCall("local");
141435
141436                 jQuery("#callSettings tr:last-child td").text("");
141437                 jQuery("#communication-callStart > span").text("Call");
141438                 jQuery(".communication-callContainer tr:nth-child(3)").show();
141439                 jQuery(".communication-callContainer tr:last-child").hide();
141440                 jQuery("#callSettings input").removeAttr("disabled");
141441             }
141442
141443         }
141444     );
141445
141446     event.on("ApplicationLoad", function () {
141447         switch (_data.status) {
141448         case _status.INPROGRESS:
141449             jQuery("#communication-callStart").click();
141450             break;
141451         case _status.DIALED:
141452             jQuery("#communication-ignore").click();
141453             break;
141454         default:
141455             break;
141456         }
141457     });
141458
141459     jQuery("#communication-ignore").unbind('click').click(function () {
141460         _endCall("rejected");
141461
141462         jQuery("#callSettings tr:last-child td").text("");
141463         jQuery("#communication-callStart > span").text("Call");
141464         jQuery("#communication-callStart").removeData();
141465         jQuery("#callSettings input").removeAttr("disabled");
141466     });
141467
141468     jQuery("#communication-answer").unbind('click').click(function () {
141469         _data.conversationStartTime = new Date();
141470         event.trigger("CallInProgress", [true]);
141471         _data.status = _status.INPROGRESS;
141472
141473         _conversationTimer = setInterval(function () {
141474             var timeObj = new Date(1970, 0, 1),
141475                 timeString;
141476
141477             timeObj.setSeconds(_conversationSeconds);
141478             timeString = timeObj.toTimeString().substr(0, 8);
141479             jQuery("#callSettings tr:last-child td").text(timeString);
141480             _conversationSeconds = _conversationSeconds + 1;
141481         }, 1000);
141482
141483         jQuery(".communication-callContainer tr:nth-child(3)").hide();
141484         jQuery(".communication-callContainer tr:last-child").show();
141485     });
141486
141487     jQuery("#communication-end").unbind('click').click(function () {
141488         _endCall("remote");
141489
141490         jQuery("#callSettings tr:last-child td").text("");
141491         jQuery("#communication-callStart > span").text("Call");
141492         jQuery("#communication-callStart").removeData();
141493         jQuery(".communication-callContainer tr:nth-child(3)").show();
141494         jQuery(".communication-callContainer tr:last-child").hide();
141495         jQuery("#callSettings input").removeAttr("disabled");
141496     });
141497 /*
141498     jQuery("#communication-callEndReason").unbind("change").change(function () {
141499         if (!jQuery("#communication-callEndReason").val()) {
141500             _data.isInException = false;
141501         } else {
141502             _data.isInException = true;
141503             if (_data.isInException && (_data.status !== _status.IDLE)) {
141504                 _endCall(jQuery("#communication-callEndReason").val());
141505             }
141506         }
141507
141508         jQuery("#callSettings tr:last-child td").text("");
141509         jQuery("#communication-callStart > span").text("Call");
141510         jQuery("#communication-callStart").removeData();
141511         jQuery(".communication-callContainer tr:nth-child(3)").show();
141512         jQuery(".communication-callContainer tr:last-child").hide();
141513         jQuery("#callSettings input").removeAttr("disabled");
141514     });
141515 */
141516 }
141517
141518 function _contactInitialize() {
141519     var data = db.retrieveObject(_CONTACT_KEY),
141520         displayName = null, number = null, index = 0;
141521
141522     _contactNameArr = [];
141523     _contactNumArr = [];
141524
141525     utils.forEach(data, function (addrBook) {
141526         utils.forEach(addrBook._contacts, function (contact) {
141527             if (contact.name && contact.name && contact.phoneNumbers && contact.phoneNumbers.length > 0) {
141528                 displayName = contact.name.firstName + ' ' + contact.name.lastName;
141529                 number = contact.phoneNumbers[0].number;
141530                 _contactNameArr.push(displayName);
141531                 _contactNumArr[displayName] = number;
141532                 index++;
141533             }
141534         });
141535     });
141536
141537     jQuery("#communication-callerName").autocomplete({
141538         source: _contactNameArr,
141539         select: function (event, ui) {
141540             jQuery("#communication-callNum").val(_contactNumArr[ui.item.value]);
141541         }
141542     });
141543     jQuery("#communication-senderName").autocomplete({
141544         source: _contactNameArr
141545     });
141546 }
141547
141548 function _callInitialize() {
141549     _callEventInitialize();
141550
141551     _contactInitialize();
141552 /*
141553     utils.forEach(_exception, function (value, key) {
141554         var typeNode = utils.createElement("option", {
141555                 "innerText": value,
141556                 "value": key
141557             });
141558
141559         jQuery("#communication-callEndReason").append(typeNode);
141560     });
141561 */
141562 }
141563
141564 function _pushEventInitialize() {
141565     function register(appService) {
141566         appService.registrationId = Math.uuid(null, 16);
141567
141568         window.setTimeout(function () {
141569             var appLabel;
141570
141571             if ($("#communication-push-" + appService.appId).length !== 0) {
141572                 $("#" + appService.appId).click();
141573                 $("#communication-push-status-" + appService.appId).html("||");
141574                 $("#communication-push-status-" + appService.appId).css("color", "#ff0000");
141575
141576                 return;
141577             }
141578
141579             if (!$("#communication-push-app > tbody").html()) {
141580                 $("#communication-push-header").show();
141581                 $("#communication-push-submit").removeAttr("disabled");
141582             }
141583
141584             appLabel = appService.appControl.uri || appService.appId;
141585
141586             $("#communication-push-app").append(
141587                 "<tr id='communication-push-" + appService.appId + "'>" +
141588                 "<td style='width: 90%'><input type='radio' name='communication-push-list' id='" +
141589                 appService.appId + "' style='margin: 5px' checked='checked' />" +
141590                 "<label for='" + appService.appId + "'>" + appLabel + "</label></td>" +
141591                 "<td id='communication-push-status-" + appService.appId + "'>||</td>" +
141592                 "</tr>");
141593
141594             $("label[for='" + appService.appId + "']").css({
141595                 "display": "inline-block",
141596                 "width": "220px",
141597                 "white-space": "nowrap",
141598                 "overflow": "hidden",
141599                 "text-overflow": "ellipsis"
141600             });
141601
141602             $("#communication-push-status-" + appService.appId).css({
141603                 "width": "10%",
141604                 "color": "#ff0000",
141605                 "text-align": "center",
141606                 "font-weight": "bold",
141607                 "font-size": "14px"
141608             });
141609
141610             $("#communication-push-app tr:even").css("background-color", "white");
141611             $("#communication-push-app tr:odd").css("background-color", "whitesmoke");
141612         }, 1);
141613     }
141614
141615     function unregister(appId) {
141616         if ($("#communication-push-" + appId).length === 0)
141617             return;
141618
141619         $("tr[id='communication-push-" + appId + "']").remove();
141620
141621         if (!$("#communication-push-app > tbody").html()) {
141622             $("#communication-push-header").hide();
141623             $("#communication-push-submit").attr("disabled", "disabled");
141624
141625             return;
141626         }
141627
141628         if ($("input[name='communication-push-list']:checked").length === 0) {
141629             $("#communication-push-app input:first").click();
141630         }
141631
141632         $("#communication-push-app tr:even").css("background-color", "white");
141633         $("#communication-push-app tr:odd").css("background-color", "whitesmoke");
141634     }
141635
141636     function connect(appId) {
141637         $("#communication-push-status-" + appId).html("<=>");
141638         $("#communication-push-status-" + appId).css("color", "#32cd32");
141639     }
141640
141641     function disconnect(appId) {
141642         $("#communication-push-status-" + appId).html("||");
141643         $("#communication-push-status-" + appId).css("color", "#ff0000");
141644     }
141645
141646     event.on("PushRequest", function (command, cmdData) {
141647         switch (command) {
141648         case "REGISTER":
141649             register(cmdData);
141650             break;
141651
141652         case "UNREGISTER":
141653             unregister(cmdData);
141654             break;
141655
141656         case "CONNECT":
141657             connect(cmdData);
141658             break;
141659
141660         case "DISCONNECT":
141661             disconnect(cmdData);
141662             break;
141663         }
141664     });
141665 }
141666
141667 function _pushElementInitialize() {
141668     $("#communication-push-submit").attr("disabled", "disabled");
141669     $("#communication-push-submit").unbind('click').click(function () {
141670         var appId, pushMessage;
141671
141672         appId = $("#communication-push-app :checked").attr("id");
141673         if (!appId)
141674             return;
141675
141676         pushMessage = {
141677             appData:      $("#communication-push-data").val(),
141678             alertMessage: $("#communication-push-msg").val(),
141679             date:         new Date()
141680         };
141681
141682         if (!pushMessage.appData || !pushMessage.alertMessage)
141683             return;
141684
141685         event.trigger("PushNotified", [appId, pushMessage]);
141686     });
141687
141688     $("#communication-push-clear").unbind('click').click(function () {
141689         $("#communication-push-msg").val("");
141690         $("#communication-push-data").val("");
141691     });
141692 }
141693
141694 function _pushInitialize() {
141695     _pushEventInitialize();
141696     _pushElementInitialize();
141697 }
141698
141699 module.exports = {
141700     panel: {
141701         domId: "communication-container",
141702         collapsed: true,
141703         pane: "left",
141704         titleName: "Communications",
141705         display: true
141706     },
141707     initialize: function () {
141708         jQuery("#communication-select").tabs();
141709         _callInitialize();
141710         _msgInitialize();
141711         _pushInitialize();
141712     }
141713 };
141714
141715 });
141716 define('ripple/ui/plugins/configWindow', function (require, exports, module) {
141717 /*
141718  *  Copyright 2011 Research In Motion Limited.
141719  *
141720  * Licensed under the Apache License, Version 2.0 (the "License");
141721  * you may not use this file except in compliance with the License.
141722  * You may obtain a copy of the License at
141723  *
141724  * http://www.apache.org/licenses/LICENSE-2.0
141725  *
141726  * Unless required by applicable law or agreed to in writing, software
141727  * distributed under the License is distributed on an "AS IS" BASIS,
141728  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141729  * See the License for the specific language governing permissions and
141730  * limitations under the License.
141731  */
141732 var utils = require('ripple/utils'),
141733     event = require('ripple/event'),
141734     db = require('ripple/db'),
141735     tooltip = require('ripple/ui/plugins/tooltip'),
141736     platform = require('ripple/platform'),
141737     items = [{name: "DEVICE", id: "device-conf-panel"},
141738              {name: "SYSTEM SETTINGS", id: "system-settings-conf-panel"},
141739              {name: "NETWORK", id: "network-conf-panel"}
141740             ],
141741     _KEY = "tizen-configuration-window-setting",
141742     _PERSISTENCE_KEY = "devicesettings",
141743     _DEVICESETTING_SAVE_KEY = "tizen-configuration-window-device-setting",
141744     _DB_APPLICATION_KEY = "tizen1-db-application",
141745     _DB_APPLICATION_SAVE_KEY = "tizen-configuration-window-application-key";
141746
141747 function reload() {
141748     window.tinyHipposReload = true;
141749     location.reload();
141750 }
141751
141752 function _hideConfigWindow() {
141753     $("#configure-window-popup").hide("slide", {direction: "up"}, "slow");
141754     $("#overlayBackground").hide("fade", "slow");
141755 }
141756
141757
141758 function checkResolutionValue(val) {
141759     var ret = false;
141760     if (val >= 200 && val <= 2000) {
141761         ret = true;
141762     }
141763     return ret;
141764 }
141765
141766 function _showConfigWindow() {
141767     var position_x;
141768     $("#item_container").empty();
141769     items.forEach(function (item) {
141770         $("#item_container").append('<div class="configuration-window-item">' + item.name + '</div>');
141771         $("#" + item.id).hide();
141772     });
141773
141774     $("#content_container").show();
141775     $("#" + items[0].id).show("fast");
141776     
141777     $(".configuration-window-item:eq(0)").css("background-color", "#003399");
141778     $(".configuration-window-item:eq(0)").css("color", "#ffffff");
141779
141780     $(".configuration-window-item").unbind('click');
141781     $(".configuration-window-item").bind("click", function () {
141782         $(".configuration-window-item").css("background-color", "#eeeeee");
141783         $(".configuration-window-item").css("color", "#333333");
141784        
141785         $(this).css("background-color", "#003399");
141786         $(this).css("color", "#ffffff");
141787
141788         items.forEach(function (item) {
141789             $("#" + item.id).hide();
141790         });
141791         $("#" + items[$(this).index()].id).show("fast");
141792     });
141793
141794     if ($("#configure-window-popup").is(":visible")) {
141795         $("#configure-window-popup").hide("slide", {direction: "up"}, "slow");
141796         $("#overlayBackground").hide("fade", "slow");
141797         return;
141798     }
141799
141800     position_x = (($(window).width() - 800) / 2)  < 0 ? 0 : ($(window).width() - 800) / 2;
141801     $("#configure-window-popup").css("top", 80);
141802     $("#configure-window-popup").css("left", position_x);
141803
141804     position_x = (($(window).width() - 400) / 2)  < 0 ? 0 : ($(window).width() - 400) / 2;
141805     $("#configure-window-done-popup").css("top", 80);
141806     $("#configure-window-done-popup").css("left", position_x);
141807
141808     $("#overlayBackground").css("width", $(window).width());
141809     $("#overlayBackground").css("height", $(window).height());
141810     $("#overlayBackground").show("fade", "slow");
141811     $("#configure-window-popup").show("slide", {direction: "up"}, "slow");
141812
141813     $("#configuration-window-done-btn").unbind('click');
141814     $("#configuration-window-done-btn").bind("click", function () {
141815         var platformId, version, device, type, width, height, url;
141816
141817         // device & resolution setting
141818         platformId = jQuery("#platform-select").val();
141819         version = jQuery("#version-select").val();
141820         device = jQuery("#device-select").val();
141821         width = jQuery("#resolution-custom-width").val();
141822         height = jQuery("#resolution-custom-height").val();
141823         type = jQuery('input:radio[name="resolution-type"]:checked').val();
141824
141825         if (type === "custom") {
141826             device = "custom";
141827             if (!checkResolutionValue(width) || !checkResolutionValue(height)) {
141828                 return;
141829             }
141830         }
141831
141832         if (platformId === "mobile" || platformId === "tizen") {
141833             platformId = "tizen";
141834             version = "2.0";
141835         }
141836         else {
141837             platformId = "ivi";
141838             version = "3.0";
141839         }
141840
141841         platform.changeEnvironment({
141842             "name": platformId,
141843             "version": version
141844         }, device, function () {
141845             _hideConfigWindow();
141846             window.tinyHipposReload = true;
141847             url = location.href.replace(/&platform=(.+?)-(.+?)$/, "&platform=" + platformId + "-" + version);
141848             location.href = url;
141849             //reload();
141850         });
141851     });
141852
141853     $("#configuration-window-close-btn").unbind('click');
141854     $("#configuration-window-close-btn").bind("click", function () {
141855         if ($("#configure-window-popup").is(":visible")) {
141856             _hideConfigWindow();
141857             return;
141858         }
141859     });
141860     tooltip.create("#configuration-window-save-btn", "Save Configuration");
141861     $("#configuration-window-save-btn").unbind('click');
141862     $("#configuration-window-save-btn").bind("click", function () {
141863         var _type, _device, _custom_width = 0, _custom_height = 0, programs, deviceInfo, _settings;
141864
141865         deviceInfo = db.retrieveObject(_PERSISTENCE_KEY);
141866         db.saveObject(_DEVICESETTING_SAVE_KEY, deviceInfo);
141867
141868         _device = jQuery("#device-select").val();
141869         _type = jQuery('input:radio[name="resolution-type"]:checked').val();
141870         if (_type === "custom") {
141871             _device = "custom";
141872             _custom_width = jQuery("#resolution-custom-width").val();
141873             _custom_height = jQuery("#resolution-custom-height").val();
141874         }
141875         _settings = {
141876             platformId : jQuery("#platform-select").val(),
141877             version : jQuery("#version-select").val(),
141878             device : _device,
141879             type : _type,
141880             custom_width : _custom_width,
141881             custom_height : _custom_height
141882         };
141883         db.saveObject(_KEY, _settings);
141884         programs = db.retrieveObject(_DB_APPLICATION_KEY);
141885         db.saveObject(_DB_APPLICATION_SAVE_KEY, programs);
141886
141887     });
141888     tooltip.create("#configuration-window-load-btn", "Load Configuration");
141889     $("#configuration-window-load-btn").unbind('click');
141890     $("#configuration-window-load-btn").bind("click", function () {
141891         var platformList,
141892             programs,
141893             deviceInfo,
141894             _settings,
141895             versionSelect = document.getElementById("version-select");
141896         if (db.retrieveObject(_DEVICESETTING_SAVE_KEY) === undefined) {
141897             //Never saving data exist
141898             return;
141899         }
141900         //reload system & network setting
141901         deviceInfo = db.retrieveObject(_DEVICESETTING_SAVE_KEY);
141902         db.saveObject("devicesettings", deviceInfo);
141903         jQuery("#devicesettings-content-container").empty();
141904         jQuery("#networksettings-content-container").empty();
141905         require('ripple/deviceSettings').initialize();
141906         require('ripple/ui/plugins/deviceSettings').terminate();
141907         require('ripple/ui/plugins/deviceSettings').initialize();
141908
141909         //reload device setting
141910         jQuery(versionSelect).empty();
141911         _settings = db.retrieveObject(_KEY);
141912         jQuery("#platform-select").val(_settings.platformId);
141913         jQuery("#device-select").val(_settings.device);
141914         if (_settings.type === "custom") {
141915             $('input:radio[name="resolution-type"][value="custom"]').click();
141916             jQuery("#resolution-custom-width").val(parseInt(_settings.custom_width, 10));
141917             jQuery("#resolution-custom-height").val(parseInt(_settings.custom_height, 10));
141918         } else {
141919             $('input:radio[name="resolution-type"][value="predefined"]').click();
141920         }
141921
141922         platformList = platform.getList();
141923         utils.forEach(platformList, function (platform) {
141924             utils.forEach(platform, function (version, versionNumber) {
141925                 if (_settings.platformId === version.id) {
141926                     versionSelect.appendChild(utils.createElement("option", {
141927                         "innerText": versionNumber,
141928                         "value":  versionNumber
141929                     }));
141930                 }
141931             });
141932         });
141933         jQuery("#version-select").val(_settings.version);
141934     });
141935
141936     $(window).bind('resize', function () {
141937         var position_x = 0;
141938         $("#configure-window-popup").css("top", 80);
141939         position_x = (($(window).width() - 800) / 2)  < 0 ? 0 : ($(window).width() - 800) / 2;
141940         $("#configure-window-popup").css("left", position_x);
141941
141942         $("#configure-window-done-popup").css("top", 180);
141943         position_x = (($(window).width() - 400) / 2)  < 0 ? 0 : ($(window).width() - 400) / 2;
141944         $("#configure-window-done-popup").css("left", position_x);
141945
141946         $("#overlayBackground").css("width", $(window).width());
141947         $("#overlayBackground").css("height", $(window).height());
141948     });
141949
141950     if (jQuery("#platform-select").val() === "ivi") {
141951         jQuery("#configuration-window-save-btn").hide();
141952         jQuery("#configuration-window-load-btn").hide();
141953
141954         jQuery("#item_container :nth-child(2)").hide();
141955         jQuery("#item_container :nth-child(3)").hide();
141956     }
141957     else {
141958         jQuery("#configuration-window-save-btn").show();
141959         jQuery("#configuration-window-load-btn").show();
141960
141961         jQuery("#item_container :nth-child(2)").show();
141962         jQuery("#item_container :nth-child(3)").show();
141963     }
141964 }
141965
141966 module.exports = {
141967     initialize: function () {
141968         if (platform.current().id === "cordova") {
141969             items.splice(1, 1);
141970         }
141971         $("#options-button-config-window").bind("click", function ()  {
141972             _showConfigWindow();
141973         });
141974     }
141975 };
141976
141977 });
141978 define('ripple/ui/plugins/deviceSettings', function (require, exports, module) {
141979 /*
141980  *  Copyright 2011 Research In Motion Limited.
141981  *
141982  * Licensed under the Apache License, Version 2.0 (the "License");
141983  * you may not use this file except in compliance with the License.
141984  * You may obtain a copy of the License at
141985  *
141986  * http://www.apache.org/licenses/LICENSE-2.0
141987  *
141988  * Unless required by applicable law or agreed to in writing, software
141989  * distributed under the License is distributed on an "AS IS" BASIS,
141990  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141991  * See the License for the specific language governing permissions and
141992  * limitations under the License.
141993  */
141994 var event = require('ripple/event'),
141995     constants = require('ripple/constants'),
141996     deviceSettings = require('ripple/deviceSettings'),
141997     utils = require('ripple/utils'),
141998     exception = require('ripple/exception'),
141999     platform = require('ripple/platform'),
142000     db = require('ripple/db'),
142001     _CONST = {
142002         "CONTENT_CONTAINER_ID": "devicesettings-content-container",
142003         "UKNOWN_CONTROL_MESSAGE": "Unknown device control type"
142004     },
142005     _contentContainer,
142006     _network_contentContainer,
142007     DBNETWORKSETTING_KEY = "tizen2-preFlightModeNetworksetting",
142008     _CONTAINER_ID = _CONST.CONTENT_CONTAINER_ID;
142009
142010 function _retrieveDeviceInfo(key) {
142011     var layout, rtn, deviceInfo = require('ripple/devices').getCurrentDevice();
142012
142013     switch (key) {
142014     case "Device.model":
142015         return deviceInfo.model;
142016     case "Device.version":
142017         return deviceInfo.firmware;
142018     case "Device.vendor":
142019         return deviceInfo.manufacturer;
142020     case "DISPLAY.resolutionHeight":
142021         return deviceInfo.screen.height;
142022     case "DISPLAY.resolutionWidth":
142023         return deviceInfo.screen.width;
142024     case "DISPLAY.pixelAspectRatio":
142025         return (deviceInfo.screen.width / deviceInfo.screen.height).toFixed(2);
142026
142027     case "DISPLAY.physicalWidth":
142028         return Number((deviceInfo.screen.width / deviceInfo.ppi).toFixed(2));
142029     case "DISPLAY.physicalHeight":
142030         return Number((deviceInfo.screen.height / deviceInfo.ppi).toFixed(2));
142031     case "DISPLAY.dpiY":
142032     case "DISPLAY.dotsPerInchHeight":
142033         return deviceInfo.ppi;
142034     case "DISPLAY.dpiX":
142035     case "DISPLAY.dotsPerInchWidth":
142036         return deviceInfo.ppi;
142037     case "OperatingSystem.version":
142038         return deviceInfo.osVersion;
142039     case "OperatingSystem.name":
142040         return deviceInfo.osName;
142041     case "OperatingSystem.vendor":
142042         return deviceInfo.manufacturer;
142043     case "DEVICE_ORIENTATION.status":
142044         layout = db.retrieve("layout");
142045         if (layout === null || layout === undefined) {
142046             layout = deviceInfo.defaultOrientation || "portrait";
142047         }
142048         if (layout === "portrait") {
142049             return "PORTRAIT_PRIMARY";
142050         } else {
142051             return "LANDSCAPE_PRIMARY";
142052         }
142053         break;
142054     case "WIFI_NETWORK.status":
142055     case "CELLULAR_NETWORK.status":
142056         rtn = deviceSettings.retrieve(key);
142057         if (rtn === true) {
142058             return "ON";
142059         } else {
142060             return "OFF";
142061         }
142062         break;
142063     case "CPU.load":
142064         rtn = deviceSettings.retrieve(key);
142065         if (rtn > 1) {
142066             rtn = 1;
142067             deviceSettings.persist(key, rtn);
142068         }
142069         if (rtn < 0) {
142070             rtn = 0;
142071             deviceSettings.persist(key, rtn);
142072         }
142073         return rtn;
142074     case "DISPLAY.brightness":
142075         rtn = deviceSettings.retrieve(key);
142076         if (rtn > 1) {
142077             rtn = 1;
142078             deviceSettings.persist("DISPLAY.brightness", rtn);
142079         }
142080         if (rtn < 0) {
142081             rtn = 0;
142082             deviceSettings.persist("DISPLAY.brightness", rtn);
142083         }
142084         return rtn;
142085     case "BUILD.manufacturer":
142086         return deviceInfo.manufacturer;
142087     default:
142088         return deviceSettings.retrieve(key);
142089     }
142090 }
142091
142092 function _retrieveSettingName(type) {
142093
142094     switch (type) {
142095     case "CellularHardware":
142096         return "Cellular Hardware";
142097     case "CellularNetwork":
142098         return "Cellular Network";
142099     case "MemoryUnit":
142100         return "Memory Unit";
142101     case "OperatingSystem":
142102         return "Operating System";
142103     case "WebRuntime":
142104         return "Web Runtime";
142105     case "WiFiHardware":
142106         return "WiFi Hardware";
142107     case "WiFiNetwork":
142108         return "WiFi Network";
142109     default:
142110         return type;
142111     }
142112 }
142113
142114 function _appendSettingNode(labelNode, inputNode, label) {
142115     var frag = document.createDocumentFragment(),
142116         rowNode = frag.appendChild(utils.createElement("tr")),
142117         tempTdNode;
142118
142119     rowNode.appendChild(utils.createElement("td"))
142120            .appendChild(labelNode);
142121
142122     tempTdNode = rowNode.appendChild(utils.createElement("td"));
142123
142124     if (label) {
142125         tempTdNode.appendChild(label);
142126     }
142127
142128     tempTdNode.appendChild(inputNode);
142129
142130     return frag;
142131 }
142132
142133 function _getCurrentSetting(setting, settingType, key) {
142134     var ret, savedSetting, fullKey;
142135     fullKey = settingType + "." + key;
142136     savedSetting = _retrieveDeviceInfo(fullKey);
142137     if (fullKey === "WIFI_NETWORK.status" || fullKey === "CELLULAR_NETWORK.status") {
142138         if (savedSetting === "ON") {
142139             savedSetting = true;
142140         } else {
142141             savedSetting = false;
142142         }
142143     }
142144     ret = (savedSetting || savedSetting === false || savedSetting === "" || savedSetting === 0) ? savedSetting : setting.control.value;
142145     return ret;
142146 }
142147
142148 function _buildDOMNode(setting, settingType, key) {
142149     var settingsNode, tagName, jNode,
142150         fullKey = settingType + "." + key,
142151         savedSetting = _retrieveDeviceInfo(fullKey),
142152         // TODO: move this into Utils (isSet method)
142153         currentSetting,
142154         domNode,
142155         domNodeLabel = null;
142156
142157     if (fullKey === "WIFI_NETWORK.status" || fullKey === "CELLULAR_NETWORK.status") {
142158         if (savedSetting === "ON") {
142159             savedSetting = true;
142160         } else {
142161             savedSetting = false;
142162         }
142163     }
142164     currentSetting = (savedSetting || savedSetting === false || savedSetting === "" || savedSetting === 0) ? savedSetting : setting.control.value;
142165
142166     switch (setting.control.type) {
142167     case "text":
142168     case "number":
142169     case "range":
142170     case "checkbox":
142171         tagName = "input";
142172         break;
142173     case "textarea":
142174         tagName = "textarea";
142175         break;
142176     case "select":
142177         tagName = "select";
142178         break;
142179     case "label":
142180         tagName = "label";
142181         break;
142182     default:
142183         exception.raise(exception.types.Application, _CONST.UKNOWN_CONTROL_MESSAGE);
142184     }
142185
142186     settingsNode = utils.createElement(tagName, setting.control.type === "select" ? null : setting.control);
142187     settingsNode.setAttribute("id", "device-settings-" + settingType + "-" + key);
142188
142189     // TODO: this should really be part of utils.createControl? add element of type "range" with label?
142190     if (setting.control.type === "range") {
142191         domNodeLabel = utils.createElement("label", {
142192             "class": constants.UI.LEFT_RANGE_LABEL_CLASS
142193         });
142194     }
142195
142196     domNode = _appendSettingNode(utils.createElement("span", {"innerText": setting.name, "class": "configure-window-text-label"}), settingsNode, domNodeLabel);
142197
142198     jNode = jQuery(settingsNode);
142199     if (tagName !== "label") {
142200         jNode.addClass(constants.UI.JQUERY_UI_INPUT_CLASSES);
142201     }
142202
142203     switch (setting.control.type) {
142204     case "checkbox":
142205         jNode.bind("click", function () {
142206             var checked = this.checked ? true : false;
142207             deviceSettings.persist(fullKey, checked);
142208             if (typeof setting.callback === "function") {
142209                 setting.callback(checked);
142210             }
142211         });
142212
142213         if (currentSetting === true) {
142214             jNode.attr("checked", "checked");
142215         }
142216
142217         break;
142218
142219     case "text":
142220     case "textarea":
142221     case "number":
142222         jNode.val(currentSetting);
142223         utils.bindAutoSaveEvent(jNode, function () {
142224             if (setting.control.type === "number") {
142225                 deviceSettings.persist(fullKey, Number(jNode.val()));
142226             } else {
142227                 deviceSettings.persist(fullKey, jNode.val());
142228             }
142229
142230             if (typeof setting.callback === "function") {
142231                 setting.callback(jNode.val());
142232             }
142233         });
142234         break;
142235
142236     case "label":
142237         jNode.text(currentSetting);
142238         break;
142239
142240     case "select":
142241     case "range":
142242         if (setting.control.type === "select") {
142243             utils.forEach(setting.options,  function (value, option) {
142244                 jNode.append(utils.createElement("option", {
142245                     "value": option,
142246                     "innerText": value
142247                 }));
142248             });
142249         }
142250         else {
142251             if (domNodeLabel) {
142252                 domNodeLabel.innerText = currentSetting;
142253             }
142254         }
142255
142256         jNode.val(currentSetting)
142257              .bind("change", function () {
142258                 if (setting.control.type === "range" && domNodeLabel) {
142259                     domNodeLabel.innerText = jQuery(this).val();
142260                 }
142261                 deviceSettings.persist(fullKey, jQuery(this).val());
142262
142263                 if (typeof setting.callback === "function") {
142264                     setting.callback(jQuery(this).val(), currentSetting);
142265                 }
142266             }
142267         );
142268     }
142269
142270     // TODO: Brent, do in DeviceSettings on load instead?
142271     if (currentSetting !== setting.control.value) {
142272         deviceSettings.register(fullKey, currentSetting);
142273     }
142274
142275     return domNode;
142276 }
142277
142278 function displayBrightnessCB(value) {
142279     if (value > 1) value = 1;
142280     if (value < 0) value = 0;
142281     if (document.getElementById("device-settings-DISPLAY-brightness").value === value) {
142282         return;
142283     }
142284     deviceSettings.persist("DISPLAY.brightness", Number(value));
142285     document.getElementById("device-settings-DISPLAY-brightness").value = value;
142286 }
142287
142288 function cpuLoadCB(value) {
142289     if (value > 1) value = 1;
142290     if (value < 0) value = 0;
142291     if (document.getElementById("device-settings-CPU-load").value === value) {
142292         return;
142293     }
142294     deviceSettings.persist("CPU.load", Number(value));
142295     document.getElementById("device-settings-CPU-load").value = value;
142296 }
142297
142298 function availCapacityCB(value) {
142299     var capacity = deviceSettings.retrieve("STORAGE.capacity");
142300     if (Number(value) > Number(capacity)) value = capacity;
142301     if (Number(value) < 0) value = 0;
142302     deviceSettings.persist("STORAGE.availableCapacity", Number(value));
142303     document.getElementById("device-settings-STORAGE-availableCapacity").value = Number(value);
142304 }
142305
142306 function wiFiNetworkStatusCB(value) {
142307     document.getElementById("device-settings-WIFI_NETWORK-status").checked = value;
142308 }
142309
142310 function flightModeChangedCB(value) {
142311     var networkSettings = {};
142312     if (value === true) {
142313         networkSettings['wifiSetting'] = deviceSettings.retrieve("WIFI_NETWORK.status");
142314         networkSettings['cellularSetting'] = deviceSettings.retrieve("CELLULAR_NETWORK.status");
142315         //networkSettings['bluetoothSetting'] = deviceSettings.retrieve("CELLULAR_NETWORK.status");
142316         //networkSettings['nfcSetting'] = deviceSettings.retrieve("CELLULAR_NETWORK.status");
142317         db.saveObject(DBNETWORKSETTING_KEY, networkSettings);
142318
142319         deviceSettings.persist("CELLULAR_NETWORK.status", false);
142320         deviceSettings.persist("WIFI_NETWORK.status", false);
142321         event.trigger("nfc-power-setting", [false]);
142322         event.trigger("bt-power-setting", [false]);
142323
142324         document.getElementById("device-settings-WIFI_NETWORK-status").checked = false;
142325         document.getElementById("device-settings-CELLULAR_NETWORK-status").checked = false;
142326         $("#device-settings-CELLULAR_NETWORK-status").parent().append("<span id='config_flight_mode_notice' style='color:#555555;'>  (Disabled for Flight Mode)</span>");
142327         document.getElementById("device-settings-CELLULAR_NETWORK-status").disabled = true;
142328
142329     } else {
142330         networkSettings = db.retrieveObject(DBNETWORKSETTING_KEY)||{"wifiSetting": true, "cellularSetting": true};
142331         deviceSettings.persist("WIFI_NETWORK.status", networkSettings['wifiSetting']);
142332         deviceSettings.persist("CELLULAR_NETWORK.status", networkSettings['cellularSetting']);
142333         document.getElementById("device-settings-WIFI_NETWORK-status").checked = networkSettings['wifiSetting'];
142334         document.getElementById("device-settings-CELLULAR_NETWORK-status").checked = networkSettings['cellularSetting'];
142335         $("#config_flight_mode_notice").remove();
142336         document.getElementById("device-settings-CELLULAR_NETWORK-status").disabled = false;
142337     }
142338 }
142339
142340 function cellularNetworkStatusCB(value) {
142341     document.getElementById("device-settings-CELLULAR_NETWORK-status").checked = value;
142342 }
142343
142344 function layoutCB(value) {
142345     if (value === 'portrait') {
142346         deviceSettings.register("DEVICE_ORIENTATION.status", "PORTRAIT_PRIMARY");
142347         document.getElementById("device-settings-DEVICE_ORIENTATION-status").innerText = "PORTRAIT_PRIMARY";
142348     } else {
142349         deviceSettings.register("DEVICE_ORIENTATION.status", "LANDSCAPE_PRIMARY");
142350         document.getElementById("device-settings-DEVICE_ORIENTATION-status").innerText = "LANDSCAPE_PRIMARY";
142351     }
142352 }
142353
142354 // goes through current platforms device settings
142355 // adds nodes to panel and binds respective events
142356 // talks to DeviceSettings for persistence
142357 module.exports = {
142358     initialize: function () {
142359         var settings, value;
142360         _contentContainer = document.getElementById(_CONTAINER_ID);
142361         _network_contentContainer = document.getElementById("networksettings-content-container");
142362
142363         settings = platform.current().device;
142364         utils.forEach(settings, function (settingSection, settingType) {
142365
142366             var currentTableNode, currentTableNode2, settingNameNode, settingName = _retrieveSettingName(settingType);
142367
142368             settingNameNode = utils.createElement("h3", { "innerText": settingName });
142369             settingNameNode.setAttribute("class", "configure-window-session-title");
142370
142371             if (settingType === 'NETWORK' || settingType === 'WIFI_NETWORK' || settingType === 'CELLULAR_NETWORK' || settingType === 'SIM') {
142372                 _network_contentContainer.appendChild(settingNameNode);
142373                 currentTableNode2 = utils.createElement("table", {
142374                     "class": constants.UI.PANEL_TABLE_CLASS
142375                 });
142376                 currentTableNode2.setAttribute("class", "configure-window-panel-table");
142377                 _network_contentContainer.appendChild(currentTableNode2);
142378             }
142379             else {
142380                 _contentContainer.appendChild(settingNameNode);
142381                 currentTableNode = utils.createElement("table", {
142382                     "class": constants.UI.PANEL_TABLE_CLASS
142383                 });
142384                 currentTableNode.setAttribute("class", "configure-window-panel-table");
142385                 _contentContainer.appendChild(currentTableNode);
142386             }
142387
142388             utils.forEach(settingSection, function (setting, key) {
142389                 if (settingType === 'NETWORK' || settingType === 'WIFI_NETWORK' || settingType === 'CELLULAR_NETWORK' || settingType === 'SIM') {
142390                     currentTableNode2.appendChild(_buildDOMNode(setting, settingType, key));
142391                 }
142392                 else {
142393                     currentTableNode.appendChild(_buildDOMNode(setting, settingType, key));
142394                 }
142395                 value = _getCurrentSetting(setting, settingType, key);
142396                 if (setting.callback) {
142397                     setting.callback(value);
142398                 }
142399             });
142400         });
142401
142402         if (deviceSettings.retrieve("CELLULAR_NETWORK.isFlightMode") === true) {
142403             $("#device-settings-CELLULAR_NETWORK-status").parent().append("<span id='config_flight_mode_notice' style='color:#555555;'>  (Disabled for Flight Mode)</span>");
142404             document.getElementById("device-settings-CELLULAR_NETWORK-status").disabled = true;
142405         }
142406
142407         event.on("DisplayBrightnessChanged", displayBrightnessCB);
142408         event.on("DisplayBrightnessChangedByPower", displayBrightnessCB);
142409         event.on("CpuLoadChanged", cpuLoadCB);
142410         event.on("AvailCapacityChanged", availCapacityCB);
142411         event.on("CpuLoadChangedByPower", cpuLoadCB);
142412         event.on("FlightModeChanged", flightModeChangedCB);
142413         event.on("WiFiNetworkStatusChanged", wiFiNetworkStatusCB);
142414         event.on("CellularNetworkStatusChanged", cellularNetworkStatusCB);
142415         event.on("LayoutChanged", layoutCB);
142416     },
142417     terminate: function () {
142418         event.deleteEventHandler("DisplayBrightnessChanged", displayBrightnessCB);
142419         event.deleteEventHandler("DisplayBrightnessChangedByPower", displayBrightnessCB);
142420         event.deleteEventHandler("CpuLoadChanged", cpuLoadCB);
142421         event.deleteEventHandler("AvailCapacityChanged", availCapacityCB);
142422         event.deleteEventHandler("FlightModeChanged", flightModeChangedCB);
142423         event.deleteEventHandler("CpuLoadChangedByPower", cpuLoadCB);
142424         event.deleteEventHandler("WiFiNetworkStatusChanged", wiFiNetworkStatusCB);
142425         event.deleteEventHandler("CellularNetworkStatusChanged", cellularNetworkStatusCB);
142426         event.deleteEventHandler("LayoutChanged", layoutCB);
142427     }
142428 };
142429
142430 });
142431 define('ripple/ui/plugins/devices', function (require, exports, module) {
142432 /*
142433  *  Copyright 2011 Research In Motion Limited.
142434  *
142435  * Licensed under the Apache License, Version 2.0 (the "License");
142436  * you may not use this file except in compliance with the License.
142437  * You may obtain a copy of the License at
142438  *
142439  * http://www.apache.org/licenses/LICENSE-2.0
142440  *
142441  * Unless required by applicable law or agreed to in writing, software
142442  * distributed under the License is distributed on an "AS IS" BASIS,
142443  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142444  * See the License for the specific language governing permissions and
142445  * limitations under the License.
142446  */
142447 var constants = require('ripple/constants'),
142448     db = require('ripple/db'),
142449     resizer = require('ripple/resizer');
142450
142451 function _getTextZooming(zooming) {
142452     return zooming + '%';
142453 }
142454
142455 module.exports = {
142456     panel: {
142457         domId: "devices-container",
142458         collapsed: true,
142459         pane: "left",
142460         titleName: "Orientation and Zooming",
142461         display: true
142462     },
142463
142464     initialize: function () {
142465         var zooming = document.getElementById(constants.ENCAPSULATOR.ZOOMING);
142466         function updateZoomingValues() {
142467             var zoomingText, scaleFactor;
142468
142469             zoomingText = _getTextZooming(zooming.value);
142470             jQuery('#screen-zooming-label').html(zoomingText);
142471
142472             // Zooming device skin
142473             scaleFactor = zooming.value / 100;
142474             resizer.scaleDevice(scaleFactor);
142475         }
142476
142477         function initializeValues() {
142478             var zoomingValue =  db.retrieve(constants.ENCAPSULATOR.ZOOMING);
142479
142480             if (!zoomingValue) {
142481                 zoomingValue = 100;
142482             }
142483             jQuery("#" + constants.ENCAPSULATOR.ZOOMING).val(zoomingValue);
142484             updateZoomingValues();
142485         }
142486
142487         jQuery("#" + constants.ENCAPSULATOR.ZOOMING).bind("change", function () {
142488             updateZoomingValues();
142489             db.save(constants.ENCAPSULATOR.ZOOMING, zooming.value);
142490         });
142491
142492         initializeValues();
142493     }
142494 };
142495
142496
142497 });
142498 define('ripple/ui/plugins/download', function (require, exports, module) {
142499 /*
142500  *  Copyright 2012 Intel Corporation.
142501  *
142502  * Licensed under the Apache License, Version 2.0 (the "License");
142503  * you may not use this file except in compliance with the License.
142504  * You may obtain a copy of the License at
142505  *
142506  * http://www.apache.org/licenses/LICENSE-2.0
142507  *
142508  * Unless required by applicable law or agreed to in writing, software
142509  * distributed under the License is distributed on an "AS IS" BASIS,
142510  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142511  * See the License for the specific language governing permissions and
142512  * limitations under the License.
142513  */
142514
142515 var db = require('ripple/db'),
142516     event = require('ripple/event'),
142517     utils = require('ripple/utils'),
142518     _data = {
142519         DB_DOWNLOAD_KEY : "tizen1-db-download",
142520         resources : []
142521     },
142522     _cleanInputs, intervalId,
142523     _downloads;
142524
142525 function _get() {
142526     _downloads = [
142527         {id: "0001", url : "http://tizen.org/small_file.zip", size : "5", speed : "1.0", estimatedTime : "5", MIMEType : "application/zip"},
142528         {id: "0002", url : "http://tizen.org/big_file.zip", size : "20", speed : "1.0", estimatedTime : "20", MIMEType : "application/zip"},
142529         {id: "0003", url : "http://download.tizen.org/tct/2_1/webapi-tizen-download-test-image-hq.png", size : "3937596", speed : "1968798", estimatedTime : "2", MIMEType : "image/png"},
142530         {id: "0004", url : "http://download.tizen.org/tct/2_1/webapi-tizen-download-test-image-lq.png", size : "589", speed : "589", estimatedTime : "1", MIMEType : "image/png"}
142531     ];
142532     _data.resources = db.retrieveObject(_data.DB_DOWNLOAD_KEY) || _downloads;
142533     if (db.retrieveObject(_data.DB_DOWNLOAD_KEY) && db.retrieveObject(_data.DB_DOWNLOAD_KEY).length === 0) {
142534         _data.resources = _downloads;
142535     } else {
142536         _data.resources = db.retrieveObject(_data.DB_DOWNLOAD_KEY) || _downloads;
142537     }
142538     _save();
142539 }
142540
142541 function _save() {
142542     db.saveObject(_data.DB_DOWNLOAD_KEY, _data.resources);
142543     event.trigger('downloadResourceChanged');
142544 }
142545
142546 function checkURL(url) {
142547     var rg = new RegExp("((^http)|(^https)|(^ftp)):\/\/()+");
142548     return rg.test(url);
142549 }
142550
142551 function loadResources() {
142552     var installed = document.getElementById("download-resource"), node, i;
142553     installed.innerHTML = "";
142554     for (i in _data.resources) {
142555         node = utils.createElement("option", {
142556             "innerText": _data.resources[i].url,
142557             "value": _data.resources[i].id
142558         });
142559         installed.appendChild(node);
142560     }
142561     _cleanInputs();
142562 }
142563
142564 function _displayInfo(text) {
142565     var info = document.getElementById("download-error");
142566     info.innerHTML = text;
142567     if (intervalId) {
142568         clearTimeout(intervalId);
142569     }
142570     intervalId = setTimeout(clearDisplayInfo, 5000);
142571 }
142572
142573 function clearDisplayInfo() {
142574     document.getElementById('download-error').innerHTML = '';
142575 }
142576
142577 function _cleanInputs() {
142578     document.getElementById("download-url").value = "";
142579     document.getElementById("download-size").value = "";
142580     document.getElementById("download-speed").value = "";
142581     document.getElementById("download-time").innerText = "0";
142582     document.getElementById("download-MIMEType").value = "";
142583 }
142584
142585 function checkProperties(optionType, url, size, speed, time, MIMEType) {
142586     var back = true;
142587     if (url === "" || size === "" ||  speed === "" || time === "" || MIMEType === "") {
142588         _displayInfo(optionType + " failed, empty input.");
142589         back = false;
142590     }
142591     if (!checkURL(url)) {
142592         _displayInfo(optionType + " failed, 'URL' is invalid.");
142593         back = false;
142594     }
142595     if (size <= 0 ||  speed <= 0) {
142596         _displayInfo(optionType + " failed, invalid input.");
142597         back = false;
142598     }
142599     return back;
142600 }
142601
142602 function showUpdateNotification() {
142603     var url     = document.getElementById("download-url").value,
142604         size    = document.getElementById("download-size").value,
142605         speed   = document.getElementById("download-speed").value,
142606         MIMEType = document.getElementById("download-MIMEType").value,
142607         isValid = true;
142608     if (url === "" || size === "" ||  speed === "" || MIMEType === "" || !checkURL(url) || size <= 0 ||  speed <= 0) {
142609         isValid = false;
142610     }
142611     if (isValid) {
142612         _displayInfo("Resource changed, please Add or Update the content.");
142613     }
142614 }
142615
142616 function _adding() {
142617     var id, time, url, size, speed, MIMEType, object, i, isValid;
142618     url     = document.getElementById("download-url").value;
142619     size    = document.getElementById("download-size").value;
142620     speed   = document.getElementById("download-speed").value;
142621     MIMEType = document.getElementById("download-MIMEType").value;
142622     time    = size / speed;
142623     id      = Math.uuid(null, 16);
142624
142625     isValid = checkProperties("Add", url, size, speed, time, MIMEType);
142626     if (!isValid)
142627         return;
142628     if (_data.resources.length !== 0) {
142629         for (i in _data.resources) {
142630             if (url === _data.resources[i].url) {
142631                 _displayInfo("Add failed, the download resource is already available.");
142632                 return;
142633             }
142634         }
142635     }
142636     document.getElementById("download-time").innerText = Math.round(time * 100) / 100;
142637     object = {'id': id, 'url': url, 'size': size, 'speed': speed, 'estimatedTime': time, MIMEType: MIMEType};
142638     _data.resources.push(object);
142639     _save();
142640     loadResources();
142641 }
142642
142643 function _update() {
142644     var id, time, url, size, speed, MIMEType, i, isExist = false, isValid;
142645
142646     id    = document.getElementById("download-resource").value;
142647     url   = document.getElementById("download-url").value;
142648     size  = document.getElementById("download-size").value;
142649     speed = document.getElementById("download-speed").value;
142650     MIMEType = document.getElementById("download-MIMEType").value;
142651     time  = size / speed;
142652
142653     if (_data.resources.length === 0) {
142654         _displayInfo("Update failed, there is no download resource now.");
142655         return;
142656     }
142657     isValid = checkProperties("Update", url, size, speed, time, MIMEType);
142658     if (!isValid)
142659         return;
142660     for (i in _data.resources) {
142661         if (_data.resources[i].url === url) {
142662             isExist = true;
142663             _data.resources[i] = {id: id, url : url, size : size, speed : speed, estimatedTime: time, MIMEType: MIMEType};
142664             loadResources();
142665             _save();
142666             break;
142667         }
142668     }
142669     if (!isExist)
142670         _displayInfo("Update failed, the download resource doesn't exist.");
142671 }
142672
142673 function _delete() {
142674     var i, id;
142675     id = document.getElementById("download-resource").value;
142676     if (id) {
142677         for (i in _data.resources) {
142678             if (_data.resources[i].id === id) {
142679                 _data.resources.splice(i, 1);
142680                 _save();
142681                 loadResources();
142682             }
142683         }
142684     }
142685 }
142686
142687 function _showAppDetail(id) {
142688     var i;
142689     for (i in _data.resources) {
142690         if (id === _data.resources[i].id) {
142691             document.getElementById("download-time").innerText = Math.round(_data.resources[i].estimatedTime * 100) / 100;
142692             jQuery("#download-url").val(_data.resources[i].url);
142693             jQuery("#download-size").val(_data.resources[i].size);
142694             jQuery("#download-speed").val(_data.resources[i].speed);
142695             jQuery("#download-MIMEType").val(_data.resources[i].MIMEType);
142696         }
142697     }
142698 }
142699
142700 function _changeAppData() {
142701     var id = jQuery("#download-resource").val();
142702     _showAppDetail(id);
142703 }
142704 function changeValue() {
142705     var size  = document.getElementById("download-size").value,
142706         speed = document.getElementById("download-speed").value;
142707     if (size > 0 && speed > 0) {
142708         document.getElementById("download-time").innerText = Math.round(size / speed * 100) / 100;
142709     } else {
142710         document.getElementById("download-time").innerText  = "";
142711     }
142712 }
142713 function checkInputValue(input) {
142714     if (input.value === "" || input.value <= 0) {
142715         input.style['border-color'] = 'red';
142716         _displayInfo("Invalided value.");
142717     } else {
142718         if (input.style['border-color']) {
142719             input.style.removeProperty('border-color');
142720         }
142721         changeValue();
142722         //showUpdateNotification();
142723     }
142724 }
142725 module.exports = {
142726     panel: {
142727         domId: "download-container",
142728         collapsed: true,
142729         pane: "left",
142730         titleName: "Download",
142731         display: true
142732     },
142733     initialize: function () {
142734         _get();
142735         loadResources();
142736
142737         document.getElementById("download-add").addEventListener("click", _adding, false);
142738         document.getElementById("download-update").addEventListener("click", _update, false);
142739         document.getElementById("download-delete").addEventListener("click", _delete, false);
142740
142741         jQuery("#download-resource").bind("focus change", function () {
142742             var url = document.getElementById("download-url"),
142743                 size = document.getElementById("download-size"),
142744                 speed = document.getElementById("download-speed"),
142745                 MIMEType = document.getElementById("download-MIMEType");
142746             if (url.style['border-color']) {
142747                 url.style.removeProperty('border-color');
142748             }
142749             if (MIMEType.style['border-color']) {
142750                 MIMEType.style.removeProperty('border-color');
142751             }
142752             if (size.value > 0 && size.style['border-color']) {
142753                 size.style.removeProperty('border-color');
142754             }
142755             if (speed.value > 0 && speed.style['border-color']) {
142756                 speed.style.removeProperty('border-color');
142757             }
142758             _changeAppData();
142759         });
142760         jQuery("#download-speed").bind("blur", function () {
142761             changeValue();
142762         });
142763         jQuery("#download-size").bind("blur", function () {
142764             changeValue();
142765         });
142766         jQuery("#download-speed").bind("change", function () {
142767             checkInputValue(this);
142768         });
142769         jQuery("#download-size").bind("change", function () {
142770             checkInputValue(this);
142771         });
142772         jQuery("#download-speed").bind("change", function () {
142773             checkInputValue(this);
142774         });
142775         jQuery("#download-url").bind("change", function () {
142776             if (this.style['border-color']) {
142777                 this.style.removeProperty('border-color');
142778             }
142779             if (this.value && checkURL(this.value)) {
142780                 //showUpdateNotification();
142781             } else  {
142782                 _displayInfo("Invalided URL.");
142783                 this.style['border-color'] = 'red';
142784             }
142785         });
142786     }
142787 };
142788
142789 });
142790 define('ripple/ui/plugins/eulaCheck', function (require, exports, module) {
142791 /*
142792  *  Copyright 2011 Research In Motion Limited.
142793  *
142794  * Licensed under the Apache License, Version 2.0 (the "License");
142795  * you may not use this file except in compliance with the License.
142796  * You may obtain a copy of the License at
142797  *
142798  * http://www.apache.org/licenses/LICENSE-2.0
142799  *
142800  * Unless required by applicable law or agreed to in writing, software
142801  * distributed under the License is distributed on an "AS IS" BASIS,
142802  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142803  * See the License for the specific language governing permissions and
142804  * limitations under the License.
142805  */
142806 var utils = require('ripple/utils'),
142807     bus = require('ripple/bus');
142808
142809 function _initializeEulaCheck() {
142810     var width = jQuery(document).width(),
142811         p = (width / 2) - 277;
142812
142813
142814     $(".eula-window").show();
142815     $(".eula-dialog").show().css({left: p + "px"});
142816
142817     $("#eula-accept").click(function () {
142818         bus.send("acceptEula", null, function (result) {
142819             $(".eula-window").hide();
142820             $(".eula-dialog").hide();
142821         });
142822     });
142823
142824     $("#eula-decline").click(function () {
142825         bus.send("disable", null, null);
142826     });
142827 }
142828
142829 module.exports = {
142830     initialize: function () {
142831         //HACK: there has to be a better way!!!
142832         if ($("#extension-url").val().match(/geelfhphabnejjhdalkjhgipohgpdnoc/)) {
142833             // do nothing, extension was installed from the Chrome Store
142834             return;
142835         }
142836
142837         bus.send("checkEula", null, function (response) {
142838             console.log("eula response: ", response);
142839             if (response === false) {
142840                 _initializeEulaCheck();
142841             }
142842         });
142843     }
142844 };
142845
142846 });
142847 define('ripple/ui/plugins/exec-dialog', function (require, exports, module) {
142848 /*
142849  *  Copyright 2011 Research In Motion Limited.
142850  *
142851  * Licensed under the Apache License, Version 2.0 (the "License");
142852  * you may not use this file except in compliance with the License.
142853  * You may obtain a copy of the License at
142854  *
142855  * http://www.apache.org/licenses/LICENSE-2.0
142856  *
142857  * Unless required by applicable law or agreed to in writing, software
142858  * distributed under the License is distributed on an "AS IS" BASIS,
142859  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142860  * See the License for the specific language governing permissions and
142861  * limitations under the License.
142862  */
142863
142864 function exec(func) {
142865     return function () {
142866         var val = $("#exec-response").val();
142867
142868         //TODO: handle multiple args
142869         func.apply(null, val ? [JSON.parse(val)] : []);
142870         $("#exec-dialog").dialog("close");
142871     };
142872 }
142873
142874 module.exports = {
142875     initialize: function () {
142876         $("#exec-dialog").dialog({
142877             autoOpen: false,
142878             modal: true,
142879             title: "I Haz Cheeseburger?!?!",
142880             width: 500,
142881             position: 'center'
142882         }).hide();
142883
142884         $("#exec-success").button();
142885         $("#exec-fail").button();
142886     },
142887
142888     show: function (service, action, success, fail) {
142889         console.log(service);
142890         console.log(action);
142891         $("#exec-service").text(service);
142892         $("#exec-action").text(action);
142893         $("#exec-dialog").dialog("open");
142894         $("#exec-success").unbind().bind('click', exec(success));
142895         $("#exec-fail").unbind().bind('click', exec(fail));
142896     }
142897 };
142898
142899 });
142900 define('ripple/ui/plugins/fileSystem', function (require, exports, module) {
142901 /*
142902  *  Copyright 2011 Research In Motion Limited.
142903  *
142904  * Licensed under the Apache License, Version 2.0 (the "License");
142905  * you may not use this file except in compliance with the License.
142906  * You may obtain a copy of the License at
142907  *
142908  * http://www.apache.org/licenses/LICENSE-2.0
142909  *
142910  * Unless required by applicable law or agreed to in writing, software
142911  * distributed under the License is distributed on an "AS IS" BASIS,
142912  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142913  * See the License for the specific language governing permissions and
142914  * limitations under the License.
142915  */
142916 var utils = require('ripple/utils'),
142917     constants = require('ripple/constants'),
142918     fileSystem = require('ripple/fileSystem'),
142919     fileSystemPaths = fileSystem.getFileSystemPaths();
142920
142921 module.exports = {
142922     panel: {
142923         domId: "filsystem-container",
142924         collapsed: true,
142925         pane: "left"
142926     },
142927     initialize: function () {
142928         var fileSystemPaths = fileSystem.getFileSystemPaths();
142929
142930         utils.forEach(fileSystemPaths, function (value, key) {
142931             utils.bindAutoSaveEvent(jQuery(constants.FILESYSTEM.INPUT_PREFIX_ID + key).val(value.uri), function () {
142932                 value.uri = jQuery(constants.FILESYSTEM.INPUT_PREFIX_ID + key).val();
142933                 fileSystem.updateFileSystemPaths(fileSystemPaths);
142934             });
142935         });
142936     }
142937 };
142938
142939 });
142940 define('ripple/ui/plugins/firstRunCheck', function (require, exports, module) {
142941 /*
142942  *  Copyright 2011 Research In Motion Limited.
142943  *
142944  * Licensed under the Apache License, Version 2.0 (the "License");
142945  * you may not use this file except in compliance with the License.
142946  * You may obtain a copy of the License at
142947  *
142948  * http://www.apache.org/licenses/LICENSE-2.0
142949  *
142950  * Unless required by applicable law or agreed to in writing, software
142951  * distributed under the License is distributed on an "AS IS" BASIS,
142952  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142953  * See the License for the specific language governing permissions and
142954  * limitations under the License.
142955  */
142956 var utils = require('ripple/utils'),
142957     _platform = require('ripple/platform'),
142958     db = require('ripple/db');
142959
142960 function _handleFirstRunResponse(platform, version) {
142961     var device = jQuery("#device-select").val(),
142962         api = {
142963             name: platform.id,
142964             version: version
142965         };
142966
142967
142968     _platform.changeEnvironment(api, device, function () {
142969         window.tinyHipposReload = true;
142970         location.reload();
142971     });
142972 }
142973
142974 function _addPlatformButton(platform, version) {
142975     var section = jQuery(".platform-select-buttons"),
142976         buttonID = "platform-" + platform.id,
142977         button = utils.createElement("button", {
142978             "id": buttonID,
142979             "class": "ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
142980         });
142981
142982     button.appendChild(utils.createElement("span", {
142983         "class": "ui-button-text",
142984         "innertext" : platform.name
142985     }));
142986
142987     section.append(button);
142988
142989     document.getElementById(buttonID).addEventListener("click", function () {
142990         _handleFirstRunResponse(platform, version);
142991     });
142992 }
142993
142994 function _initializeFirstRunCheck() {
142995     var savedPlatform = db.retrieveObject("api-key"),
142996         firstRunOverlayNode, firstRunOptionsNode,
142997         width, p;
142998
142999     if (!savedPlatform) {
143000         width = jQuery(document).width();
143001         p = (width / 2) - 277;
143002
143003         firstRunOverlayNode = jQuery(".first-run-window").css({display: 'block'});
143004         firstRunOptionsNode = jQuery(".platform-select-dialog").css({display: 'block', left: p + "px"});
143005
143006         utils.forEach(_platform.getList(), function (platform) {
143007             utils.forEach(platform, function (details, version) {
143008                 _addPlatformButton(details, version);
143009             });
143010         });
143011     }
143012 }
143013
143014 module.exports = {
143015     initialize: function () {
143016         if (utils.map(_platform.getList(), function (platform) {
143017             return platform;
143018         }).length > 1) {
143019             _initializeFirstRunCheck();
143020         }
143021     }
143022 };
143023
143024 });
143025 define('ripple/ui/plugins/geoDB', function (require, exports, module) {
143026 /*
143027  *  Copyright 2012 Intel Corporation.
143028  *
143029  * Licensed under the Apache License, Version 2.0 (the "License");
143030  * you may not use this file except in compliance with the License.
143031  * You may obtain a copy of the License at
143032  *
143033  * http://www.apache.org/licenses/LICENSE-2.0
143034  *
143035  * Unless required by applicable law or agreed to in writing, software
143036  * distributed under the License is distributed on an "AS IS" BASIS,
143037  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143038  * See the License for the specific language governing permissions and
143039  * limitations under the License.
143040  */
143041
143042 var db = require('ripple/db'),
143043     utils = require('ripple/utils'),
143044     lbs = require('ripple/platform/tizen/2.0/lbs_utils'),
143045     _GEO_OBJECTS = "tizen1.0-geocode-objects",
143046     _geoList, _currentGeo, _saveID, _showGeoDetail;
143047
143048 function _getGeo() {
143049     var geoList = [],
143050         data = db.retrieveObject(_GEO_OBJECTS);
143051
143052     utils.forEach(data, function (geo) {
143053         geoList.push(geo);
143054     });
143055     return geoList;
143056 }
143057
143058 function _saveGeo() {
143059     db.saveObject(_GEO_OBJECTS, _geoList);
143060 }
143061
143062 function GeoEntry(addr, coord) {
143063     var _self;
143064     _self = {
143065         address : addr || null,
143066         coordinate : coord || null
143067     };
143068     return _self;
143069 }
143070
143071 function _updateGeoDBSelect() {
143072     var geoDBSelect = document.getElementById("geo-select"),
143073         geoNode, i;
143074
143075     geoDBSelect.innerHTML = "";
143076     for (i = 0; i < _geoList.length; i++) {
143077         geoNode = utils.createElement("option", {
143078             "innerText": "(" + _geoList[i].coordinate.latitude + ", " + _geoList[i].coordinate.longitude + ")",
143079             "value": i
143080         });
143081         if (_currentGeo === Number(geoNode.value)) {
143082             geoNode.selected = true;
143083             _showGeoDetail(_geoList[_currentGeo].coordinate, _geoList[_currentGeo].address);
143084         }
143085         geoDBSelect.appendChild(geoNode);
143086     }
143087 }
143088
143089 function _showGeoDetail(coord, addr) {
143090     jQuery("#geoDB-latitude").val(coord.latitude);
143091     jQuery("#geoDB-longitude").val(coord.longitude);
143092     jQuery("#geoDB-altitude").val(coord.altitude);
143093     jQuery("#geoDB-accuracy").val(coord.accuracy);
143094     jQuery("#geoDB-altitudeAccuracy").val(coord.altitudeAccuracy);
143095     jQuery("#geoDB-heading").val(coord.heading);
143096     jQuery("#geoDB-speed").val(coord.speed);
143097
143098     jQuery("#geoDB-country").val(addr.country);
143099     jQuery("#geoDB-region").val(addr.region);
143100     jQuery("#geoDB-county").val(addr.county);
143101     jQuery("#geoDB-city").val(addr.city);
143102     jQuery("#geoDB-street").val(addr.street);
143103     jQuery("#geoDB-streetNumber").val(addr.streetNumber);
143104     jQuery("#geoDB-premises").val(addr.premises);
143105     jQuery("#geoDB-additionalInformation").val(addr.additionalInformation);
143106     jQuery("#geoDB-postalCode").val(addr.postalCode);
143107 }
143108
143109 function _changeGeoData() {
143110     var id = Number(jQuery("#geo-select").val());
143111     _currentGeo = id;
143112     _showGeoDetail(_geoList[id].coordinate, _geoList[id].address);
143113 }
143114
143115 function _triggerReadOnly(on) {
143116     if (on === true) {
143117         jQuery("#geoDB-table input").attr("readonly", "readonly");
143118         jQuery("#geoDB-add").show();
143119         jQuery("#geoDB-modify").show();
143120         jQuery("#geoDB-delete").show();
143121         jQuery("#geo-select").removeAttr("disabled");
143122         jQuery("#geoDB-save").hide();
143123         jQuery("#geoDB-cancel").hide();
143124     } else {
143125         jQuery("#geoDB-table input").removeAttr("readonly");
143126         jQuery("#geoDB-add").hide();
143127         jQuery("#geoDB-modify").hide();
143128         jQuery("#geoDB-delete").hide();
143129         jQuery("#geo-select").attr("disabled", "disabled");
143130         jQuery("#geoDB-save").show();
143131         jQuery("#geoDB-cancel").show();
143132     }
143133 }
143134
143135 function _addGeoData() {
143136     _triggerReadOnly(false);
143137     jQuery("#geoDB-table input").val("");
143138     _saveID = _geoList.length;
143139     jQuery("#geo-select").val("");
143140 }
143141 function _modifyGeoData() {
143142     _triggerReadOnly(false);
143143     _saveID = _currentGeo;
143144 }
143145 function _deleteGeoData() {
143146     _geoList.splice(_currentGeo, 1);
143147     _saveGeo();
143148     _currentGeo = 0;
143149     _updateGeoDBSelect();
143150 }
143151 function _saveGeoData() {
143152     var entry;
143153     entry = new GeoEntry(new lbs.StructuredAddress({
143154         country: jQuery("#geoDB-country").val(),
143155         region: jQuery("#geoDB-region").val(),
143156         county: jQuery("#geoDB-county").val(),
143157         city: jQuery("#geoDB-city").val(),
143158         street: jQuery("#geoDB-street").val(),
143159         streetNumber: jQuery("#geoDB-streetNumber").val(),
143160         premises: jQuery("#geoDB-premises").val(),
143161         additionalInformation: jQuery("#geoDB-additionalInformation").val(),
143162         postalCode: jQuery("#geoDB-postalCode").val()
143163     }),
143164         new lbs.GeoCoordinates({
143165         latitude: parseFloat(jQuery("#geoDB-latitude").val()),
143166         longitude: parseFloat(jQuery("#geoDB-longitude").val()),
143167         altitude: parseFloat(jQuery("#geoDB-altitude").val()),
143168         accuracy: parseFloat(jQuery("#geoDB-accuracy").val()),
143169         altitudeAccuracy: parseFloat(jQuery("#geoDB-altitudeAccuracy").val()),
143170         heading: parseFloat(jQuery("#geoDB-heading").val()),
143171         speed: parseFloat(jQuery("#geoDB-speed").val())
143172     }));
143173     if (_saveID === _geoList.length)
143174         _geoList.push(entry);
143175     else
143176         _geoList[_saveID] = entry;
143177     
143178     _saveGeo();
143179     _currentGeo = _saveID;
143180     _updateGeoDBSelect();
143181     _triggerReadOnly(true);
143182 }
143183
143184 function _cancelGeoData() {
143185     _triggerReadOnly(true);
143186     _updateGeoDBSelect();
143187 }
143188
143189 module.exports = {
143190     panel: {
143191         domId: "geoDB-container",
143192         collapsed: true,
143193         pane: "right"
143194     },
143195
143196     initialize: function () {
143197         _currentGeo = 0; // set _geoList[0] as default value
143198         _geoList = _getGeo();
143199         _updateGeoDBSelect();
143200         _triggerReadOnly(true);
143201
143202         jQuery("#geo-select").bind("change", function () {
143203             _changeGeoData();
143204         });
143205         jQuery("#geoDB-add").bind("click", function () {
143206             _addGeoData();
143207         });
143208         jQuery("#geoDB-modify").bind("click", function () {
143209             _modifyGeoData();
143210         });
143211         jQuery("#geoDB-delete").bind("click", function () {
143212             _deleteGeoData();
143213         });
143214         jQuery("#geoDB-save").bind("click", function () {
143215             _saveGeoData();
143216         });
143217         jQuery("#geoDB-cancel").bind("click", function () {
143218             _cancelGeoData();
143219         });
143220     }
143221 };
143222
143223 });
143224 define('ripple/ui/plugins/geoView', function (require, exports, module) {
143225 /*
143226  *  Copyright 2011 Research In Motion Limited.
143227  *
143228  * Licensed under the Apache License, Version 2.0 (the "License");
143229  * you may not use this file except in compliance with the License.
143230  * You may obtain a copy of the License at
143231  *
143232  * http://www.apache.org/licenses/LICENSE-2.0
143233  *
143234  * Unless required by applicable law or agreed to in writing, software
143235  * distributed under the License is distributed on an "AS IS" BASIS,
143236  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143237  * See the License for the specific language governing permissions and
143238  * limitations under the License.
143239  */
143240 var constants = require('ripple/constants'),
143241     geo = require('ripple/geo'),
143242     db = require('ripple/db'),
143243     event = require('ripple/event'),
143244     utils = require('ripple/utils'),
143245     platform = require('ripple/platform'),
143246     markers,
143247     _gpsMapZoomLevel,
143248     _routePoints = [],
143249     _routes = [],
143250     _routeMarkers,
143251     _lineLayer,
143252     _drawLineTimeout,
143253     _playFrequency = 0,
143254     _originalNavigator = window.navigator,
143255     _locationSharing = false;
143256     _playState = {'play': false, 'replay': false};
143257
143258 function _initTimeZone() {
143259     var allTZ, dbTZ, node = jQuery("#time-locale-select"),
143260         timezone = require('ripple/platform/tizen/2.0/timezone_info'),
143261         alarms, time;
143262
143263     function triggerAlarm() {
143264         time = new Date();
143265         alarms = db.retrieveObject("tizen1.0-db-alarms");
143266         if (alarms !== null) {
143267             utils.forEach(alarms, function (obj) {
143268                 if (obj.id !== undefined) {
143269                     event.trigger("CheckAlarm", [obj.id]);
143270                 }
143271             });
143272         }
143273     }
143274     window.setInterval(triggerAlarm, 1000);
143275
143276     allTZ = timezone.getAllTimezone();
143277     utils.forEach(allTZ, function (tz) {
143278         node.append(utils.createElement("option", {
143279             "value": tz,
143280             "innerHTML": tz + " - " + timezone.getTimezoneAbbr(tz) + "(" + timezone.getTimezoneDiff(tz) + ")"
143281         }));
143282     });
143283     dbTZ = db.retrieve("tizen-timezone");
143284     if (timezone.isValidTimezone(dbTZ)) {
143285         node.val(dbTZ);
143286     } else {
143287         db.save("tizen-timezone", node.val());
143288     }
143289     node.bind("change", function () {
143290         db.save("tizen-timezone", node.val());
143291     });
143292 }
143293
143294 function _updateGpsMap() {
143295     var positionInfo = geo.getPositionInfo(),
143296         mapContainer = document.getElementById(constants.GEO.OPTIONS.MAP_CONTAINER);
143297
143298     if (mapContainer && jQuery(mapContainer).is(':visible')) {
143299         geo.map.setCenter(new OpenLayers.LonLat(positionInfo.longitude, positionInfo.latitude).transform(
143300             new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")), _gpsMapZoomLevel, true);
143301     }
143302
143303     if (_lineLayer) {
143304         geo.map.removeLayer(_lineLayer);
143305         geo.map.addLayer(_lineLayer);
143306     }
143307 }
143308
143309 function _updateGpsMapZoom(goUp) {
143310     if (goUp && _gpsMapZoomLevel < constants.GEO.MAP_ZOOM_MAX) {
143311         _gpsMapZoomLevel++;
143312     }
143313     else if (!goUp && _gpsMapZoomLevel > constants.GEO.MAP_ZOOM_MIN) {
143314         _gpsMapZoomLevel--;
143315     }
143316
143317     _updateGpsMap();
143318     db.save(constants.GEO.MAP_ZOOM_KEY, _gpsMapZoomLevel);
143319 }
143320
143321 function _getTextHeading(heading) {
143322     if (heading >= 337.5 || (heading >= 0 && heading <= 22.5)) {
143323         return 'N';
143324     }
143325
143326     if (heading >= 22.5 && heading <= 67.5) {
143327         return 'NE';
143328     }
143329
143330     if (heading >= 67.5 && heading <= 112.5) {
143331         return 'E';
143332     }
143333     if (heading >= 112.5 && heading <= 157.5) {
143334         return 'SE';
143335     }
143336
143337     if (heading >= 157.5 && heading <= 202.5) {
143338         return 'S';
143339     }
143340
143341     if (heading >= 202.5 && heading <= 247.5) {
143342         return 'SW';
143343     }
143344
143345     if (heading >= 247.5 && heading <= 292.5) {
143346         return 'W';
143347     }
143348
143349     if (heading >= 292.5 && heading <= 337.5) {
143350         return 'NW';
143351     }
143352 }
143353
143354 function _updateRoutes() {
143355     var i, j, k, lon_step, lat_step;
143356     _routes = [];
143357
143358     for (i = 0; i < _routePoints.length - 1; i++) {
143359         lon_step = (_routePoints[i + 1].lonlat.lon - _routePoints[i].lonlat.lon) / 50;
143360         lat_step = (_routePoints[i + 1].lonlat.lat - _routePoints[i].lonlat.lat) / 50;
143361
143362         _routes.push(new OpenLayers.LonLat(_routePoints[i].lonlat.lon, _routePoints[i].lonlat.lat));
143363         for (j = 1, k = _routes.length; j < 50; j++, k++) {
143364             _routes.push(new OpenLayers.LonLat(_routes[k - 1].lon + lon_step, _routes[k - 1].lat + lat_step));
143365         }
143366     }
143367     _routes.push(new OpenLayers.LonLat(
143368         _routePoints[_routePoints.length - 1].lonlat.lon,
143369         _routePoints[_routePoints.length - 1].lonlat.lat)
143370     );
143371 }
143372
143373 function _drawLine(array) {
143374     var GEO_OPTIONS = constants.GEO.OPTIONS,
143375         latitude = document.getElementById(GEO_OPTIONS.LATITUDE),
143376         longitude = document.getElementById(GEO_OPTIONS.LONGITUDE),
143377         lonlat = new OpenLayers.LonLat(array[0].lon, array[0].lat).transform(
143378             new OpenLayers.Projection("EPSG:900913"),
143379             new OpenLayers.Projection("EPSG:4326")
143380         ),
143381         points = new Array(
143382             new OpenLayers.Geometry.Point(array[0].lon, array[0].lat),
143383             new OpenLayers.Geometry.Point(array[1].lon, array[1].lat)
143384         ),
143385         line = new OpenLayers.Geometry.LineString(points),
143386         style = {
143387             strokeColor: '#0000ff',
143388             strokeOpacity: 1,
143389             strokeWidth: 3
143390         },
143391         lineFeature = new OpenLayers.Feature.Vector(line, null, style);
143392
143393     if (!_lineLayer) {
143394         _lineLayer = new OpenLayers.Layer.Vector("Line Layer");
143395         geo.map.addLayer(_lineLayer);
143396     }
143397
143398     _lineLayer.addFeatures([lineFeature]);
143399     longitude.value = lonlat.lon;
143400     latitude.value = lonlat.lat;
143401
143402     if (_playFrequency % 10 === 0) {
143403         geo.map.panTo(new OpenLayers.LonLat(array[0].lon, array[0].lat), _gpsMapZoomLevel);
143404     }
143405     _playFrequency++;
143406 }
143407
143408 function clearRoute() {
143409     if (!_playState.play) {
143410         _routePoints.forEach(function (item) {
143411             _routeMarkers.removeMarker(item.marker);
143412         });
143413         _routePoints = [];
143414         _routes = [];
143415         _lineLayer.removeFeatures(_lineLayer.features);
143416     }
143417 }
143418
143419 function setRoute() {
143420     var clickHandler = new OpenLayers.Handler.Click(
143421         this,
143422         {
143423             click: function (e) {
143424                 if (geo.map.calculateBounds(null, 1) === null) {
143425                     geo.map.zoomTo(geo.map.zoom);
143426                 }
143427                 var location = geo.map.getLonLatFromViewPortPx(e.xy),
143428                     size = new OpenLayers.Size(21, 25),
143429                     offset = new OpenLayers.Pixel(-(size.w / 2), -size.h),
143430                     icon = new OpenLayers.Icon('images/map_marker.png', size, offset),
143431                     marker = new OpenLayers.Marker(new OpenLayers.LonLat(location.lon, location.lat), icon);
143432
143433                 geo.map.addLayer(_routeMarkers);
143434                 _routeMarkers.addMarker(marker);
143435                 _routePoints.push({
143436                     lonlat : location,
143437                     marker : marker
143438                 });
143439             }
143440         },
143441         {double: true}
143442     );
143443     clickHandler.dblclick = function () {
143444         _updateRoutes();
143445         this.deactivate();
143446     };
143447
143448     if (!_playState.play) {
143449         clickHandler.setMap(geo.map);
143450         clickHandler.activate();
143451     }
143452 }
143453
143454 function playRoute() {
143455     var speed = document.getElementById("play-route-speed"),
143456         getPlaySpeed = function () {
143457             return 20 / speed.value * 1000 / 50;
143458         },
143459         draw = function () {
143460             if (_routes.length <= 1) {
143461                 window.clearTimeout(_drawLineTimeout);
143462                 geo.map.panTo(new OpenLayers.LonLat(
143463                     _routePoints[_routePoints.length - 1].lonlat.lon,
143464                     _routePoints[_routePoints.length - 1].lonlat.lat),
143465                     _gpsMapZoomLevel);
143466                 _playState.play = false;
143467                 _playState.replay = true;
143468                 document.getElementById('play-btn-icon').src = "images/play.png";
143469             } else {
143470                 _drawLine(_routes);
143471                 _routes.splice(0, 1);
143472                 _drawLineTimeout = window.setTimeout(draw, getPlaySpeed());
143473             }
143474         };
143475
143476     if (!_playState.play && _routes.length !== 0) {
143477         if (_lineLayer && _playState.replay) {
143478             _lineLayer.removeFeatures(_lineLayer.features);
143479             _updateRoutes();
143480         }
143481         draw();
143482         _playState.play = true;
143483         document.getElementById('play-btn-icon').src = "images/pause.png";
143484     } else if (_playState.play) {
143485         window.clearTimeout(_drawLineTimeout);
143486         _playState.play = false;
143487         _playState.replay = false;
143488         document.getElementById('play-btn-icon').src = "images/play.png";
143489     }
143490 }
143491
143492 function skipTo(position) {
143493     if (_routes.length !== 0) {
143494         var index = (position === 'start' ? 0 : _routePoints.length - 1);
143495         window.clearTimeout(_drawLineTimeout);
143496         _lineLayer.removeFeatures(_lineLayer.features);
143497         geo.map.panTo(new OpenLayers.LonLat(_routePoints[index].lonlat.lon, _routePoints[index].lonlat.lat), _gpsMapZoomLevel);
143498         _routes = [];
143499         _updateRoutes();
143500         _playFrequency = 0;
143501         _playState.play = false;
143502         _playState.replay = false;
143503         document.getElementById('play-btn-icon').src = "images/play.png";
143504     }
143505 }
143506
143507 module.exports = {
143508     panel: {
143509         domId: "gps-container",
143510         collapsed: true,
143511         pane: "left",
143512         titleName: "Geolocation",
143513         display: true
143514     },
143515     initialize: function () {
143516         var GEO_OPTIONS = constants.GEO.OPTIONS,
143517             positionInfo = geo.getPositionInfo(),
143518             positionEvent = "PositionInfoUpdatedEvent",
143519             latitude = document.getElementById(GEO_OPTIONS.LATITUDE),
143520             longitude = document.getElementById(GEO_OPTIONS.LONGITUDE),
143521             altitude = document.getElementById(GEO_OPTIONS.ALTITUDE),
143522             accuracy = document.getElementById(GEO_OPTIONS.ACCURACY),
143523             altitudeAccuracy = document.getElementById(GEO_OPTIONS.ALTITUDE_ACCURACY),
143524             heading = document.getElementById(GEO_OPTIONS.HEADING),
143525             speed = document.getElementById(GEO_OPTIONS.SPEED),
143526             cellID = document.getElementById(GEO_OPTIONS.CELL_ID),
143527             delay = document.getElementById(GEO_OPTIONS.DELAY),
143528             delayLabel = document.getElementById(GEO_OPTIONS.DELAY_LABEL),
143529             headingLabel = document.getElementById(GEO_OPTIONS.HEADING_LABEL),
143530             headingMapLabel = document.getElementById(GEO_OPTIONS.HEADING_MAP_LABEL),
143531             timeout = document.getElementById(GEO_OPTIONS.TIMEOUT),
143532             gpxMultiplier = document.getElementById(GEO_OPTIONS.GPXMULTIPLIER),
143533             gpxReplayStatus = document.getElementById(GEO_OPTIONS.GPXREPLAYSTATUS),
143534             gpxGo = $(document.getElementById(GEO_OPTIONS.GPXGO)).find("span")[0],
143535             mapContainer = document.getElementById(GEO_OPTIONS.MAP_CONTAINER),
143536             map = null,
143537             track = [],
143538             _replayingGpxFile = false,
143539             _haltGpxReplay = false;
143540
143541         function updateGeo() {
143542             if (parseFloat(latitude.value) > 90)
143543                 latitude.value = 90;
143544             else if (parseFloat(latitude.value) < -90)
143545                 latitude.value = -90;
143546
143547             if (parseFloat(longitude.value) > 180)
143548                 longitude.value = 180;
143549             else if (parseFloat(longitude.value) < -180)
143550                 longitude.value = -180;
143551
143552             geo.updatePositionInfo({
143553                 latitude: parseFloat(latitude.value),
143554                 longitude: parseFloat(longitude.value),
143555                 altitude: parseInt(altitude.value, 10),
143556                 accuracy: parseInt(accuracy.value, 10),
143557                 altitudeAccuracy: parseInt(altitudeAccuracy.value, 10),
143558                 heading: heading.value ? parseFloat(heading.value) : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
143559                 speed: speed.value ? parseInt(speed.value, 10) : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
143560                 cellID: cellID.value,
143561                 timeStamp: new Date()
143562             },
143563             delay.value,
143564             timeout.checked);
143565         }
143566
143567         function updateHeadingValues() {
143568             var headingDeg = parseFloat(heading.value),
143569                 headingText = _getTextHeading(parseFloat(heading.value));
143570
143571             headingLabel.innerText = headingText;
143572             headingMapLabel.innerHTML = headingText + "</br>" + headingDeg + "&deg;";
143573         }
143574
143575         function updateValsFromMap() {
143576             var center = geo.map.getCenter().transform(
143577                 new OpenLayers.Projection("EPSG:900913"),
143578                 new OpenLayers.Projection("EPSG:4326"));
143579             longitude.value = center.lon;
143580             latitude.value = center.lat;
143581             updateGeo();
143582         }
143583
143584         function initializeValues() {
143585             latitude.value =          positionInfo.latitude;
143586             longitude.value =         positionInfo.longitude;
143587             altitude.value =          positionInfo.altitude;
143588             accuracy.value =          positionInfo.accuracy;
143589             altitudeAccuracy.value =  positionInfo.altitudeAccuracy;
143590             cellID.value =            positionInfo.cellID;
143591             delay.value = document.getElementById(GEO_OPTIONS.DELAY_LABEL).innerText = geo.delay || 0;
143592             if (geo.timeout) {
143593                 timeout.checked = true;
143594             }
143595             updateHeadingValues();
143596         }
143597
143598         function initMap() {
143599             var marker, clickHandler;
143600             // override image location so we don't have to include image assets
143601             OpenLayers.ImgPath = 'http://openlayers.org/api/img/';
143602
143603             // init map
143604             geo.map = new OpenLayers.Map(mapContainer, { controls: [] });
143605
143606             // add controls and OSM map layer
143607             geo.map.addLayer(new OpenLayers.Layer.OSM());
143608             geo.map.addControl(new OpenLayers.Control.Navigation());
143609
143610             // override behaviour of click to pan and double click to zoom in
143611             clickHandler = new OpenLayers.Handler.Click(
143612                 this,
143613                 {
143614                     click: function (e) {
143615                         if (geo.map.calculateBounds(null, 1) === null) {
143616                             geo.map.zoomTo(geo.map.zoom);
143617                         }
143618                         var location = geo.map.getLonLatFromViewPortPx(e.xy);
143619                         geo.map.panTo(new OpenLayers.LonLat(location.lon, location.lat), _gpsMapZoomLevel);
143620                     },
143621
143622                     dblclick: function () {
143623                         _updateGpsMapZoom(true);
143624                     }
143625                 },
143626                 {double: true}
143627             );
143628
143629             // add click handler to map
143630             clickHandler.setMap(geo.map);
143631             clickHandler.activate();
143632
143633             // update long and lat when map is panned
143634             geo.map.events.register("moveend", map, function () {
143635                 updateValsFromMap();
143636             });
143637             geo.map.events.register("zoomend", map, function (obj) {
143638                 if ((obj.object.zoom > _gpsMapZoomLevel && _gpsMapZoomLevel < constants.GEO.MAP_ZOOM_MAX) ||
143639                     (obj.object.zoom < _gpsMapZoomLevel && _gpsMapZoomLevel > constants.GEO.MAP_ZOOM_MIN)) {
143640                     _gpsMapZoomLevel = obj.object.zoom;
143641                 }
143642             });
143643
143644             markers = new OpenLayers.Layer.Markers("markers");
143645             _routeMarkers = new OpenLayers.Layer.Markers("markers");
143646             geo.map.addLayer(markers);
143647
143648             event.on("ApplicationState", function (obj) {
143649                 if (obj && obj[0].id === 'gps-container' && obj.hasClass('ui-box-open')) {
143650                     _updateGpsMap();
143651
143652                     // Update the position if user accept location sharing
143653                     if (_locationSharing === false) {
143654                         _originalNavigator.geolocation.getCurrentPosition(function(geoPosition) {
143655                             geo.map.panTo(new OpenLayers.LonLat(geoPosition.coords.longitude, geoPosition.coords.latitude).transform(
143656                                 new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")), _gpsMapZoomLevel);
143657                             _locationSharing = true;
143658                         });
143659                     }
143660
143661                     // Simulator is loaded with geo panel folded, now it's the first time it's unfolded
143662                     if (!marker) {
143663                         // Only when the geo panel is unfolded, getCenter() will go well
143664                         marker = new OpenLayers.Marker(geo.map.getCenter(),
143665                             new OpenLayers.Icon("images/arrow.png", new OpenLayers.Size(22, 30), new OpenLayers.Pixel(-11, -15)));
143666                         markers.addMarker(marker);
143667
143668                         navigator.geolocation.getCurrentPosition(function (geoPosition) {
143669                             geo.map.panTo(new OpenLayers.LonLat(geoPosition.coords.longitude, geoPosition.coords.latitude).transform(
143670                                 new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")), _gpsMapZoomLevel);
143671                         });
143672                     }
143673                 }
143674             });
143675             _updateGpsMap();
143676
143677             // Simulator is loaded with geo panel unfolded
143678             if (mapContainer && jQuery(mapContainer).is(':visible')) {
143679                 marker = new OpenLayers.Marker(geo.map.getCenter(),
143680                     new OpenLayers.Icon("images/arrow.png", new OpenLayers.Size(22, 30), new OpenLayers.Pixel(-11, -15)));
143681                 markers.addMarker(marker);
143682
143683                 navigator.geolocation.getCurrentPosition(function (geoPosition) {
143684                     geo.map.panTo(new OpenLayers.LonLat(geoPosition.coords.longitude, geoPosition.coords.latitude).transform(
143685                         new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")), _gpsMapZoomLevel);
143686                     _locationSharing = true;
143687                 });
143688             }
143689
143690             geo.map.events.register("move", map, function () {
143691                 markers.clearMarkers();
143692                 marker = new OpenLayers.Marker(geo.map.getCenter(),
143693                         new OpenLayers.Icon("images/arrow.png", new OpenLayers.Size(22, 30), new OpenLayers.Pixel(-11, -15)));
143694                 markers.addMarker(marker);
143695             });
143696         }
143697
143698         function loadGpxFile(win, fail, args) {
143699             var reader = new FileReader(),
143700                 file = args[0],
143701                 _xml,
143702                 t,
143703                 att,
143704                 lastAtt,
143705                 _ele,
143706                 _timestamp,
143707                 _lastTimestamp,
143708                 _useTimestamp = new Date().getTime(),
143709                 _tempTimestamp,
143710                 _tempPosition,
143711                 _lastPosition,
143712                 _useLastTimestamp,
143713                 _heading = 0,
143714                 _speed = 0,
143715                 _dist = 0,
143716                 navUtils = new utils.navHelper();
143717
143718             reader.onload = function (e) {
143719                 _xml = e.target.result;
143720                 t = $(_xml).find('trkpt');
143721
143722                 track = [];
143723
143724                 utils.forEach(t, function (p, i) {
143725                     if (!isNaN(i)) {
143726                         att = t[i].attributes;
143727                         lastAtt = t[i - 1] ? t[i - 1].attributes : {};
143728                         _ele = $(t[i]).find("ele")[0];
143729                         _timestamp = $(t[i]).find("time")[0];
143730                         _lastTimestamp = $(t[i - 1]).find("time")[0];
143731
143732                         if (_timestamp) {
143733                             //files recorded with endomondo and others have timestamps, this is not a route plan but a record of a track
143734                             _useTimestamp = new Date(_timestamp.innerText).getTime();
143735                         }
143736
143737                         if (t[i - 1]) {
143738                             _dist = navUtils.getDistance(att["lat"].value, att["lon"].value, lastAtt["lat"].value, lastAtt["lon"].value);
143739
143740                             if (_lastTimestamp) {
143741                                 _useLastTimestamp = new Date(_lastTimestamp.innerText).getTime();
143742                             }
143743                             else {
143744                                 //routes from YOURS come in as tracks (rather than routes under the GPX schema), but with no timestamps.  This is a route.
143745                                 _useLastTimestamp = _useTimestamp;
143746                                 _useTimestamp += Math.round(_dist / 22.2222 * 1000);  //80km/h in m/s
143747                             }
143748
143749                             _heading = navUtils.getHeading(lastAtt["lat"].value, lastAtt["lon"].value, att["lat"].value, att["lon"].value);
143750                             _speed = (_dist / ((_useTimestamp - _useLastTimestamp) / 1000)).toFixed(2);
143751
143752                             if (!_lastTimestamp) {
143753                                 //on YOURS routes, make sure we have at least one update a second
143754                                 _tempTimestamp = _useLastTimestamp;
143755
143756                                 while (_useTimestamp - _tempTimestamp > 1000) {
143757                                     _tempTimestamp += 1000;
143758                                     _lastPosition = track[track.length - 1].coords;
143759                                     _tempPosition = navUtils.simulateTravel(_lastPosition.latitude, _lastPosition.longitude, _heading, _speed);
143760                                     track.push({
143761                                         coords: {
143762                                             latitude: _tempPosition.latitude,
143763                                             longitude: _tempPosition.longitude,
143764                                             altitude: _ele ? _ele.innerText : 0,
143765                                             accuracy: 150,
143766                                             altitudeAccuracy: 80,
143767                                             heading: _heading,
143768                                             speed: _speed
143769                                         },
143770                                         timestamp: _tempTimestamp
143771                                     });
143772                                 }
143773                             }
143774                         }
143775
143776                         track.push({
143777                             coords: {
143778                                 latitude: att["lat"].value,
143779                                 longitude: att["lon"].value,
143780                                 altitude: _ele ? _ele.innerText : 0,
143781                                 accuracy: 150,
143782                                 altitudeAccuracy: 80,
143783                                 heading: _heading,
143784                                 speed: _speed
143785                             },
143786                             timestamp: _useTimestamp
143787                         });
143788                     }
143789                 });
143790             };
143791             reader.onerror = function (e) {
143792                 fail(e);
143793             };
143794             reader.readAsText(file.target.files[0], "UTF-8");
143795         }
143796
143797         function replayGpxTrack() {
143798             if (_replayingGpxFile) {
143799                 _haltGpxReplay = true;
143800                 gpxGo.innerText = constants.GEO.GPXGO_LABELS.GO;
143801             }
143802             else {
143803                 if (track.length > 0) {
143804                     _haltGpxReplay = false;
143805                     gpxGo.innerText = constants.GEO.GPXGO_LABELS.STOP;
143806
143807                     latitude.value = track[0].coords.latitude;
143808                     longitude.value = track[0].coords.longitude;
143809                     altitude.value = track[0].coords.altitude;
143810                     accuracy.value = track[0].coords.accuracy;
143811                     altitudeAccuracy.value = track[0].coords.altitudeAccuracy;
143812                     heading.value = track[0].coords.heading;
143813                     speed.value = track[0].coords.speed;
143814
143815                     updateGeo();
143816                     updateHeadingValues();
143817                     _triggerEvent();
143818
143819                     moveNextGpxTrack(1);
143820                 }
143821             }
143822         }
143823
143824         function moveNextGpxTrack(i)
143825         {
143826             if (_haltGpxReplay) {
143827                 _replayingGpxFile = false;
143828                 _haltGpxReplay = false;
143829                 console.log("Ripple :: User interrupted replay of GPX file (Aye Captain, answers All Stop.)");
143830             }
143831             else {
143832                 _replayingGpxFile = true;
143833                 var _timeMultiplier = !isNaN(gpxMultiplier.value) ? gpxMultiplier.value : 1,
143834                 _step = 0,
143835                 _interval = 0;
143836
143837                 while (_interval < 250) {
143838                     _step++;
143839                     if ((i + _step) >= track.length) { break; }
143840                     _interval = (track[i + _step].timestamp - track[i].timestamp) / _timeMultiplier;
143841                 }
143842
143843                 gpxReplayStatus.textContent = (_interval / 1000).toFixed(2) + "s (" + (_interval / 1000 * _timeMultiplier).toFixed(2) + "s realtime), " + (i + 1) + " of " + track.length + " (stepping " + _step + " at " + _timeMultiplier + "x)";
143844
143845                 setTimeout(function () {
143846                     latitude.value = track[i].coords.latitude;
143847                     longitude.value = track[i].coords.longitude;
143848                     altitude.value = track[i].coords.altitude;
143849                     accuracy.value = track[i].coords.accuracy;
143850                     altitudeAccuracy.value = track[i].coords.altitudeAccuracy;
143851                     heading.value = track[i].coords.heading;
143852                     speed.value = track[i].coords.speed;
143853
143854                     updateGeo();
143855                     updateHeadingValues();
143856                     _triggerEvent();
143857
143858                     if (track[i + _step]) {
143859                         moveNextGpxTrack(i + _step);
143860                     }
143861                     else {
143862                         if (i < track.length - 1) {
143863                             moveNextGpxTrack(track.length - 1);
143864                         }
143865                         else {
143866                             _replayingGpxFile = false;
143867                             gpxGo.innerText = constants.GEO.GPXGO_LABELS.GO;
143868                             console.log("Ripple :: Finished replaying GPX file (Arriving at our destination, assuming standard orbit Captain.)");
143869                         }
143870                     }
143871                 }, _interval);
143872             }
143873         }
143874
143875         // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847 (double HACK!!!)
143876         if (platform.current().id === 'phonegap' ||
143877             platform.current().id === 'webworks' ||
143878             platform.current().id === 'cordova') {
143879             // make the fields visible
143880             jQuery("#geo-cellid-container").hide();
143881             jQuery("#geo-heading-container").show();
143882             jQuery("#geo-speed-container").show();
143883         }
143884         else {
143885             jQuery("#geo-cellid-container").show();
143886             jQuery("#geo-heading-container").hide();
143887             jQuery("#geo-speed-container").hide();
143888         }
143889
143890         _gpsMapZoomLevel = db.retrieve(constants.GEO.MAP_ZOOM_KEY) || 14;
143891
143892         jQuery("#geo-map-zoom-decrease").bind("click", function () {
143893             _updateGpsMapZoom(false);
143894         });
143895
143896         jQuery("#geo-map-zoom-increase").bind("click", function () {
143897             _updateGpsMapZoom(true);
143898         });
143899
143900         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.LATITUDE), updateGeo);
143901         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.LONGITUDE), updateGeo);
143902         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.ALTITUDE), updateGeo);
143903         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.ACCURACY), updateGeo);
143904         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.ALTITUDE_ACCURACY), updateGeo);
143905         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.CELL_ID), updateGeo);
143906
143907         jQuery("#play-route-speed-label").html(jQuery("#play-route-speed").val() + 'x');
143908         jQuery("#play-route-speed").bind("change", function () {
143909             jQuery("#play-route-speed-label").html(jQuery("#play-route-speed").val() + 'x');
143910         });
143911         jQuery("#clear-route-btn").bind("click", function () {
143912             clearRoute();
143913         });
143914         jQuery("#set-route-btn").bind("click", function () {
143915             setRoute();
143916         });
143917         jQuery("#play-route-btn").bind("click", function () {
143918             playRoute();
143919         });
143920         jQuery("#back-route-btn").bind("click", function () {
143921             skipTo("start");
143922         });
143923         jQuery("#forward-route-btn").bind("click", function () {
143924             skipTo("end");
143925         });
143926
143927         jQuery("#" + GEO_OPTIONS.DELAY).bind("change", function () {
143928             updateGeo();
143929             delayLabel.innerText = delay.value;
143930         });
143931         jQuery("#" + GEO_OPTIONS.TIMEOUT).bind("click", function () {
143932             updateGeo();
143933         });
143934         jQuery("#" + GEO_OPTIONS.GPXFILE).bind("change", function (a) {
143935             loadGpxFile(null, null, [a]);
143936         });
143937         jQuery("#" + GEO_OPTIONS.GPXGO).bind("click", function () {
143938             replayGpxTrack();
143939         });
143940
143941         // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847 (double HACK!!!)
143942         if (platform.current().id === 'phonegap' || platform.current().id === 'webworks' || platform.current().id === 'cordova') {
143943             jQuery("#" + GEO_OPTIONS.HEADING).bind("change", function () {
143944                 updateGeo();
143945                 updateHeadingValues();
143946             });
143947
143948             utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.SPEED), updateGeo);
143949             heading.value =       positionInfo.heading;
143950             speed.value =         positionInfo.speed;
143951         }
143952
143953         initMap();
143954         if (navigator.onLine === false) {
143955             jQuery("#disable_geo_panel").show();
143956         }
143957         jQuery(window).bind("online", function () {
143958             jQuery("#disable_geo_panel").hide();
143959             console.log("ONLINE");
143960         });
143961         jQuery(window).bind("offline", function () {
143962             jQuery("#disable_geo_panel").show();
143963             console.log("OFFLINE");
143964         });
143965
143966         initializeValues();
143967         _initTimeZone();
143968
143969         event.on(positionEvent, function () {
143970             _updateGpsMap();
143971         });
143972
143973         _triggerEvent();
143974
143975         function _triggerEvent() {
143976             event.trigger(positionEvent, [{
143977                 latitude: latitude.value,
143978                 longitude: longitude.value,
143979                 altitude: altitude.value,
143980                 accuracy: accuracy.value,
143981                 altitudeAccuracy: altitudeAccuracy.value,
143982                 heading: heading ? heading.value : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
143983                 speed: speed ? speed.value : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
143984                 cellID: cellID.value,
143985                 timeStamp: new Date()
143986             }]);
143987         }
143988     }
143989 };
143990
143991 });
143992 define('ripple/ui/plugins/goodVibrations', function (require, exports, module) {
143993 /*
143994  *  Copyright 2011 Research In Motion Limited.
143995  *
143996  * Licensed under the Apache License, Version 2.0 (the "License");
143997  * you may not use this file except in compliance with the License.
143998  * You may obtain a copy of the License at
143999  *
144000  * http://www.apache.org/licenses/LICENSE-2.0
144001  *
144002  * Unless required by applicable law or agreed to in writing, software
144003  * distributed under the License is distributed on an "AS IS" BASIS,
144004  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144005  * See the License for the specific language governing permissions and
144006  * limitations under the License.
144007  */
144008 var constants = require('ripple/constants');
144009
144010 module.exports = {
144011     vibrateDevice: function (milliseconds) {
144012         var node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
144013             x, times;
144014
144015         times = Math.floor(milliseconds / 100);
144016
144017         for (x = 1; x <= times; x++) {
144018             node.animate({ left: -10 }, 5)
144019             .animate({ left: 0 }, 1)
144020             .animate({ left: 10 }, 5)
144021             .animate({ left: 0 }, 1);
144022
144023             node.animate({ top: -10 }, 5)
144024             .animate({ top: 0 }, 1)
144025             .animate({ top: 10 }, 5)
144026             .animate({ top: 0 }, 1);
144027         }
144028     },
144029     shakeDevice: function (times) {
144030         var node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
144031             x;
144032
144033         for (x = 1; x <= times; x++) {
144034             node.animate({ left: -25 }, 50)
144035             .animate({ left: 0 }, 30)
144036             .animate({ left: 25 }, 50)
144037             .animate({ left: 0 }, 30);
144038         }
144039     }
144040 };
144041
144042 });
144043 define('ripple/ui/plugins/information', function (require, exports, module) {
144044 /*
144045  *  Copyright 2011 Research In Motion Limited.
144046  *
144047  * Licensed under the Apache License, Version 2.0 (the "License");
144048  * you may not use this file except in compliance with the License.
144049  * You may obtain a copy of the License at
144050  *
144051  * http://www.apache.org/licenses/LICENSE-2.0
144052  *
144053  * Unless required by applicable law or agreed to in writing, software
144054  * distributed under the License is distributed on an "AS IS" BASIS,
144055  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144056  * See the License for the specific language governing permissions and
144057  * limitations under the License.
144058  */
144059 var constants = require('ripple/constants'),
144060     devices = require('ripple/devices'),
144061     event = require('ripple/event'),
144062     platform = require('ripple/platform'),
144063     utils = require('ripple/utils'),
144064     app = require('ripple/app'),
144065     tooltip = require('ripple/ui/plugins/tooltip'),
144066     db = require('ripple/db');
144067
144068 function _updateInformationView() {
144069     var infoPane = document.getElementById(constants.COMMON.INFO_SECTION),
144070         infoList = [],
144071         device = devices.getCurrentDevice(),
144072         tempString = "",
144073         widgetInfo = app.getInfo(),
144074         layout = db.retrieve("layout") || "portrait",
144075         _systemSettings = db.retrieveObject("tizen2-systemsetting") || {"HOME_SCREEN": "", "LOCK_SCREEN": "", "INCOMING_CALL": "", "NOTIFICATION_EMAIL": ""};
144076
144077     //TODO: refactor this stuff to grab info from API, do this in a loop rather then hardcoded. Better DOM injection approach. This is legacy code
144078
144079     infoList.push('<section id=\"information-banner\" style=\"display:none\"><img id=\"information-banner-icon\" width=\"16px\" height=\"16px\"/> <span id=\"information-banner-count\"></span></section>');
144080
144081     if (widgetInfo.icon) {
144082         infoList.push('<section style="position: absolute; left: 260px;"  class="information-widgeticon"><img class="ui-corner-all" width="64" src="' + utils.appLocation() + widgetInfo.icon + '" alt="widget icon"/></section>');
144083     }
144084     if (widgetInfo.name) {
144085         infoList.push("<section><div id=\"systemSummaryAppNameContainer\" style=\"width:240px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">App Name: </label><span class=\"text-is-selectable\">" + widgetInfo.name + "</span></div></section>");
144086         //Update Title
144087         document.title = "Web Simulator - " + widgetInfo.name;
144088     }
144089
144090     infoList.push('<table class="tf_panel-table" style="border-spacing: 0px;">');
144091    
144092     if (widgetInfo.version) {
144093         infoList.push('<section class="information-widgetversion"><label class=\"ui-text-label\">Version: </label><span class="text-is-selectable">' + widgetInfo.version + '</span></section>');
144094     }
144095     infoList.push("<section><label class=\"ui-text-label\">Platform: </label><span class=\"text-is-selectable\">" + platform.current().name + "</span></section>");
144096     infoList.push("<section><label class=\"ui-text-label\">Device: </label><span class=\"text-is-selectable\">" + device.name + "</span></section>");
144097     infoList.push("<section><label class=\"ui-text-label\">OS: </label><span class=\"text-is-selectable\">" + device.osName + " " + device.osVersion + "</span></section>");
144098     infoList.push("<section><label class=\"ui-text-label\">Manufacturer: </label><span class=\"text-is-selectable\">" + device.manufacturer + "</span></section>");
144099     infoList.push("<section><label class=\"ui-text-label\">Screen: </label><span class=\"text-is-selectable\">" + device.screen.width + "x" + device.screen.height + "</span></section>");
144100     infoList.push("<section><label class=\"ui-text-label\">Viewport: </label><span class=\"text-is-selectable\">" + device.viewPort[layout].width.toFixed(0) + "x" + device.viewPort[layout].height.toFixed(0) + "</span></section>");
144101     infoList.push("<section><label class=\"ui-text-label\">Density: </label><span class=\"text-is-selectable\">" + device.ppi + " PPI</span></section>");
144102     infoList.push("<section><label class=\"ui-text-label\" style=\"float:left; padding-top: 0px; \">User Agent: </label>" +
144103                     "<div class=\"text-is-selectable\" style=\"padding-left: 80px\">" + device.userAgent + "</div></section>");
144104
144105     if (device.notes) {
144106         utils.forEach(device.notes, function (note) {
144107             tempString += "<li class=\"text-is-selectable\">" + note + "</li>";
144108         });
144109         infoList.push("<section><div style=\"clear:both;\"></div><label class=\"ui-text-label\">Notes: </label><ul>" + tempString + "</ul></section>");
144110     }
144111
144112     infoList.push("<section><div style=\"clear:both;\"></div><div id=\"systemSummaryHomeScreenContainer\" style=\"width:320px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">Home Screen Image: </label><span>" + _systemSettings["HOME_SCREEN"] + "</span></div></section>");
144113     infoList.push("<section><div style=\"clear:both;\"></div><div id=\"systemSummaryLockScreenContainer\" style=\"width:320px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">Lock Screen Image: </label><span>" + _systemSettings["LOCK_SCREEN"] + "</span></div></section>");
144114     infoList.push("<section><div style=\"clear:both;\"></div><div id=\"systemSummaryInComingCallContainer\" style=\"width:320px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">Incoming Call Number: </label><span>" + _systemSettings["INCOMING_CALL"] + "</span></div></section>");
144115     infoList.push("<section><div style=\"clear:both;\"></div><div id=\"systemSummaryNotiEMailContainer\" style=\"width:320px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">Notification Email: </label><span>" + _systemSettings["NOTIFICATION_EMAIL"] + "</span></div></section>");
144116     infoList.push("<section><div style=\"clear:both;\"></div><div id=\"NFCExclusiveModeContainer\" style=\"width:320px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">NFC Exclusive Mode: </label><span id=\"NFCExclusiveModeValue\">false</span></div></section>");
144117     infoPane.innerHTML = infoList.join("");
144118
144119     // Make tooltip if it needed
144120     if ((jQuery("#systemSummaryAppNameContainer").children("label").width() + jQuery("#systemSummaryAppNameContainer").children("span").width()) > 240) {
144121         tooltip.create("#systemSummaryAppNameContainer", jQuery("#systemSummaryAppNameContainer").children("span").text());
144122     }
144123     if ((jQuery("#systemSummaryHomeScreenContainer").children("label").width() + jQuery("#systemSummaryHomeScreenContainer").children("span").width()) > 320) {
144124         tooltip.create("#systemSummaryHomeScreenContainer", jQuery("#systemSummaryHomeScreenContainer").children("span").text());
144125     }
144126     if ((jQuery("#systemSummaryLockScreenContainer").children("label").width() + jQuery("#systemSummaryLockScreenContainer").children("span").width()) > 320) {
144127         tooltip.create("#systemSummaryLockScreenContainer", jQuery("#systemSummaryLockScreenContainer").children("span").text());
144128     }
144129     if ((jQuery("#systemSummaryInComingCallContainer").children("label").width() + jQuery("#systemSummaryInComingCallContainer").children("span").width()) > 320) {
144130         tooltip.create("#systemSummaryInComingCallContainer", jQuery("#systemSummaryInComingCallContainer").children("span").text());
144131     }
144132     if ((jQuery("#systemSummaryNotiEMailContainer").children("label").width() + jQuery("#systemSummaryNotiEMailContainer").children("span").width()) > 320) {
144133         tooltip.create("#systemSummaryNotiEMailContainer", jQuery("#systemSummaryNotiEMailContainer").children("span").text());
144134     }
144135 }
144136
144137 function _updateBanner(icon, count) {
144138     var bannerSection = document.getElementById("information-banner"),
144139         iconImg  = document.getElementById("information-banner-icon"),
144140         countSpan = document.getElementById("information-banner-count");
144141
144142     if (icon && (count === undefined || count !== 0)) {
144143         count = count || "";
144144         jQuery("#" + constants.COMMON.INFO_SECTION).show();
144145         jQuery(bannerSection).fadeToggle(1000);
144146         jQuery(bannerSection).fadeIn(1000);
144147     }
144148     else {
144149         jQuery(bannerSection).fadeOut(1000);
144150     }
144151
144152     iconImg.src = utils.appLocation() + icon;
144153     if (icon.indexOf("http") === 0) {
144154         iconImg.src = icon;
144155     }
144156
144157     countSpan.innerHTML = count > 99 ? "99+" : count;
144158 }
144159
144160 module.exports = {
144161     panel: {
144162         domId: "information-container",
144163         collapsed: false,
144164         pane: "left",
144165         titleName: "System Summary",
144166         display: true
144167     },
144168     initialize: function () {
144169         event.on("BannerUpdated", function (icon, count) {
144170             _updateBanner(icon, count);
144171         });
144172
144173         event.on("PlatformChangedEvent", function () {
144174             _updateInformationView();
144175         });
144176
144177         event.on("WidgetInformationUpdated", function () {
144178             _updateInformationView();
144179         });
144180         
144181         event.on("SystemSettingChanged", function () {
144182             _updateInformationView();
144183         });
144184
144185         event.on("ScreenChangeDimensions", function() {
144186             _updateInformationView();
144187         });
144188         _updateInformationView();
144189     }
144190 };
144191
144192 });
144193 define('ripple/ui/plugins/invoke', function (require, exports, module) {
144194 /*
144195  *  Copyright 2011 Research In Motion Limited.
144196  *
144197  * Licensed under the Apache License, Version 2.0 (the "License");
144198  * you may not use this file except in compliance with the License.
144199  * You may obtain a copy of the License at
144200  *
144201  * http://www.apache.org/licenses/LICENSE-2.0
144202  *
144203  * Unless required by applicable law or agreed to in writing, software
144204  * distributed under the License is distributed on an "AS IS" BASIS,
144205  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144206  * See the License for the specific language governing permissions and
144207  * limitations under the License.
144208  */
144209 var constants = require('ripple/constants'),
144210     event = require('ripple/event');
144211
144212 module.exports = {
144213     panel: {
144214         domId: "invoke-container",
144215         collapsed: true,
144216         pane: "left"
144217     },
144218     initialize: function () {
144219         document.getElementById("invoke-send")
144220             .addEventListener("click", function () {
144221                 var invokeInfo = {};
144222
144223                 invokeInfo.uri = document.getElementById("invoke-uri-text").value;
144224                 invokeInfo.source = document.getElementById("invoke-source-text").value;
144225                 invokeInfo.target = document.getElementById("invoke-target-text").value;
144226                 invokeInfo.action = document.getElementById("invoke-action-text").value;
144227                 invokeInfo.type = document.getElementById("invoke-mime-type-text").value;
144228                 invokeInfo.extension = document.getElementById("invoke-extension-text").value;
144229                 invokeInfo.data = document.getElementById("invoke-data-text").value;
144230                 if (invokeInfo.data) {
144231                     invokeInfo.data = window.btoa(invokeInfo.data);
144232                 }
144233
144234                 event.trigger("AppInvoke", [invokeInfo]);
144235             }, false);
144236     }
144237 };
144238
144239 });
144240 define('ripple/ui/plugins/layout', function (require, exports, module) {
144241 /*
144242  *  Copyright 2011 Research In Motion Limited.
144243  *
144244  * Licensed under the Apache License, Version 2.0 (the "License");
144245  * you may not use this file except in compliance with the License.
144246  * You may obtain a copy of the License at
144247  *
144248  * http://www.apache.org/licenses/LICENSE-2.0
144249  *
144250  * Unless required by applicable law or agreed to in writing, software
144251  * distributed under the License is distributed on an "AS IS" BASIS,
144252  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144253  * See the License for the specific language governing permissions and
144254  * limitations under the License.
144255  */
144256 var constants = require('ripple/constants'),
144257     db = require('ripple/db'),
144258     resizer = require('ripple/resizer'),
144259     devices = require('ripple/devices'),
144260     event = require('ripple/event');
144261
144262 function _initializeLayout(prev, baton) {
144263     var layout = db.retrieve("layout"),
144264         orientation = db.retrieve("deviceOrientation") || "portrait",
144265         layoutLandscape = document.getElementById(constants.COMMON.ORIENTATION_SELECT_LANDSCAPE_ID),
144266         layoutPortrait = document.getElementById(constants.COMMON.ORIENTATION_SELECT_PORTRAIT_ID),
144267         currentDevice = devices.getCurrentDevice(),
144268         defaultOrientation =  currentDevice ? currentDevice.defaultOrientation : null,
144269         layoutTypeChanged = false;
144270
144271     jQuery("#" + constants.COMMON.ORIENTATION_SELECT_LANDSCAPE_ID).bind("click", function () {
144272         layoutLandscape.setAttribute("class", "layout-selected");
144273         layoutPortrait.setAttribute("class", "layout-not-selected");
144274         resizer.rotateDevice("landscape");
144275         event.trigger("OrientationChanged", ["landscape"], true);
144276     });
144277
144278     jQuery("#" + constants.COMMON.ORIENTATION_SELECT_PORTRAIT_ID).bind("click", function () {
144279         layoutLandscape.setAttribute("class", "layout-not-selected");
144280         layoutPortrait.setAttribute("class", "layout-selected");
144281         resizer.rotateDevice("portrait");
144282         event.trigger("OrientationChanged", ["portrait"], true);
144283     });
144284
144285     jQuery("#" + constants.COMMON.MENU_BUTTON).bind("click", function () {
144286         event.trigger("HardwareKey", [1]);
144287     });
144288
144289     jQuery("#" + constants.COMMON.BACK_BUTTON).bind("click", function () {
144290         event.trigger("HardwareKey", [0]);
144291     });
144292
144293     if (!layout) {
144294         layout = defaultOrientation || "portrait";
144295         layoutTypeChanged = true;
144296         resizer.changeLayoutType(layout);
144297     }
144298
144299     //Hide the orientation buttons that we don't need for this device
144300     if (!currentDevice.viewPort.landscape) {
144301         layoutLandscape.setAttribute("style", "display:none");
144302     }
144303
144304     if (!currentDevice.viewPort.portrait) {
144305         layoutPortrait.setAttribute("style", "display:none");
144306     }
144307
144308     if (layout && layout === "portrait") {
144309         layoutLandscape.setAttribute("class", "layout-not-selected");
144310         layoutPortrait.setAttribute("class", "layout-selected");
144311     }
144312     else if (layout && layout === "landscape") {
144313         layoutLandscape.setAttribute("class", "layout-selected");
144314         layoutPortrait.setAttribute("class", "layout-not-selected");
144315     }
144316
144317     if (!layoutTypeChanged) {
144318         resizer.resize(currentDevice);
144319     }
144320
144321     if (orientation === "portrait") {
144322         layoutLandscape.setAttribute("class", "layout-not-selected");
144323         layoutPortrait.setAttribute("class", "layout-selected");
144324     } else {
144325         layoutLandscape.setAttribute("class", "layout-selected");
144326         layoutPortrait.setAttribute("class", "layout-not-selected");
144327     }
144328     resizer.rotateDevice(orientation);
144329 }
144330
144331 module.exports = {
144332     initialize: _initializeLayout
144333 };
144334
144335 });
144336 define('ripple/ui/plugins/messaging', function (require, exports, module) {
144337 /*
144338  *  Copyright 2011 Research In Motion Limited.
144339  *
144340  * Licensed under the Apache License, Version 2.0 (the "License");
144341  * you may not use this file except in compliance with the License.
144342  * You may obtain a copy of the License at
144343  *
144344  * http://www.apache.org/licenses/LICENSE-2.0
144345  *
144346  * Unless required by applicable law or agreed to in writing, software
144347  * distributed under the License is distributed on an "AS IS" BASIS,
144348  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144349  * See the License for the specific language governing permissions and
144350  * limitations under the License.
144351  */
144352 var event = require('ripple/event'),
144353     utils = require('ripple/utils'),
144354     _type = {
144355         sms: "SMS",
144356         mms: "MMS",
144357         email: "E-mail"
144358     },
144359     _filename_suffix = 0,
144360     _attachments = [];
144361
144362 function _getAttachmentFileName() {
144363     return "attach" + _filename_suffix + ".txt";
144364 }
144365
144366 module.exports = {
144367     panel: {
144368         domId: "messaging-container",
144369         collapsed: true,
144370         pane: "left",
144371         titleName: "Messaging",
144372         display: true
144373     },
144374     initialize: function () {
144375         document.getElementById("messaging-send")
144376             .addEventListener("click", function () {
144377                 var number = document.getElementById("messaging-sms-number").value,
144378                     text = document.getElementById("messaging-text").value,
144379                     type = document.getElementById("messaging-type").value,
144380                     message = {
144381                         type: type,
144382                         body: text,
144383                         from: number,
144384                         time: new Date(),
144385                         attachments: _attachments
144386                     };
144387
144388                 event.trigger("MessageReceived", [message]);
144389                 
144390                 _attachments = [];
144391 /* TODO: add back when attachment is finished
144392                 document.getElementById("messaging-attachments").innerHTML = "";
144393 */
144394                 _filename_suffix = 0;
144395             }, false);
144396
144397 /* TODO: add back when attachment is finished
144398         document.getElementById("messaging-attach")
144399             .addEventListener("click", function () {
144400                 var attachedFile, attachedFileCheckbox, attachedFileName;
144401                 if (_filename_suffix > 0)
144402                     return;
144403                 _attachments.push({filename: _getAttachmentFileName(), content: document.getElementById("messaging-attachment-content").value});
144404
144405                 attachedFile = document.getElementById("messaging-attachments").insertRow(0);
144406                 attachedFileName = attachedFile.insertCell(0);
144407                 attachedFileCheckbox = attachedFile.insertCell(1);
144408                 attachedFileName.innerHTML = _attachments[_filename_suffix].filename;
144409 //                attachedFileCheckbox.innerHTML = '<input type="checkbox" value="' + _filename_suffix + '">';
144410
144411                 document.getElementById("messaging-attachment-content").value = "";
144412                 _filename_suffix++;
144413             }, false);
144414
144415         document.getElementById("messaging-detach")
144416             .addEventListener("click", function () {
144417                 _attachments = [];
144418                 document.getElementById("messaging-attachments").innerHTML = "";
144419                 _filename_suffix = 0;
144420             }, false);
144421 */
144422         event.on("OutsideMessageReceived", function (message) {
144423             var numRecipients = 0,
144424                 i = 0,
144425                 recipients = [],
144426                 recipientsStatus = {},
144427                 strRecipients = document.getElementById("messaging-recipients").value;
144428
144429             recipientsStatus.id = message.id;
144430             recipientsStatus.msg = message.msg;
144431             for (i in message.to) {
144432                 recipientsStatus[message.to[i]] = true;
144433                 recipients.push(message.to[i]);
144434             }
144435             for (i in message.cc) {
144436                 recipientsStatus[message.cc[i]] = true;
144437                 recipients.push(message.cc[i]);
144438             }
144439             for (i in message.bcc) {
144440                 recipientsStatus[message.bcc[i]] = true;
144441                 recipients.push(message.bcc[i]);
144442             }
144443             numRecipients = recipients.length;
144444             strRecipients = recipients.join(",");
144445             event.trigger("MessageSent", [recipientsStatus]);
144446             document.getElementById("messaging-received").innerHTML = "" + numRecipients + " recipient(s)" + " delivered";
144447             document.getElementById("messaging-recipients").value = strRecipients;
144448             document.getElementById("received-message-box").value = message.body;
144449         });
144450         
144451         document.getElementById("messaging-clear")
144452             .addEventListener("click", function () {
144453                 document.getElementById("received-message-box").value = "";
144454                 document.getElementById("messaging-received").innerHTML = "";
144455             }, false);
144456         
144457         utils.forEach(_type, function (msgTypeText, msgType) {
144458             var typeNode = utils.createElement("option", {
144459                     "innerText": msgTypeText,
144460                     "value": msgType
144461                 });
144462
144463             document.getElementById("messaging-type").appendChild(typeNode);
144464         });
144465     }
144466 };
144467
144468 });
144469 define('ripple/ui/plugins/multimedia', function (require, exports, module) {
144470 /*
144471  *  Copyright 2011 Research In Motion Limited.
144472  *
144473  * Licensed under the Apache License, Version 2.0 (the "License");
144474  * you may not use this file except in compliance with the License.
144475  * You may obtain a copy of the License at
144476  *
144477  * http://www.apache.org/licenses/LICENSE-2.0
144478  *
144479  * Unless required by applicable law or agreed to in writing, software
144480  * distributed under the License is distributed on an "AS IS" BASIS,
144481  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144482  * See the License for the specific language governing permissions and
144483  * limitations under the License.
144484  */
144485 var constants = require('ripple/constants'),
144486     event = require('ripple/event'),
144487     volumeField = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_FIELD_ID),
144488     volume = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_SLIDER_ID);
144489
144490 module.exports = {
144491     panel: {
144492         domId: "multimedia-container",
144493         collapsed: true,
144494         pane: "left"
144495     },
144496     initialize: function () {
144497         var volumeField = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_FIELD_ID),
144498             volume = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_SLIDER_ID);
144499
144500         event.on("MultimediaVolumeChanged", function (volume) {
144501             volumeField.innerText = volume > 9 ? volume : "0" + volume;
144502             if (volume.value !== volume) {
144503                 volume.value = volume;
144504             }
144505         });
144506
144507         volume.addEventListener('change', function () {
144508             event.trigger("MultimediaVolumeChanged", [this.value], true);
144509         }, false);
144510
144511         event.on("MultimediaAudioStateChanged", function updateIsAudioPlaying(state) {
144512             document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PLAYING_FIELD_ID).innerHTML = state === constants.MULTIMEDIA.AUDIO_STATES.PLAYING;
144513         });
144514     }
144515 };
144516
144517 });
144518 define('ripple/ui/plugins/network', function (require, exports, module) {
144519 /*
144520  *  Copyright 2012 Intel Corporation
144521  *
144522  * Licensed under the Apache License, Version 2.0 (the "License");
144523  * you may not use this file except in compliance with the License.
144524  * You may obtain a copy of the License at
144525  *
144526  * http://www.apache.org/licenses/LICENSE-2.0
144527  *
144528  * Unless required by applicable law or agreed to in writing, software
144529  * distributed under the License is distributed on an "AS IS" BASIS,
144530  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144531  * See the License for the specific language governing permissions and
144532  * limitations under the License.
144533  */
144534
144535 var db = require('ripple/db'),
144536     utils = require('ripple/utils'),
144537     event = require('ripple/event'),
144538     deviceSettings = require('ripple/deviceSettings'),
144539     //dbinit = require('ripple/platform/tizen/2.0/dbinit'),
144540     _NFC_TAG = "tizen1.0-nfc-tag",
144541     _NFC_PEER = "tizen1.0-nfc-peer",
144542     _NFC_OUTPUT_MESSAGE = "tizen1.0-nfc-output-message",
144543     _powered = false,
144544     _isConnected = false,
144545     _tagNDEF = {
144546         type: "GENERIC_TARGET",
144547         isSupportedNDEF: true,
144548         ndefSize: 3,
144549         ndefs: [{
144550             recordCount: 2,
144551             records: [{
144552                 tnf: 1,
144553                 type: "TypeA",
144554                 id: "ID001",
144555                 payload: "This is 1st payload"
144556             }, {
144557                 tnf: 1,
144558                 type: "TypeA",
144559                 id: "ID002",
144560                 payload: "This is 2nd payload"
144561             }]
144562         },
144563         {
144564             recordCount: 2,
144565             records: [{
144566                 tnf: 1,
144567                 type: "TypeA",
144568                 id: "ID003",
144569                 payload: "This is 1st payload"
144570             }, {
144571                 tnf: 1,
144572                 type: "TypeA",
144573                 id: "ID004",
144574                 payload: "This is 2nd payload"
144575             }]
144576         },
144577         {
144578             recordCount: 2,
144579             records: [{
144580                 tnf: 1,
144581                 type: "TypeA",
144582                 id: "ID005",
144583                 payload: "This is 1st payload"
144584             }, {
144585                 tnf: 1,
144586                 type: "TypeA",
144587                 id: "ID006",
144588                 payload: "This is 2nd payload"
144589             }]
144590         }]
144591     },
144592     _tagRaw = {
144593         type: "GENERIC_TARGET",
144594         isSupportedNDEF: false,
144595         rawData : ""
144596     },
144597     _peerNDEF = {
144598         ndef: {
144599             recordCount: 2,
144600             records: [{
144601                 tnf: 1,
144602                 type: "TypeA",
144603                 id: "ID001",
144604                 payload: "This is 1st payload"
144605             }, {
144606                 tnf: 1,
144607                 type: "TypeA",
144608                 id: "ID002",
144609                 payload: "This is 2nd payload"
144610             }]
144611         }
144612     },
144613     btNodes,
144614     _btDeviceTemplate = "",
144615     _btSimulatedDevs = {},
144616     _btBluetoothDB;
144617
144618 function elementEnableDisableSetting(prop) {
144619     jQuery("#nfc-attach-msg").text("\xa0");
144620     jQuery("#nfc-peer-send-msg").text("\xa0");
144621     if (prop && prop.power !== undefined && prop.power !== null) {
144622         if (!prop.power) {
144623             $("#nfc-type").removeAttr("disabled");
144624         }
144625     }
144626     if (prop && prop.connectedState !== undefined && prop.connectedState !== null) {
144627         if (prop.connectedState) {
144628             $("#nfc-type").attr("disabled", "disabled");
144629             $("#nfc-tag-type-text").text($("#nfc-tag-type option:selected").text());
144630             $("#nfc-tag-type").hide();
144631             $("#nfc-tag-type-text").show();
144632             $("#nfc-tag-NDEF-support-text").text($("#nfc-tag-NDEF-support option:selected").text());
144633             $("#nfc-tag-NDEF-support").hide();
144634             $("#nfc-tag-NDEF-support-text").show();
144635             $("#nfc-raw-data").attr("disabled", "disabled");
144636         } else {
144637             $("#nfc-type").removeAttr("disabled");
144638             $("#nfc-tag-type").show();
144639             $("#nfc-tag-type-text").hide();
144640             $("#nfc-tag-NDEF-support").show();
144641             $("#nfc-tag-NDEF-support-text").hide();
144642             $("#nfc-raw-data").removeAttr("disabled");
144643         }
144644     }
144645 }
144646
144647 function _initializeElements() {
144648     jQuery(function () {
144649         var stop = false,
144650         wifiRadio = $("#wifi-radio"),
144651         isSupportNDEF, type;
144652
144653         // initialize main menus
144654         wifiRadio.buttonset();
144655
144656         $("#cellular-radio").buttonset();
144657         $("#nfc-radio").buttonset();
144658         $("#bluetooth-radio").buttonset();
144659         $("#bearer-radio").buttonset();
144660
144661         $("#wifi-radio1").prop('checked', false);
144662         $("#wifi-radio2").prop('checked', false);
144663         if (deviceSettings.retrieve("WIFI_NETWORK.status") === true) {
144664             $("#wifi-radio1").prop('checked', true);
144665             $("#wifi-radio1-label").css({'color': '#000000'});
144666             $("#wifi-radio2-label").css({'color': '#bbbbbb'});
144667         }
144668         else {
144669             $("#wifi-radio2").prop('checked', true);
144670             $("#wifi-radio1-label").css({'color': '#bbbbbb'});
144671             $("#wifi-radio2-label").css({'color': '#222222'});
144672         }
144673         $("#wifi-radio1").button("refresh");
144674         $("#wifi-radio2").button("refresh");
144675
144676         $("#cellular-radio1").prop('checked', false);
144677         $("#cellular-radio2").prop('checked', false);
144678         if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === true) {
144679             $("#cellular-radio1").prop('checked', true);
144680             $("#cellular-radio1-label").css({'color': '#000000'});
144681             $("#cellular-radio2-label").css({'color': '#bbbbbb'});
144682         }
144683         else {
144684             $("#cellular-radio2").prop('checked', true);
144685             $("#cellular-radio1-label").css({'color': '#bbbbbb'});
144686             $("#cellular-radio2-label").css({'color': '#222222'});
144687         }
144688
144689         if (deviceSettings.retrieve("CELLULAR_NETWORK.isFlightMode") === true) {
144690             $("#cellular-radio1").prop('disabled', true);
144691             $("#cellular-radio2").prop('disabled', true);
144692             $("#panel_flight_mode_notice").show();
144693         }
144694         else {
144695             $("#cellular-radio1").prop('disabled', false);
144696             $("#cellular-radio2").prop('disabled', false);
144697             $("#panel_flight_mode_notice").hide();
144698         }
144699
144700         $("#cellular-radio1").button("refresh");
144701         $("#cellular-radio2").button("refresh");
144702
144703         $("#bearer-radio2").prop('checked', true);
144704         $("#bearer-radio2").button("refresh");
144705
144706         $("#wifi-radio1").click(function () {
144707             $("#wifi-radio1-label").css({'color': '#000000'});
144708             $("#wifi-radio2-label").css({'color': '#bbbbbb'});
144709             deviceSettings.persist("WIFI_NETWORK.status", true);
144710             event.trigger("WiFiNetworkStatusChanged", [true]);
144711         });
144712
144713         $("#wifi-radio2").click(function () {
144714             $("#wifi-radio1-label").css({'color': '#bbbbbb'});
144715             $("#wifi-radio2-label").css({'color': '#222222'});
144716             deviceSettings.persist("WIFI_NETWORK.status", false);
144717             event.trigger("WiFiNetworkStatusChanged", [false]);
144718         });
144719
144720         $("#cellular-radio1").click(function () {
144721             $("#cellular-radio1-label").css({'color': '#000000'});
144722             $("#cellular-radio2-label").css({'color': '#bbbbbb'});
144723             deviceSettings.persist("CELLULAR_NETWORK.status", true);
144724             event.trigger("CellularNetworkStatusChanged", [true]);
144725         });
144726
144727         $("#cellular-radio2").click(function () {
144728             $("#cellular-radio1-label").css({'color': '#bbbbbb'});
144729             $("#cellular-radio2-label").css({'color': '#222222'});
144730             deviceSettings.persist("CELLULAR_NETWORK.status", false);
144731             event.trigger("CellularNetworkStatusChanged", [false]);
144732         });
144733
144734         $("#nfc-radio1-label").css({'color': '#bbbbbb'});
144735         $("#nfc-radio2-label").css({'color': '#222222'});
144736
144737         $("#bluetooth-radio1-label").css({'color': '#bbbbbb'});
144738         $("#bluetooth-radio2-label").css({'color': '#222222'});
144739
144740         $("#bearer-radio1-label").css({'color': '#bbbbbb'});
144741         $("#bearer-radio2-label").css({'color': '#222222'});
144742
144743         $("#nfc-radio1").click(function () {
144744             $("#nfc-radio2-label").css({'color': '#bbbbbb'});
144745             $("#nfc-radio1-label").css({'color': '#222222'});
144746             $("#nfc-main-container").show();
144747         });
144748
144749         $("#nfc-radio2").click(function () {
144750             $("#nfc-radio1-label").css({'color': '#bbbbbb'});
144751             $("#nfc-radio2-label").css({'color': '#222222'});
144752             $("#nfc-main-container").hide();
144753         });
144754
144755         $("#bluetooth-radio1").click(function () {
144756             $("#bluetooth-radio2-label").css({'color': '#bbbbbb'});
144757             $("#bluetooth-radio1-label").css({'color': '#222222'});
144758             $("#bluetooth-main-container").show();
144759         });
144760
144761         $("#bluetooth-radio2").click(function () {
144762             $("#bluetooth-radio1-label").css({'color': '#bbbbbb'});
144763             $("#bluetooth-radio2-label").css({'color': '#222222'});
144764             $("#bluetooth-main-container").hide();
144765         });
144766
144767         $("#bearer-radio1").click(function () {
144768             $("#bearer-radio2-label").css({'color': '#bbbbbb'});
144769             $("#bearer-radio1-label").css({'color': '#222222'});
144770             $("#bearer-main-container").show();
144771         });
144772
144773         $("#bearer-radio2").click(function () {
144774             $("#bearer-radio1-label").css({'color': '#bbbbbb'});
144775             $("#bearer-radio2-label").css({'color': '#222222'});
144776             $("#bearer-main-container").hide();
144777         });
144778
144779         // initialize nfc
144780         jQuery("nfc-tag-ndef-container h3").click(function (event) {
144781             if (stop) {
144782                 event.stopImmediatePropagation();
144783                 event.preventDefault();
144784                 stop = false;
144785             }
144786         });
144787         jQuery("#nfc-tag-ndef-container").accordion("destroy").accordion({
144788             header: "> div > h3",
144789             autoHeight: false
144790         });
144791         jQuery("nfc-nfcpeer h3").click(function (event) {
144792             if (stop) {
144793                 event.stopImmediatePropagation();
144794                 event.preventDefault();
144795                 stop = false;
144796             }
144797         });
144798         jQuery("#nfc-nfcpeer").accordion("destroy").accordion({
144799             header: "> div > h3",
144800             autoHeight: false
144801         });
144802         jQuery("#nfc-tag-NDEF-support").bind("change", function () {
144803             isSupportNDEF = jQuery("#nfc-tag-NDEF-support").val();
144804             if (isSupportNDEF === "Yes") {
144805                 jQuery("#nfc-tag-ndef-container").fadeIn();
144806                 jQuery("#nfc-tag-raw-container").hide();
144807             } else {
144808                 jQuery("#nfc-tag-ndef-container").hide();
144809                 jQuery("#nfc-tag-raw-container").fadeIn();
144810             }
144811         });
144812         jQuery("#nfc-type").bind("change", function () {
144813             type = jQuery("#nfc-type").val();
144814             if (type === "Tag") {
144815                 jQuery("#nfc-nfctag").fadeIn();
144816                 jQuery("#nfc-nfcpeer").hide();
144817             } else {
144818                 jQuery("#nfc-nfctag").hide();
144819                 jQuery("#nfc-nfcpeer").fadeIn();
144820             }
144821             elementEnableDisableSetting();
144822         });
144823         jQuery("#nfc-power").bind("change", function () {
144824             var status;
144825             status = jQuery("#nfc-power").val() === "On" ? true : false;
144826             if (status)
144827                 jQuery("#nfc").show();
144828             event.trigger("nfc-power-setting", [status]);
144829         });
144830         jQuery("#nfc-attach").bind("click", function () {
144831             var type, isAttached;
144832             isAttached = jQuery("#nfc-attach").children().text() === "Attach" ? true : false;
144833             jQuery("#nfc-attach-msg").text("\xa0");
144834
144835             if (!_powered && isAttached) {
144836                 jQuery("#nfc-attach-msg").text("Power:Off, attach won't work");
144837                 return;
144838             }
144839             type = jQuery("#nfc-type").val();
144840             event.trigger("nfc-attach-setting", [type, isAttached]);
144841         });
144842         jQuery("#nfc-peer-send").bind("click", function () {
144843             jQuery("#nfc-peer-send-msg").text("\xa0");
144844             if (!_isConnected) {
144845                 jQuery("#nfc-peer-send-msg").text("Disconnected. Send won't work");
144846                 return;
144847             }
144848             db.saveObject(_NFC_PEER, _peerNDEF);
144849             event.trigger("nfc-peer-sending-ndef", []);
144850         });
144851
144852         // Initialize network bearer selection
144853         $("#bearer-cellular-radio1").prop('checked', true);
144854         $("#bearer-unknown-radio2").prop('checked', true);
144855         $("#bearer-cellular-radio1").button("refresh");
144856         $("#bearer-unknown-radio2").button("refresh");
144857
144858         $("#bearer-cellular-radio2").click(function () {
144859             $("#bearer-cellular button").click();
144860         });
144861
144862         $("#bearer-unknown-radio2").click(function () {
144863             $("#bearer-unknown button").click();
144864         });
144865     });
144866 }
144867
144868 function _btRender() {
144869     var devicesHTML, btHtmlContent = "";
144870
144871     utils.forEach(_btSimulatedDevs, function (item) {
144872         var uuidsHTML = "", firstService = null;
144873
144874         utils.forEach(item.services, function (s, index) {
144875             if (!firstService) {
144876                 firstService = s;
144877             }
144878             uuidsHTML += '<option value="' + index + '">' + s.name + '</option>';
144879         });
144880
144881         devicesHTML = _btDeviceTemplate.replace(/#name/g, item.name)
144882         .replace(/#address/g, item.address)
144883         .replace(/#class-major/, item.deviceClass.majorName)
144884         .replace(/#class-minor/, item.deviceClass.minorName)
144885         .replace(/#class-service/, item.deviceClass.servicesName.join(","))
144886         .replace(/#bonded/, "No")
144887         .replace(/#trusted/, item.isTrusted ? "Yes" : "No")
144888         .replace(/#connected/, "No")
144889         .replace(/#uuids/, uuidsHTML)
144890         .replace(/#service-uuid/, firstService.uuid)
144891         .replace(/#service-protocol/, firstService.protocol)
144892         .replace(/#service-state/, firstService.state || "CLOSED")
144893         .replace(/#id/g, item.address.replace(/:/g, ""));
144894
144895         btHtmlContent += devicesHTML;
144896     });
144897
144898     $("#network-bt-box").accordion("destroy");
144899     $("#network-bt-box").html(btHtmlContent).accordion({
144900         active : false,
144901         collapsible : true,
144902         autoHeight : false
144903     });
144904 }
144905
144906 function _btRemove(index) {
144907     delete _btSimulatedDevs[index];
144908     db.saveObject("bt-simulated-devices", _btSimulatedDevs);
144909     event.trigger("bt-simulated-devices-changed", []);
144910     _btRender();
144911 }
144912
144913 function _bearerRelease(type, idBearer, evNetworkDisconnected) {
144914     if ($("#bearer-row-" + idBearer).length > 0) {
144915         $("tr[id='bearer-row-" + idBearer + "']").remove();
144916     }
144917
144918     event.trigger(evNetworkDisconnected);
144919
144920     $("#bearer-" + type + " tr:even").css("background-color", "white");
144921     $("#bearer-" + type + " tr:odd").css("background-color", "whitesmoke");
144922 }
144923
144924 module.exports = {
144925     panel: {
144926         domId: "network-container",
144927         collapsed: true,
144928         pane: "left",
144929         titleName: "Network Management",
144930         display: true
144931     },
144932     initialize: function () {
144933         _initializeElements();
144934
144935         // Events for nfc module
144936         event.on("nfc-power-changed", function (status) {
144937             _powered = status;
144938             if (_powered === true) {
144939                 $("#nfc-power").val("On");
144940             } else {
144941                 $("#nfc-power").val("Off");
144942             }
144943             elementEnableDisableSetting({power: status});
144944         });
144945         event.on("nfc-connectedState-changed", function (state) {
144946             var i, type, isSupportedNDEF, str, bytes = [];
144947             _isConnected = state;
144948             elementEnableDisableSetting({connectedState: state});
144949             type = jQuery("#nfc-type").val();
144950             if (state) {
144951                 jQuery("#nfc-attach").children().text("Detach");
144952                 jQuery("#nfc-tag-connection").text("Connected");
144953                 jQuery("#nfc-peer-connection").text("Connected");
144954                 if (type === "Tag") {
144955                     isSupportedNDEF = jQuery("#nfc-tag-NDEF-support").val() === "Yes" ? true : false;
144956                     if (isSupportedNDEF) {
144957                         _tagNDEF.type = jQuery("#nfc-tag-type").val();
144958                         db.saveObject(_NFC_TAG, _tagNDEF);
144959                     } else {
144960                         _tagRaw.type = jQuery("#nfc-tag-type").val();
144961                         str = jQuery("#nfc-raw-data").val();
144962                         for (i = 0; i < str.length; i++) {
144963                             bytes.push(str.charCodeAt(i));
144964                         }
144965                         _tagRaw.rawData = bytes;
144966                         db.saveObject(_NFC_TAG, _tagRaw);
144967                     }
144968                     event.trigger("nfc-tag-send", [true]);
144969                 } else {
144970                     event.trigger("nfc-peer-send", [true]);
144971                 }
144972             } else {
144973                 jQuery("#nfc-attach").children().text("Attach");
144974                 jQuery("#nfc-tag-connection").text("Disconnected");
144975                 jQuery("#nfc-peer-connection").text("Disconnected");
144976                 jQuery("#nfc-output").text("");
144977                 jQuery("#nfc-output-table").hide();
144978                 if (type === "Tag") {
144979                     event.trigger("nfc-tag-send", [false]);
144980                 } else {
144981                     event.trigger("nfc-peer-send", [false]);
144982                 }
144983             }
144984         });
144985         event.on("nfc-output-msg", function () {
144986             var msg;
144987             msg = db.retrieve(_NFC_OUTPUT_MESSAGE);
144988             jQuery("#nfc-output").text(msg);
144989             jQuery("#nfc-output-table").show();
144990         });
144991
144992         // Events for bluetooth module
144993         event.on("bluetoothPowerState", function (state) {
144994             if (state) {
144995                 $("#bluetooth-radio1").click();
144996             } else {
144997                 $("#bluetooth-radio2").click();
144998             }
144999         });
145000         event.on("bt-adapter-name-changed", function (name) {
145001             $("#bt-adapter-name").text(name);
145002         });
145003         event.on("bt-adapter-power-changed", function (state) {
145004             if (state) {
145005                 $("#bt-adapter-power").text("On");
145006             } else {
145007                 $("#bt-adapter-power").text("Off");
145008             }
145009         });
145010         event.on("bt-adapter-visible-changed", function (state) {
145011             if (state) {
145012                 $("#bt-adapter-visible").text("On");
145013             } else {
145014                 $("#bt-adapter-visible").text("Off");
145015             }
145016         });
145017         event.on("bt-device-bonded-changed", function (addr, isBonded) {
145018             var str = "No";
145019             if (isBonded) {
145020                 str = "Yes";
145021             }
145022             jQuery("#bonded-" + addr.replace(/:/g, "")).html(str);
145023         });
145024         event.on("bt-device-connected-changed", function (addr, isConnected) {
145025             var str = "No";
145026             if (isConnected) {
145027                 str = "Yes";
145028             }
145029             jQuery("#connected-" + addr.replace(/:/g, "")).html(str);
145030         });
145031         event.on("bt-service-state-changed", function (addr, uuid, state) {
145032             var str = "CLOSED";
145033             if (state) {
145034                 str = "OPEN";
145035             }
145036             _btSimulatedDevs[addr].services[uuid].state = str;
145037             jQuery("#service-state-" + addr.replace(/:/g, "")).html(str);
145038         });
145039         event.on("bt-service-write-msg", function (addr, uuid, data) {
145040             var msg = "", uuidNow;
145041             utils.forEach(data, function (char) {
145042                 msg += String.fromCharCode(char);
145043             });
145044             uuidNow = jQuery("#network-bt-uuid-" + addr.replace(/:/g, "")).html();
145045             if (uuidNow === uuid) {
145046                 jQuery("#service-receive-textarea-" + addr.replace(/:/g, "")).html(msg);
145047             }
145048         });
145049
145050         // Event for network bearer selection module
145051         event.on("NetworkRequest", function (networkType, domainName) {
145052             var type = networkType.toLowerCase(), name, idBearer,
145053                 evNetworkOpened       = "NO_" + networkType + "_" + domainName,
145054                 evNetworkDisconnected = "ND_" + networkType + "_" + domainName;
145055
145056             if (!$("#bearer-" + type + "-radio1").prop("checked")) {
145057                 event.trigger(evNetworkOpened, [false]);
145058                 event.trigger(evNetworkDisconnected);
145059
145060                 return;
145061             }
145062
145063             name = domainName.replace(/\./, "");
145064             idBearer = type + '-' + name;
145065
145066             if ($("#bearer-row-" + idBearer).length <= 0) {
145067                 $("#bearer-" + type).append("<tr id='bearer-row-" + idBearer + "'>" +
145068                      "<td>&nbsp<lable class='ui-text-label'>" + domainName + "</label></td>" +
145069                      "<td><button id='bearer-btn-" + idBearer + "'>X</button>&nbsp&nbsp</td>" +
145070                      "</tr>");
145071
145072                 $("#bearer-btn-" + idBearer).click(function () {
145073                     _bearerRelease(type, idBearer, evNetworkDisconnected);
145074                 });
145075
145076                 $("#bearer-" + type + " tr:even").css("background-color", "white");
145077                 $("#bearer-" + type + " tr:odd").css("background-color", "whitesmoke");
145078             }
145079
145080             event.trigger(evNetworkOpened, [true]);
145081         });
145082
145083         event.on("NetworkRelease", function (networkType, domainName) {
145084             var type = networkType.toLowerCase(),
145085                 name = domainName.replace(/\./, ""),
145086                 idBearer = type + '-' + name,
145087                 evNetworkDisconnected = "ND_" + networkType + "_" + domainName;
145088
145089             _bearerRelease(type, idBearer, evNetworkDisconnected);
145090         });
145091
145092         // Update UI for Flight Mode changing
145093         event.on("FlightModeChanged", function (value) {
145094             if (value === true) {
145095                 $("#cellular-radio1").prop('disabled', true);
145096                 $("#cellular-radio2").prop('disabled', true);
145097                 $("#panel_flight_mode_notice").show();
145098             }
145099             else {
145100                 $("#cellular-radio1").prop('disabled', false);
145101                 $("#cellular-radio2").prop('disabled', false);
145102                 $("#panel_flight_mode_notice").hide();
145103             }
145104
145105             $("#cellular-radio1").button("refresh");
145106             $("#cellular-radio2").button("refresh");
145107         });
145108
145109         $("#bt-adapter-name").text(db.retrieveObject("tizen1-db-bluetooth_adapter-name") || "Tizen BT Adapter");
145110         _btDeviceTemplate = $("#network-bt-template").html();
145111         $("#network-bt-box").empty();
145112         btNodes = jQuery("#network-bt-device-select");
145113         btNodes.html("");
145114
145115         //_btBluetoothDB = dbinit.Bluetooth;
145116         _btBluetoothDB = db.retrieveObject("bt-simulated-devices");
145117         utils.forEach(_btBluetoothDB, function (item, index) {
145118             btNodes.append(utils.createElement("option", {
145119                 "value": index,
145120                 "innerText": item.name
145121             }));
145122         });
145123
145124         jQuery("#network-bt-nearby-btn").click(function () {
145125             var index;
145126             index = jQuery("#network-bt-device-select").val();
145127             if (_btSimulatedDevs[index]) {
145128                 return;
145129             }
145130             _btSimulatedDevs[index] = _btBluetoothDB[index];
145131             db.saveObject("bt-simulated-devices", _btSimulatedDevs);
145132             event.trigger("bt-simulated-devices-changed", []);
145133             _btRender();
145134         });
145135         $(".network-bt-remove-btn").live("click", function () {
145136             _btRemove(this.id);
145137         });
145138         $(".network-bt-send-btn").live("click", function () {
145139             var msg = jQuery("#service-transfer-textarea-" + this.id.replace(/:/g, "")).val(),
145140             uuid = jQuery("#network-bt-uuid-" + this.id.replace(/:/g, "")).html();
145141             event.trigger("bt-service-rawdata-received", [this.id, uuid, msg]);
145142         });
145143         $(".network-bt-service-select").live("change", function () {
145144             var uuid = this.children[this.selectedIndex].value,
145145             index = this.id,
145146             addr,
145147             service;
145148             addr = index.replace(/:/g, "");
145149             service = _btSimulatedDevs[index].services[uuid];
145150             jQuery("#network-bt-uuid-" + index.replace(/:/g, "")).html(service.uuid);
145151             jQuery("#network-bt-protocol-" + index.replace(/:/g, "")).html(service.protocol);
145152             jQuery("#service-state-" + index.replace(/:/g, "")).html(service.state || "CLOSED");
145153             jQuery("#service-transfer-textarea-" + addr).val("");
145154             jQuery("#service-receive-textarea-" + addr).html("");
145155         });
145156
145157         //Default "Tizen Phone" is nearby
145158         //_btSimulatedDevs["00:02:60:00:05:63"] = _btBluetoothDB["00:02:60:00:05:63"];
145159         for (var address in _btBluetoothDB) {
145160             _btSimulatedDevs[address] = _btBluetoothDB[address];
145161             break;
145162         }
145163
145164         db.saveObject("bt-simulated-devices", _btSimulatedDevs);
145165         _btRender();
145166     }
145167 };
145168
145169 });
145170 define('ripple/ui/plugins/nfc', function (require, exports, module) {
145171 /*
145172  *  Copyright 2012 Intel Corporation
145173  *
145174  * Licensed under the Apache License, Version 2.0 (the "License");
145175  * you may not use this file except in compliance with the License.
145176  * You may obtain a copy of the License at
145177  *
145178  * http://www.apache.org/licenses/LICENSE-2.0
145179  *
145180  * Unless required by applicable law or agreed to in writing, software
145181  * distributed under the License is distributed on an "AS IS" BASIS,
145182  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145183  * See the License for the specific language governing permissions and
145184  * limitations under the License.
145185  */
145186
145187 var db = require('ripple/db'),
145188     event = require('ripple/event'),
145189     _NFC_TAG = "tizen1.0-nfc-tag",
145190     _NFC_PEER = "tizen1.0-nfc-peer",
145191     _NFC_OUTPUT_MESSAGE = "tizen1.0-nfc-output-message",
145192     powered = false,
145193     polling = false,
145194     isConnected = false,
145195     _tagNDEF = {
145196         type: "GENERIC_TARGET",
145197         isSupportedNDEF: true,
145198         ndefSize: 2,
145199         ndefs: [{
145200             recordCount: 2,
145201             records: [{
145202                 tnf: 1,
145203                 type: "TypeA",
145204                 id: "ID001",
145205                 payload: "This is 1st payload"
145206             }, {
145207                 tnf: 1,
145208                 type: "TypeA",
145209                 id: "ID002",
145210                 payload: "This is 2nd payload"
145211             }]
145212         },
145213             {
145214             recordCount: 2,
145215             records: [{
145216                 tnf: 1,
145217                 type: "TypeA",
145218                 id: "ID001",
145219                 payload: "This is 1st payload"
145220             }, {
145221                 tnf: 1,
145222                 type: "TypeA",
145223                 id: "ID002",
145224                 payload: "This is 2nd payload"
145225             }]
145226         }]
145227     },
145228     _tagRaw = {
145229         type: "GENERIC_TARGET",
145230         isSupportedNDEF: false,
145231         rawData : ""
145232     },
145233     _peerNDEF = {
145234         ndef: {
145235             recordCount: 2,
145236             records: [{
145237                 tnf: 1,
145238                 type: "TypeA",
145239                 id: "ID001",
145240                 payload: "This is 1st payload"
145241             }, {
145242                 tnf: 1,
145243                 type: "TypeA",
145244                 id: "ID002",
145245                 payload: "This is 2nd payload"
145246             }]
145247         }
145248     };
145249
145250 function elementEnableDisableSetting(prop) {
145251     jQuery("#nfc-attach-msg").text("\xa0");
145252     jQuery("#nfc-peer-send-msg").text("\xa0");
145253     if (prop && prop.power !== undefined && prop.power !== null) {
145254         if (prop.power) {
145255             $("#nfc-polling").removeAttr("disabled");
145256             $("#nfc-main-container").show();
145257         } else {
145258             $("#nfc-polling").attr("disabled", "disabled");
145259             $("#nfc-type").removeAttr("disabled");
145260             $("#nfc-main-container").hide();
145261         }
145262     }
145263     if (prop && prop.connectedState !== undefined && prop.connectedState !== null) {
145264         if (prop.connectedState) {
145265             $("#nfc-type").attr("disabled", "disabled");
145266             $("#nfc-tag-type-text").text($("#nfc-tag-type option:selected").text());
145267             $("#nfc-tag-type").hide();
145268             $("#nfc-tag-type-text").show();
145269             $("#nfc-tag-NDEF-support-text").text($("#nfc-tag-NDEF-support option:selected").text());
145270             $("#nfc-tag-NDEF-support").hide();
145271             $("#nfc-tag-NDEF-support-text").show();
145272             $("#nfc-raw-data").attr("disabled", "disabled");
145273         } else {
145274             $("#nfc-type").removeAttr("disabled");
145275             $("#nfc-tag-type").show();
145276             $("#nfc-tag-type-text").hide();
145277             $("#nfc-tag-NDEF-support").show();
145278             $("#nfc-tag-NDEF-support-text").hide();
145279             $("#nfc-raw-data").removeAttr("disabled");
145280         }
145281     }
145282 }
145283
145284 function _initializeElements() {
145285
145286     jQuery(function () {
145287         var stop = false,
145288             isSupportNDEF, type;
145289
145290         jQuery("nfc-tag-ndef-container h3").click(function (event) {
145291             if (stop) {
145292                 event.stopImmediatePropagation();
145293                 event.preventDefault();
145294                 stop = false;
145295             }
145296         });
145297         jQuery("#nfc-tag-ndef-container").accordion("destroy").accordion({
145298             header: "> div > h3",
145299             autoHeight: false
145300         });
145301         jQuery("nfc-nfcpeer h3").click(function (event) {
145302             if (stop) {
145303                 event.stopImmediatePropagation();
145304                 event.preventDefault();
145305                 stop = false;
145306             }
145307         });
145308         jQuery("#nfc-nfcpeer").accordion("destroy").accordion({
145309             header: "> div > h3",
145310             autoHeight: false
145311         });
145312         jQuery("#nfc-tag-NDEF-support").bind("change", function () {
145313             isSupportNDEF = jQuery("#nfc-tag-NDEF-support").val();
145314             if (isSupportNDEF === "Yes") {
145315                 jQuery("#nfc-tag-ndef-container").fadeIn();
145316                 jQuery("#nfc-tag-raw-container").hide();
145317             } else {
145318                 jQuery("#nfc-tag-ndef-container").hide();
145319                 jQuery("#nfc-tag-raw-container").fadeIn();
145320             }
145321         });
145322         jQuery("#nfc-type").bind("change", function () {
145323             type = jQuery("#nfc-type").val();
145324             if (type === "Tag") {
145325                 jQuery("#nfc-nfctag").fadeIn();
145326                 jQuery("#nfc-nfcpeer").hide();
145327             } else {
145328                 jQuery("#nfc-nfctag").hide();
145329                 jQuery("#nfc-nfcpeer").fadeIn();
145330             }
145331             elementEnableDisableSetting();
145332         });
145333         jQuery("#nfc-power").bind("change", function () {
145334             var status;
145335             status = jQuery("#nfc-power").val() === "On" ? true : false;
145336             event.trigger("nfc-power-setting", [status]);
145337         });
145338         jQuery("#nfc-polling").bind("change", function () {
145339             var status;
145340             status = jQuery("#nfc-polling").val() === "On" ? true : false;
145341             event.trigger("nfc-polling-setting", [status]);
145342         });
145343         jQuery("#nfc-attach").bind("click", function () {
145344             var type, isAttached;
145345             isAttached = jQuery("#nfc-attach").children().text() === "Attach" ? true : false;
145346             jQuery("#nfc-attach-msg").text("\xa0");
145347
145348             if (!polling && isAttached) {
145349                 jQuery("#nfc-attach-msg").text("Polling:Off, attach won't work");
145350                 return;
145351             }
145352             type = jQuery("#nfc-type").val();
145353             event.trigger("nfc-attach-setting", [type, isAttached]);
145354         });
145355         jQuery("#nfc-peer-send").bind("click", function () {
145356             jQuery("#nfc-peer-send-msg").text("\xa0");
145357             if (!isConnected) {
145358                 jQuery("#nfc-peer-send-msg").text("Disconnected. Send won't work");
145359                 return;
145360             }
145361             db.saveObject(_NFC_PEER, _peerNDEF);
145362             event.trigger("nfc-peer-sending-ndef", []);
145363         });
145364     });
145365 }
145366
145367 module.exports = {
145368     panel: {
145369         domId: "nfc-container",
145370         collapsed: true,
145371         pane: "left",
145372         titleName: "NFC",
145373         display: true
145374     },
145375     initialize: function () {
145376         _initializeElements();
145377         event.on("nfc-power-changed", function (status) {
145378             powered = status;
145379             if (powered === true) {
145380                 $("#nfc-power").val("On");
145381             } else {
145382                 $("#nfc-power").val("Off");
145383             }
145384             elementEnableDisableSetting({power: status});
145385         });
145386         event.on("nfc-polling-changed", function (status) {
145387             polling = status;
145388             if (polling === true) {
145389                 $("#nfc-polling").val("On");
145390             } else {
145391                 $("#nfc-polling").val("Off");
145392             }
145393             elementEnableDisableSetting();
145394         });
145395         event.on("nfc-connectedState-changed", function (state) {
145396             var i, type, isSupportedNDEF, str, bytes = [];
145397             isConnected = state;
145398             elementEnableDisableSetting({connectedState: state});
145399             type = jQuery("#nfc-type").val();
145400             if (state) {
145401                 jQuery("#nfc-attach").children().text("Detach");
145402                 jQuery("#nfc-tag-connection").text("Connected");
145403                 jQuery("#nfc-peer-connection").text("Connected");
145404                 if (type === "Tag") {
145405                     isSupportedNDEF = jQuery("#nfc-tag-NDEF-support").val() === "Yes" ? true : false;
145406                     if (isSupportedNDEF) {
145407                         _tagNDEF.type = jQuery("#nfc-tag-type").val();
145408                         db.saveObject(_NFC_TAG, _tagNDEF);
145409                     } else {
145410                         _tagRaw.type = jQuery("#nfc-tag-type").val();
145411                         str = jQuery("#nfc-raw-data").val();
145412                         for (i = 0; i < str.length; i++) {
145413                             bytes.push(str.charCodeAt(i));
145414                         }
145415                         _tagRaw.rawData = bytes;
145416                         db.saveObject(_NFC_TAG, _tagRaw);
145417                     }
145418                     event.trigger("nfc-tag-send", [true]);
145419                 } else {
145420                     event.trigger("nfc-peer-send", [true]);
145421                 }
145422             } else {
145423                 jQuery("#nfc-attach").children().text("Attach");
145424                 jQuery("#nfc-tag-connection").text("Disconnected");
145425                 jQuery("#nfc-peer-connection").text("Disconnected");
145426                 jQuery("#nfc-output").text("");
145427                 jQuery("#nfc-output-table").hide();
145428                 if (type === "Tag") {
145429                     event.trigger("nfc-tag-send", [false]);
145430                 } else {
145431                     event.trigger("nfc-peer-send", [false]);
145432                 }
145433             }
145434         });
145435         event.on("nfc-output-msg", function () {
145436             var msg;
145437             msg = db.retrieve(_NFC_OUTPUT_MESSAGE);
145438             jQuery("#nfc-output").text(msg);
145439             jQuery("#nfc-output-table").show();
145440         });
145441     }
145442 };
145443
145444
145445 });
145446 define('ripple/ui/plugins/notifications', function (require, exports, module) {
145447 /*
145448  *  Copyright 2011 Research In Motion Limited.
145449  *
145450  * Licensed under the Apache License, Version 2.0 (the "License");
145451  * you may not use this file except in compliance with the License.
145452  * You may obtain a copy of the License at
145453  *
145454  * http://www.apache.org/licenses/LICENSE-2.0
145455  *
145456  * Unless required by applicable law or agreed to in writing, software
145457  * distributed under the License is distributed on an "AS IS" BASIS,
145458  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145459  * See the License for the specific language governing permissions and
145460  * limitations under the License.
145461  */
145462
145463 var db = require('ripple/db'),
145464     utils = require('ripple/utils'),
145465     event = require('ripple/event'),
145466     _notificationUIStack,
145467     _notificationTemplate = "";
145468
145469 function _remove(id) {
145470     delete _notificationUIStack[id];
145471     db.saveObject("posted-notifications", _notificationUIStack);
145472     event.trigger("refreshNotificationStack", [], true);
145473     _render();
145474 }
145475
145476 function _removeAll() {
145477     _notificationUIStack = {};
145478     db.saveObject("posted-notifications", _notificationUIStack);
145479     event.trigger("refreshNotificationStack", [], true);
145480     $("#notification-box").empty();
145481     $("#notification-box").append('<div style="color:#666666;">(Empty notification.)</div>');
145482     $("#remove-all-notifications-btn").hide();
145483 }
145484
145485 function _render() {
145486     var notificationHTML = "",
145487         htmlContent = "";
145488
145489     utils.forEach(_notificationUIStack, function (item) {
145490         notificationHTML = _notificationTemplate.replace(/#id/g, item.id)
145491             .replace(/#title/g, item.title)
145492             .replace(/#content/, item.content ? item.content : "")
145493             .replace(/#type/, item.type)
145494             .replace(/#statusType/, item.statusType)
145495             .replace(/#postedTime/, item.postedTime)
145496             .replace(/#iconPath/, item.iconPath ? item.iconPath : "")
145497             .replace(/#subIconPath/, item.subIconPath ? item.subIconPath : "")
145498             .replace(/#number/, item.number ? item.number : "")
145499             .replace(/#detailInfo/, item.detailInfo ? item.detailInfo.join() : "")
145500             .replace(/#backgroundImagePath/, item.backgroundImagePath ? item.backgroundImagePath : "")
145501             .replace(/#thumbnails/, item.thumbnails ? item.thumbnails.join() : "")
145502             .replace(/#soundPath/, item.soundPath ? item.soundPath : "")
145503             .replace(/#vibration/, item.vibration !== undefined ? (item.vibration === true ? "true" : "false") : "")
145504             .replace(/#appControl/, item.appControl ? item.appControl : "")
145505             .replace(/#appId/, item.appId ? item.appId : "")
145506             .replace(/#progressType/g, item.progressType ? item.progressType: "")
145507             .replace(/#progressValue/, (item.statusType === "PROGRESS" && item.progressType === "PERCENTAGE" && item.progressValue) ? item.progressValue.toString() + "%" : "")
145508             .replace(/#progressBarValue/, (item.statusType === "PROGRESS" && item.progressType === "PERCENTAGE" && item.progressValue) ? item.progressValue : 0)
145509             .replace(/#progress2Value/, (item.statusType === "PROGRESS" && item.progressType === "BYTE" && item.progressValue) ? item.progressValue.toString() + " byte(s)" : "")
145510             .replace(/#displayBar/g, (item.statusType !== "PROGRESS" || item.progressType !== "PERCENTAGE") ? "none" : "")
145511             .replace(/#display2Bar/g, (item.statusType !== "PROGRESS" || item.progressType !== "BYTE") ? "none" : "");
145512         htmlContent += notificationHTML;
145513     });
145514
145515     $("#notification-box").accordion("destroy");
145516     $("#notification-box").html(htmlContent).accordion({
145517         active : false,
145518         collapsible : true,
145519         autoHeight : false
145520     });
145521
145522     $("#notification-box .progress-bar").each(function (index, item) {
145523         $(item).width(this.id);
145524     });
145525     if (utils.count(_notificationUIStack) !== 0) {
145526         $("#remove-all-notifications-btn").show();
145527     } else {
145528         $("#remove-all-notifications-btn").hide();
145529     }
145530     $("." + "remove-notification-btn").bind("click", function () {
145531         _remove(this.id);
145532     });
145533 }
145534
145535 module.exports = {
145536     panel: {
145537         domId: "notification-container",
145538         collapsed: true,
145539         pane: "left",
145540         titleName: "Notification",
145541         display: true
145542     },
145543     initialize: function () {
145544         _notificationTemplate = $("#notification-template").html();
145545         $("#notification-box").empty();
145546         _notificationUIStack = db.retrieveObject("posted-notifications") || {};
145547         if (utils.count(_notificationUIStack) === 0) {
145548             $("#notification-box").append('<div style="color:#666666;">(Empty notification.)</div>');
145549         }
145550         else
145551             _render();
145552         $("#remove-all-notifications-btn").bind("click", _removeAll);
145553
145554         event.on("refreshNotificationUI", function () {
145555             _notificationUIStack = db.retrieveObject("posted-notifications");
145556             _render();
145557         });
145558     }
145559 };
145560
145561 });
145562 define('ripple/ui/plugins/omnibar', function (require, exports, module) {
145563 /*
145564  *  Copyright 2011 Research In Motion Limited.
145565  *
145566  * Licensed under the Apache License, Version 2.0 (the "License");
145567  * you may not use this file except in compliance with the License.
145568  * You may obtain a copy of the License at
145569  *
145570  * http://www.apache.org/licenses/LICENSE-2.0
145571  *
145572  * Unless required by applicable law or agreed to in writing, software
145573  * distributed under the License is distributed on an "AS IS" BASIS,
145574  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145575  * See the License for the specific language governing permissions and
145576  * limitations under the License.
145577  */
145578 var emulatorBridge = require('ripple/emulatorBridge'),
145579     platform = require('ripple/platform'),
145580     db = require('ripple/db'),
145581     devices = require('ripple/devices'),
145582     constants = require('ripple/constants'),
145583     _event = require('ripple/event'),
145584     tooltip = require('ripple/ui/plugins/tooltip'),
145585     histories = [];
145586
145587 function _omnibar() {
145588     return document.querySelector(".omni-bar input");
145589 }
145590
145591 function _persist(url) {
145592     db.save("current-url", url);
145593 }
145594
145595 function _persistRoot(url) {
145596     db.save("root-url", url);
145597 }
145598
145599 function _currentURL() {
145600     return db.retrieve("current-url") || "about:blank";
145601 }
145602
145603 function _rootURL() {
145604     return db.retrieve("root-url") || "about:blank";
145605 }
145606
145607 function _reload() {
145608     _event.trigger("ApplicationLoad", null);
145609     emulatorBridge.window().location.reload();
145610 }
145611
145612 function _loadApplication() {
145613     var omnibar = _omnibar(),
145614             xhr;
145615     if (omnibar.value.trim() !== "") {
145616         if (_currentURL().match(/^file:/) && omnibar.value.match(/^file:/)) { // Use ajax to know whether that file exists
145617             xhr = new XMLHttpRequest();
145618             xhr.onreadystatechange = function () {
145619                 if (xhr.readyState === 4) {
145620                     if (xhr.responseText !== '') {
145621                         _persist(omnibar.value);
145622                         _persistRoot(omnibar.value);
145623                         emulatorBridge.window().location.assign(omnibar.value);
145624                     } else {
145625                         alert("File doesn't exist!");
145626                         return;
145627                     }
145628                 }
145629             };
145630             xhr.open('GET', omnibar.value, true);
145631             xhr.send(null);
145632         } else {
145633             omnibar.value = omnibar.value.indexOf("://") < 0 ? "http://" + omnibar.value : omnibar.value;
145634             _persist(omnibar.value);
145635             _persistRoot(omnibar.value);
145636             emulatorBridge.window().location.assign(omnibar.value);
145637         }
145638         _addHistory(omnibar.value);
145639     }
145640     _event.trigger("ApplicationLoad", null);
145641 }
145642
145643 function _hideHistory() {
145644     $("#app-launching-history").hide("slide", {direction: "up"}, "fast");
145645     $("#overlayBackground-transparent").hide();
145646 }
145647
145648 function _makeHistoryItems() {
145649     histories = db.retrieveObject(constants.LAUNCHING_HISTORY);
145650     if (histories === undefined) {
145651         histories = [];
145652     }
145653     $("#app-launching-history").empty();
145654     histories.reverse();
145655     histories.forEach(function (item) {
145656         $("#app-launching-history").append('<div class="app-launching-history-item">' + item + '</div>');
145657     });
145658
145659     if (histories.length === 0) {
145660         $("#app-launching-history").append('<div class="app-launching-history-item-empty">History empty</div>');
145661     }
145662
145663     $(".app-launching-history-item").unbind('click');
145664     $(".app-launching-history-item").bind("click", function () {
145665         $(".omni-bar input").val(histories[$(this).index()]);
145666         _loadApplication();
145667         _hideHistory();
145668     });
145669 }
145670
145671
145672 function _showHistory() {
145673     _makeHistoryItems();
145674     $("#app-launching-history").css("width", $(".omni-bar input").width() + 20);
145675     $("#app-launching-history").show("slide", {direction: "up"}, "fast");
145676     $(window).bind('resize', function () {
145677         $("#app-launching-history").css("width", $(".omni-bar input").width() + 20);
145678         $("#overlayBackground-transparent").css("width", $(window).width());
145679         $("#overlayBackground-transparent").css("height", $(window).height());
145680     });
145681
145682     $("#history-background-overlay").show();
145683     $("#overlayBackground-transparent").css("width", $(window).width());
145684     $("#overlayBackground-transparent").css("height", $(window).height());
145685     $("#overlayBackground-transparent").show();
145686     $("#overlayBackground-transparent").unbind('click');
145687     $("#overlayBackground-transparent").bind("click", function () {
145688         _hideHistory();
145689     });
145690 }
145691
145692
145693 function _addHistory(uri) {
145694     var i = 0, thehistories = db.retrieveObject(constants.LAUNCHING_HISTORY);
145695     if (thehistories !== undefined) {
145696         for (i; i < thehistories.length; i++) {
145697             if (uri === thehistories[i]) {
145698                 return;
145699             }
145700         }
145701         if (thehistories.length >= 20) {
145702             thehistories.reverse();
145703             thehistories.pop();
145704             thehistories.reverse();
145705         }
145706     } else {
145707         thehistories = [];
145708     }
145709     thehistories.push(uri);
145710     db.saveObject(constants.LAUNCHING_HISTORY, thehistories);
145711 }
145712
145713 _event.on("FrameHistoryChange", function (url) {
145714     _omnibar().value = url;
145715     _persist(url);
145716     _persistRoot(url);
145717 });
145718
145719 function _getUrlParams(url) {
145720     var params = {};
145721
145722     url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(str, key, value) {
145723         params[key] = value;
145724     });
145725
145726     return params;
145727 }
145728
145729 module.exports = {
145730     initialize: function () {
145731         var omnibar = _omnibar(), loc, tmp,
145732             url, filename, matching, deviceId,
145733             xhr, uriParams, platformName, platformVersion, newUrl;
145734
145735         jQuery(".logo, .beta, .left, .right, .left-panel-collapse, .right-panel-collapse").css({
145736             "marginTop": "35px"
145737         });
145738
145739         jQuery("#settings-xhr-proxy").parent().parent().hide();
145740
145741         $(".omni-bar").show();
145742
145743         uriParams = _getUrlParams(document.documentURI);
145744         if (uriParams.platform !== undefined) {
145745             platformName = uriParams.platform.split("-")[0];
145746
145747             if (platformName === "mobile" || platformName === "tizen") {
145748                 platformName = "tizen";
145749                 platformVersion = "2.0";
145750             }
145751             else {
145752                 platformName = "ivi";
145753                 platformVersion = "3.0";
145754             }
145755
145756             if (platform.current().id !== platformName) {
145757                 deviceId = devices.getCurrentDevice().id;
145758                 if (deviceId == "CUSTOM") {
145759                     deviceId = "custom";
145760                 }
145761
145762                 platform.changeEnvironment({
145763                     "name": platformName,
145764                     "version": platformVersion
145765                 }, deviceId, function () {
145766                     window.tinyHipposReload = true;
145767                     newUrl = location.href.replace(/&platform=(.+?)-(.+?)$/, "&platform=" + platformName + "-" + platformVersion);
145768                     location.href = newUrl;
145769                     //location.reload();
145770                 });
145771             }
145772         }
145773
145774         if (uriParams.url !== undefined) {
145775             url = uriParams.url;
145776             if (url.match(/^\.[\.]?/) !== null) {
145777                 loc = document.location;
145778                 filename = loc.pathname.replace(/^.*[\\\/]/, '');
145779                 matching = new RegExp(filename, "g");
145780                 tmp = loc.protocol + "//" + loc.hostname + loc.pathname.replace(matching, "") + url;
145781                 url = tmp;
145782             }
145783             _persist(url);
145784             _persistRoot(url);
145785             require('ripple/widgetConfig').initialize();
145786             require('ripple/ui/plugins/widgetConfig').initialize();
145787         }
145788
145789         omnibar.value = _currentURL();
145790
145791         omnibar.addEventListener("keydown", function (event) {
145792             if (event.keyCode === '13' || event.keyCode === 13 || event.keyCode === '0' || event.keyCode === 0) { // enter or return
145793                 if (omnibar.value.trim() !== "") {
145794                     if (_currentURL().match(/^file:/) && omnibar.value.match(/^file:/)) { // Use ajax to know whether that file exists
145795                         xhr = new XMLHttpRequest();
145796                         xhr.onreadystatechange = function () {
145797                             if (xhr.readyState === 4) {
145798                                 if (xhr.responseText !== '') {
145799                                     _persist(omnibar.value);
145800                                     _persistRoot(omnibar.value);
145801                                     emulatorBridge.window().location.assign(omnibar.value);
145802                                 } else {
145803                                     alert("File doesn't exist!");
145804                                     return;
145805                                 }
145806                             }
145807                         };
145808                         xhr.open('GET', omnibar.value, true);
145809                         xhr.send(null);
145810                     } else {
145811                         //default the protocal if not provided
145812                         omnibar.value = omnibar.value.indexOf("://") < 0 ? "http://" + omnibar.value : omnibar.value;
145813                         _persist(omnibar.value);
145814                         _persistRoot(omnibar.value);
145815                         emulatorBridge.window().location.assign(omnibar.value);
145816                     }
145817                     _event.trigger("ApplicationLoad", null);
145818                     _addHistory(omnibar.value);
145819                 }
145820             }
145821         });
145822
145823         window.addEventListener("keydown", function (event) {
145824             var hasMetaOrAltPressed = (event.metaKey || event.ctrlKey),
145825                 key = parseInt(event.keyCode, 10);
145826
145827             if (key === 82 && hasMetaOrAltPressed) { // cmd/ctrl + r
145828                 event.preventDefault();
145829                 _reload();
145830             }
145831
145832             if (key === 116) { // F5
145833                 event.preventDefault();
145834                 _reload();
145835             }
145836         });
145837
145838         document.getElementById("history-reload").addEventListener("click", _reload);
145839         $("#options-button-history").bind("click", function () {
145840             _showHistory();
145841         });
145842         tooltip.create("#history-reload", "Reload Application");
145843         tooltip.create("#options-button-history", "History");
145844         tooltip.create("#options-button-config-window", "Configuration");
145845         tooltip.create("#options-button-panels", "Panel Settings");
145846         tooltip.create("#options-button-about", "About");
145847     },
145848     currentURL: function () {
145849         return _currentURL();
145850     },
145851     rootURL: function () {
145852         return _rootURL();
145853     }
145854 };
145855
145856 });
145857 define('ripple/ui/plugins/options', function (require, exports, module) {
145858 /*
145859  *  Copyright 2011 Research In Motion Limited.
145860  *
145861  * Licensed under the Apache License, Version 2.0 (the "License");
145862  * you may not use this file except in compliance with the License.
145863  * You may obtain a copy of the License at
145864  *
145865  * http://www.apache.org/licenses/LICENSE-2.0
145866  *
145867  * Unless required by applicable law or agreed to in writing, software
145868  * distributed under the License is distributed on an "AS IS" BASIS,
145869  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145870  * See the License for the specific language governing permissions and
145871  * limitations under the License.
145872  */
145873 var about = require('ripple/ui/plugins/about-dialog'),
145874     settings = require('ripple/ui/plugins/settings-dialog'),
145875     tooltip = require('ripple/ui/plugins/tooltip'),
145876     hide,
145877     show;
145878
145879 show = function () {
145880     if (settings.value("remoteInspector")) {
145881         $("#options-menu-build-warning").show();
145882         tooltip.create("#options-menu-build-warning", "Remote Web Inspector should be disabled when packaging for App World release");
145883     }
145884     else {
145885         $("#options-menu-build-warning").hide();
145886     }
145887
145888     $("#options-window").show();
145889     $("#options-menu").show();
145890 };
145891
145892 hide = function () {
145893     $("#options-window").hide();
145894     $("#options-menu").effect("fade", {}, 300);
145895 };
145896
145897 module.exports = {
145898     initialize: function () {
145899         $("#options-menu").menu().hide();
145900         $("#options-menu").bind("click", function (event) {
145901             var target = $("#" + event.target.parentElement.id),
145902                 action;
145903
145904             if (target.hasClass("not-ready")) {
145905                 return;
145906             }
145907
145908             switch (target.attr("id")) {
145909             case "options-menu-build":
145910             case "options-menu-launch":
145911             case "options-menu-sign":
145912                 action = target.attr("id").split("-")[2];
145913                 if (!settings.can(action)) {
145914                     settings.show(action);
145915                 }
145916                 else {
145917                     settings.perform(action);
145918                 }
145919                 break;
145920             case "options-menu-about":
145921                 about.show();
145922                 break;
145923             case "options-menu-settings":
145924                 settings.show();
145925                 break;
145926             default:
145927                 break;
145928             }
145929             hide();
145930         });
145931
145932         $("#options-window").click(hide);
145933         
145934         $("#options-button-about").bind("click", function (event) {
145935             about.show();
145936         });
145937         
145938         hide();
145939     }
145940 };
145941
145942 });
145943 define('ripple/ui/plugins/package', function (require, exports, module) {
145944 /*
145945  *  Copyright 2011 Research In Motion Limited.
145946  *
145947  * Licensed under the Apache License, Version 2.0 (the "License");
145948  * you may not use this file except in compliance with the License.
145949  * You may obtain a copy of the License at
145950  *
145951  * http://www.apache.org/licenses/LICENSE-2.0
145952  *
145953  * Unless required by applicable law or agreed to in writing, software
145954  * distributed under the License is distributed on an "AS IS" BASIS,
145955  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145956  * See the License for the specific language governing permissions and
145957  * limitations under the License.
145958  */
145959
145960 var db = require('ripple/db'),
145961     utils = require('ripple/utils'),
145962     event = require('ripple/event'),
145963     dbinit = require('ripple/platform/tizen/2.0/dbinit'),
145964     PackageInformation = require('ripple/platform/tizen/2.0/PackageInformation'),
145965     DB_PACKAGE_KEY = "tizen-db-package",
145966     _data = {
145967         packageList: {},
145968         installedList: {}
145969     },
145970     _currentPackageId = null,
145971     _packages,
145972     _installedList,
145973     _packageListTemplate,
145974     _packageInstalledTemplate;
145975
145976 function _get() {
145977     _data = db.retrieveObject(DB_PACKAGE_KEY);
145978     if (_data === undefined) {
145979         _data = {
145980             packageList: _packages,
145981             installedList: _installedList
145982         };
145983     }
145984     utils.forEach(_data.installedList, function (item) {
145985         item.lastModified = new Date(item.lastModified);
145986     });
145987 }
145988
145989 function _save() {
145990     db.saveObject(DB_PACKAGE_KEY, _data);
145991 }
145992
145993 function loadPackageList() {
145994     var nodes = jQuery("#package-list-select");
145995     nodes.html("");
145996     utils.forEach(_data.packageList, function (item, index) {
145997         nodes.append(utils.createElement("option", {
145998             "value": index,
145999             "innerText": item.name
146000         }));
146001     });
146002     renderPackageListBox($("#package-list-select option:selected").val());
146003 }
146004
146005 function loadInstalledList() {
146006     var html = "";
146007     jQuery("#package-installed-box").empty();
146008     utils.forEach(_data.installedList, function (item) {
146009         html += _packageInstalledTemplate.replace(/#Name/g, item.name)
146010             .replace(/#ID/g, item.id)
146011             .replace(/#IconPath/, item.iconPath)
146012             .replace(/#Version/, item.version)
146013             .replace(/#TotalSize/, item.totalSize)
146014             .replace(/#DataSize/, item.dataSize)
146015             .replace(/#LastModified/, item.lastModified)
146016             .replace(/#Author/, item.author)
146017             .replace(/#Description/, item.description)
146018             .replace(/#APPIDs/, item.appIds.join("<br>"));
146019     });
146020     $("#package-installed-box").accordion("destroy");
146021     $("#package-installed-box").html(html).accordion({
146022         active: false,
146023         collapsible: true,
146024         autoHeight: false
146025     });
146026     $("." + "package-remove-btn").bind("click", function () {
146027         var id = this.id;
146028         if (id === _currentPackageId) {
146029             $("#msg-" + id).html("Can't Uninstall:<br> Package including running app");
146030             setTimeout(function () {
146031                 $("#msg-" + id).text("");
146032             }, 5000);
146033             return;
146034         }
146035         utils.forEach(_data.packageList, function (item) {
146036             if (item.id === id) {
146037                 event.trigger("remove-apps", [item.appIds]);
146038             }
146039         });
146040         delete _data.installedList[this.id];
146041         _save();
146042         loadPackageList();
146043         loadInstalledList();
146044         event.trigger("uninstall-package", [this.id]);
146045     });
146046 }
146047
146048 function renderPackageListBox(path) {
146049     var item, html;
146050     jQuery("#package-list-box").empty();
146051     item = _data.packageList[path];
146052     html = _packageListTemplate.replace(/#Path/, path)
146053         .replace(/#ID/, item.id)
146054         .replace(/#Name/, item.name)
146055         .replace(/#IconPath/, item.iconPath)
146056         .replace(/#Version/, item.version)
146057         .replace(/#TotalSize/, item.totalSize)
146058         .replace(/#DataSize/, item.dataSize)
146059         .replace(/#Author/, item.author)
146060         .replace(/#Description/, item.description)
146061         .replace(/#APPList/, item.appIds.join("<br>"));
146062     jQuery("#package-list-box").html(html);
146063     if (_data.installedList[item.id]) {
146064         jQuery("#package-update-btn").show();
146065     } else {
146066         jQuery("#package-install-btn").show();
146067     }
146068 }
146069
146070 function addPackage(path, type) {
146071     var item;
146072     if (!_data.packageList[path]) {
146073         return;
146074     }
146075     item = _data.packageList[path];
146076     _data.installedList[item.id] = new PackageInformation(
146077         item.id, item.name, item.iconPath, item.version,
146078         item.totalSize, item.dataSize, new Date(),
146079         item.author, item.description, item.appIds
146080     );
146081     if (type === "install") {
146082         event.trigger("install-apps", [item.appIds]);
146083     } else {
146084         event.trigger("update-apps", [item.appIds]);
146085     }
146086     _save();
146087 }
146088
146089 module.exports = {
146090     panel: {
146091         domId: "package-container",
146092         collapsed: true,
146093         pane: "left",
146094         titleName: "Packages and Applications",
146095         display: true
146096     },
146097     initialize: function () {
146098         _packages = dbinit.Package.packages;
146099         _installedList = dbinit.Package.installedList;
146100         _packageListTemplate = jQuery("#package-list-template").html();
146101         _packageInstalledTemplate = jQuery("#package-installed-template").html();
146102
146103         _get();
146104         _save();
146105         loadPackageList();
146106         loadInstalledList();
146107         jQuery("#package-list-select").bind("focus change", function () {
146108             var path = $("#package-list-select option:selected").val();
146109             renderPackageListBox(path);
146110         });
146111         jQuery("#package-install-btn").live("click", function () {
146112             var path = $("#package-list-select option:selected").val();
146113             addPackage(path, "install");
146114             _get();
146115             loadPackageList();
146116             loadInstalledList();
146117             event.trigger("install-packge", [path]);
146118         });
146119         jQuery("#package-update-btn").live("click", function () {
146120             var path = $("#package-list-select option:selected").val();
146121             addPackage(path, "update");
146122             loadPackageList();
146123             loadInstalledList();
146124             event.trigger("update-package", [path]);
146125         });
146126         jQuery("#package-select").tabs();
146127         event.on("installedList-updated", function () {
146128             _get();
146129             loadPackageList();
146130             loadInstalledList();
146131         });
146132         event.on("install-current-package", function (item) {
146133             _data.installedList[item.id] = new PackageInformation(
146134                 item.id, item.name, item.iconPath, item.version,
146135                 item.totalSize, item.dataSize, item.lastModified,
146136                 item.author, item.description, item.appIds);
146137             _currentPackageId = item.id;
146138             loadInstalledList();
146139         });
146140     }
146141 };
146142
146143 });
146144 define('ripple/ui/plugins/panelCollapse', function (require, exports, module) {
146145 /*
146146  *  Copyright 2011 Research In Motion Limited.
146147  *
146148  * Licensed under the Apache License, Version 2.0 (the "License");
146149  * you may not use this file except in compliance with the License.
146150  * You may obtain a copy of the License at
146151  *
146152  * http://www.apache.org/licenses/LICENSE-2.0
146153  *
146154  * Unless required by applicable law or agreed to in writing, software
146155  * distributed under the License is distributed on an "AS IS" BASIS,
146156  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146157  * See the License for the specific language governing permissions and
146158  * limitations under the License.
146159  */
146160 // TODO: could use a bit of refactoring sugar
146161 var db = require('ripple/db'),
146162     constants = require('ripple/constants'),
146163     _LEFT_PANEL_COLLAPSE = ".left-panel-collapse",
146164     _RIGHT_PANEL_COLLAPSE = ".right-panel-collapse",
146165     _LEFT_PANEL = ".left",
146166     _RIGHT_PANEL = ".right",
146167     _SAVE_KEY = "panel-collapsed",
146168     platform = require('ripple/platform'),
146169     devices = require('ripple/devices'),
146170     _leftEngaged, _rightEngaged, _store;
146171
146172
146173 $(function () { 
146174     $(window).resize(function () {
146175         var windowHeight = $(window).height();
146176         jQuery(".PanelCollapseBar").css("top", windowHeight - 56);
146177         jQuery("#left_div").css("height", $(window).height() - 21);
146178         if (_store["left"] === true) {
146179             jQuery("#middle_div").css("width", $(window).width());
146180         } else {
146181             jQuery("#middle_div").css("width", $(window).width());
146182         }
146183     });
146184 });
146185
146186
146187 function _persist() {
146188     db.saveObject(_SAVE_KEY, _store);
146189 }
146190
146191
146192 function updateZoomingValues(value, origin) {
146193     var scaleFactor = value / 100, scaleString;
146194     scaleString = "scale(" + scaleFactor + ")";
146195     jQuery('#device-layout').css('-webkit-transform', scaleString);
146196     if (origin === "center") {
146197         jQuery('#device-layout').css('-webkit-transform-origin', 'center top');
146198     } else {
146199         jQuery('#device-layout').css('-webkit-transform-origin', 'left top');
146200     }
146201 }
146202
146203
146204 function _process(collapseNode, panelNode, side, callback) {
146205     var jNode = collapseNode.children("span"),
146206         jPanelNode = jQuery(panelNode),
146207         properties = {},
146208         collapseProperties = {},
146209         options = {
146210             duration: 600,
146211             complete: callback
146212         },
146213         oldIcon, newIcon,
146214         zoomingValue =  db.retrieve(constants.ENCAPSULATOR.ZOOMING);
146215
146216     if (_store[side] === true) {
146217         _store[side] = false;
146218         
146219         if (side === "left") {
146220             jQuery('#left_div').show("fast");
146221             collapseNode.removeClass("PanelCollapseBarCollapsed");
146222             collapseNode.addClass("PanelCollapseBar");
146223             collapseNode.children().remove();
146224             collapseNode.append('<img src="images/sideCollapseIconLeftSide.png" style="margin-left:330px; margin-top: 6px;"/>');
146225             collapseNode.css("top", $(window).height() - 56);
146226             collapseNode.css("left", 0);
146227             jQuery("#middle_div").css("width", $(window).width());
146228             updateZoomingValues(zoomingValue, "left");
146229         }
146230         oldIcon = (side === "left" ? "ui-icon-arrowthick-1-e" : "ui-icon-arrowthick-1-w");
146231         newIcon = (side === "left" ? "ui-icon-arrowthick-1-w" : "ui-icon-arrowthick-1-e");
146232
146233         properties[side] = "0px";
146234         collapseProperties[side] = "345px";
146235         properties.opacity = "1";
146236
146237         if (jQuery("#device-layout").position().left < 290 ) {
146238             jQuery("#device-layout").animate({left: "350px"}, 200 );
146239         }
146240     } else {
146241         _store[side] = true;
146242         
146243         if (side === "left") {
146244             collapseNode.removeClass("PanelCollapseBar");
146245             collapseNode.addClass("PanelCollapseBarCollapsed");
146246             collapseNode.children().remove();
146247             collapseNode.append('<img src="images/sideCollapseIconRightSide.png" style="position: absolute; margin-left:5px; margin-top:48%;"/>');
146248             collapseNode.css("top", 10);
146249             collapseNode.css("left", 0);
146250             collapseNode.css("margin-left", 0);
146251             jQuery('#left_div').hide("slow");
146252             jQuery("#middle_div").css("width", $(window).width());
146253             updateZoomingValues(zoomingValue, "left");
146254         }
146255
146256         oldIcon = (side === "left" ? "ui-icon-arrowthick-1-w" : "ui-icon-arrowthick-1-e");
146257         newIcon = (side === "left" ? "ui-icon-arrowthick-1-e" : "ui-icon-arrowthick-1-w");
146258
146259         properties[side] = "-340px";
146260         collapseProperties[side] = "5px";
146261         properties.opacity = "0.1";
146262     }
146263
146264     jNode.removeClass(oldIcon).addClass(newIcon);
146265
146266     jPanelNode.animate(properties, options);
146267     _persist();
146268 }
146269
146270 module.exports = {
146271     initialize: function () {
146272         var rightCollapseNode = jQuery(_RIGHT_PANEL_COLLAPSE),
146273             leftCollapseNode = jQuery(_LEFT_PANEL_COLLAPSE),
146274             device = devices.getCurrentDevice(),
146275             zoomingValue =  db.retrieve(constants.ENCAPSULATOR.ZOOMING),
146276             deviceNode = jQuery("#device-layout");
146277            
146278         _store = db.retrieveObject(_SAVE_KEY) || {
146279             left: false,
146280             right: false
146281         };
146282
146283         jQuery("#left_div").css("height", $(window).height() - 21);
146284         jQuery("#middle_div").css("width", $(window).width());
146285
146286         jQuery("#device-container").bind("mousedown", function () {
146287             jQuery("#device-maskmask").show();
146288         });
146289
146290         jQuery("#device-container").bind("mouseup", function () {
146291             jQuery("#device-maskmask").hide();
146292         });
146293
146294         jQuery("#deviceTitleBar").bind("mousedown", function () {
146295             jQuery("#device-maskmask").show();
146296         });
146297
146298         jQuery("#deviceTitleBar").bind("mouseup", function () {
146299             jQuery("#device-maskmask").hide();
146300         });
146301
146302         deviceNode.draggable({ cursor: 'move', handle: "#deviceTitleBar", containment: [0, 52, 1280, 800]});
146303         jQuery("#deviceTitle").text(device.name);
146304         if (_store.left === true) {
146305             jQuery(_LEFT_PANEL).css({
146306                 left: "-340px",
146307                 opacity: "0.1"
146308             });
146309
146310             leftCollapseNode.removeClass("PanelCollapseBar");
146311             leftCollapseNode.addClass("PanelCollapseBarCollapsed");
146312             leftCollapseNode.children().remove();
146313             leftCollapseNode.append('<img src="images/sideCollapseIconRightSide.png" style="position: absolute; margin-left:5px; margin-top:48%;"/>');
146314             leftCollapseNode.css("top", 10);
146315             leftCollapseNode.css("left", 0);
146316             leftCollapseNode.css("margin-left", 0);
146317             jQuery('#left_div').hide();
146318             jQuery("#device-layout").css("left", "21px");
146319             updateZoomingValues(zoomingValue, "left");
146320         } else {
146321             jQuery('#left_div').show("fast");
146322             leftCollapseNode.removeClass("PanelCollapseBarCollapsed");
146323             leftCollapseNode.addClass("PanelCollapseBar");
146324             leftCollapseNode.children().remove();
146325             leftCollapseNode.append('<img src="images/sideCollapseIconLeftSide.png" style="margin-left:330px; margin-top: 6px;"/>');
146326             leftCollapseNode.css("top", $(window).height() - 56);
146327             leftCollapseNode.css("left", 0);
146328             jQuery("#device-layout").css("left", "350px");
146329             updateZoomingValues(zoomingValue, "left");
146330         }   
146331
146332         if (_store.right === true) {
146333             jQuery(_RIGHT_PANEL).css({
146334                 right: "-340px",
146335                 opacity: "0.1"
146336             });
146337
146338             rightCollapseNode.css({
146339                 right: "5px"
146340             }).children("span").removeClass("ui-icon-arrowthick-1-e").addClass("ui-icon-arrowthick-1-w");
146341         }
146342
146343         leftCollapseNode.bind("click", function () {
146344             if (!_leftEngaged) {
146345                 _leftEngaged = true;
146346                 _process(leftCollapseNode, _LEFT_PANEL, "left", function () {
146347                     _leftEngaged = false;
146348                 });
146349             }
146350         });
146351
146352         rightCollapseNode.bind("click", function () {
146353             if (!_rightEngaged) {
146354                 _rightEngaged = true;
146355                 _process(rightCollapseNode, _RIGHT_PANEL, "right", function () {
146356                     _rightEngaged = false;
146357                 });
146358             }
146359         });
146360     }
146361 };
146362
146363 });
146364 define('ripple/ui/plugins/phone', function (require, exports, module) {
146365 /*
146366  *  Copyright 2011 Research In Motion Limited.
146367  *
146368  * Licensed under the Apache License, Version 2.0 (the "License");
146369  * you may not use this file except in compliance with the License.
146370  * You may obtain a copy of the License at
146371  *
146372  * http://www.apache.org/licenses/LICENSE-2.0
146373  *
146374  * Unless required by applicable law or agreed to in writing, software
146375  * distributed under the License is distributed on an "AS IS" BASIS,
146376  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146377  * See the License for the specific language governing permissions and
146378  * limitations under the License.
146379  */
146380 var utils = require('ripple/utils'),
146381     Phone = require('ripple/platform/webworks.handset/2.0.0/client/Phone'),
146382     CallLog = require('ripple/platform/webworks.handset/2.0.0/client/CallLog'),
146383     event = require('ripple/event'),
146384     _console = require('ripple/console'),
146385     eventSelect = document.getElementById("phone-event-types"),
146386     eventErrorContainer = document.getElementById("phone-event-error-container"),
146387     eventErrorSelect = document.getElementById("phone-event-error-types");
146388
146389 function _firePhoneLogEvents(type, number, error) {
146390     if (type === Phone.CB_CALL_INITIATED ||
146391         type === Phone.CB_CALL_ANSWERED) {
146392         event.trigger("PhoneCallLogAdded", [{
146393             date: new Date(),
146394             number: number,
146395             status: CallLog.STATUS_NORMAL,
146396             type: CallLog.TYPE_RECEIVED_CALL
146397         }], true);
146398     } else if (type === Phone.CB_CALL_ENDED_BYUSER ||
146399                 type === Phone.CB_CALL_FAILED) {
146400         event.trigger("PhoneCallLogAdded", [{
146401             date: new Date(),
146402             number: number,
146403             status: CallLog.STATUS_NORMAL,
146404             type: CallLog.TYPE_PLACED_CALL
146405         }], true);
146406     }
146407 }
146408
146409 function _updateActiveCalls(type, number, error) {
146410     if (type === Phone.CB_CALL_INITIATED ||
146411         type === Phone.CB_CALL_CONNECTED ||
146412         type === Phone.CB_CALL_CONFERENCECALL_ESTABLISHED ||
146413         type === Phone.CB_CALL_DIRECTCONNECT_CONNECTED ||
146414         type === Phone.CB_CALL_ANSWERED) {
146415         event.trigger("PhoneCallInitiated", [{
146416             id: number,
146417             onhold: false,
146418             outgoing: false,
146419             recipient: {
146420                 name: "",
146421                 number: String(number)
146422             }
146423         }], true);
146424     } else if (type === Phone.CB_CALL_ENDED_BYUSER ||
146425                 type === Phone.CB_CALL_FAILED ||
146426                 type === Phone.CB_CALL_DISCONNECTED ||
146427                 type === Phone.CB_CONFERENCECALL_DISCONNECTED ||
146428                 type === Phone.CB_CALL_DIRECTCONNECT_DISCONNECTED) {
146429         event.trigger("PhoneCallEnded", [{
146430             id: number
146431         }], true);
146432     }
146433 }
146434
146435 module.exports = {
146436     panel: {
146437         domId: "phone-container",
146438         collapsed: true,
146439         pane: "right"
146440     },
146441     initialize: function (prev, baton) {
146442         utils.forEach(Phone, function (value, prop) {
146443             if (prop.match(/^CB_/)) {
146444                 eventSelect.appendChild(utils.createElement("option", {
146445                     value: value,
146446                     innerHTML: prop.replace(/^CB_(CALL_)?/, "")
146447                 }));
146448             }
146449
146450             if (prop.match(/^CALL_ERROR_/)) {
146451                 eventErrorSelect.appendChild(utils.createElement("option", {
146452                     value: value,
146453                     innerHTML: prop.replace(/^CALL_ERROR_/, "")
146454                 }));
146455             }
146456         });
146457
146458         document.getElementById("phone-event-types").addEventListener("change", function () {
146459             eventErrorContainer.setAttribute("style", parseInt(eventSelect.value, 10) === Phone.CB_CALL_FAILED ? "" : "display: none");
146460         });
146461
146462         document.getElementById("phone-logs-clear").addEventListener("click", function () {
146463             event.trigger("PhoneCallLogReset");
146464         });
146465
146466         document.getElementById("phone-event-send").addEventListener("click", function () {
146467             var type = parseInt(eventSelect.value, 10),
146468                 error = type === Phone.CB_CALL_FAILED ? eventErrorSelect.value : undefined,
146469                 callId = document.getElementById("phone-call-id").value;
146470
146471             _firePhoneLogEvents(type, callId, error);
146472             _updateActiveCalls(type, callId, error);
146473
146474             event.trigger("PhoneEvent", [type, callId, error]);
146475
146476             _console.log("Fired PhoneEvent (type " + type +  ") CallID: " +
146477                          callId + (error ? (" (error type " + error + ")") : ""));
146478         }, false);
146479     }
146480 };
146481
146482 });
146483 define('ripple/ui/plugins/platform', function (require, exports, module) {
146484 /*
146485  *  Copyright 2011 Research In Motion Limited.
146486  *
146487  * Licensed under the Apache License, Version 2.0 (the "License");
146488  * you may not use this file except in compliance with the License.
146489  * You may obtain a copy of the License at
146490  *
146491  * http://www.apache.org/licenses/LICENSE-2.0
146492  *
146493  * Unless required by applicable law or agreed to in writing, software
146494  * distributed under the License is distributed on an "AS IS" BASIS,
146495  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146496  * See the License for the specific language governing permissions and
146497  * limitations under the License.
146498  */
146499 var constants = require('ripple/constants'),
146500     utils = require('ripple/utils'),
146501     devices = require('ripple/devices'),
146502     platform = require('ripple/platform'),
146503     db = require('ripple/db');
146504
146505 function _updatePlatformDeviceSelect(platformID, currentDeviceKey) {
146506     var devicesSelect = document.getElementById(constants.COMMON.DEVICE_SELECT_ID),
146507         listOfSortedDevices = devices.getDevicesForPlatform(platformID)
146508                                         .sort(function (a, b) {
146509                                             return (a.screen.width * a.screen.height) < (b.screen.width * b.screen.height) ? -1 : ((a.screen.width * a.screen.height) > (b.screen.width * b.screen.height) ? 1 : 0);
146510                                         });
146511     db.remove("viewport_width");
146512     db.remove("viewport_height");
146513     db.remove("viewportTag");
146514
146515     devicesSelect.innerHTML = "";
146516     listOfSortedDevices.forEach(function (dev) {
146517         var deviceNode = utils.createElement("option", {
146518             "innerText": dev.name,
146519             "value": dev.id
146520         });
146521
146522         if (currentDeviceKey && deviceNode.value === currentDeviceKey) {
146523             deviceNode.selected = true;
146524         }
146525
146526         devicesSelect.appendChild(deviceNode);
146527     });
146528
146529     if (platformID === "ivi") {
146530         jQuery("#configuration-window-save-btn").hide();
146531         jQuery("#configuration-window-load-btn").hide();
146532
146533         jQuery("#item_container :nth-child(2)").hide();
146534         jQuery("#item_container :nth-child(3)").hide();
146535     }
146536     else {
146537         jQuery("#configuration-window-save-btn").show();
146538         jQuery("#configuration-window-load-btn").show();
146539
146540         jQuery("#item_container :nth-child(2)").show();
146541         jQuery("#item_container :nth-child(3)").show();
146542     }
146543 }
146544
146545 function checkResolutionSize(evt) {
146546         var query_str, id_str, len;
146547         query_str = "#resolution-custom-" + evt.data.msg;
146548         id_str = "custom_" + evt.data.msg;
146549         len = jQuery(query_str).val();
146550         if (len >= 200 && len <= 2000) {
146551                 db.save(id_str, len);
146552         } else {
146553                 jQuery(query_str).val(db.retrieve(id_str));
146554         }
146555 }
146556
146557 module.exports = {
146558     initialize: function () {
146559         var currentPlatform = platform.current().id,
146560             currentVersion = platform.current().version,
146561             platformList = platform.getList(),
146562             platformSelect = document.getElementById(constants.COMMON.PLATFORM_SELECT_ID),
146563             versionSelect = document.getElementById("version-select"),
146564             currentDeviceKey = devices.getCurrentDevice().id,
146565             platformNode, versionNode;
146566
146567         jQuery("#platform-select").bind("change", function () {
146568             var newPlatform = jQuery(this).val(),
146569                 newDevice = jQuery("#device-select").val();
146570
146571             jQuery(versionSelect).children("option").remove();
146572             utils.forEach(platformList, function (platform) {
146573                 utils.forEach(platform, function (version, versionNumber) {
146574                     if (newPlatform === version.id) {
146575                         versionSelect.appendChild(utils.createElement("option", {
146576                             "innerText": version.text,
146577                             "value":  versionNumber
146578                         }));
146579                     }
146580                 });
146581             });
146582             _updatePlatformDeviceSelect(newPlatform, newDevice);
146583
146584         });
146585
146586         jQuery("#device-select").bind("focus", function () {
146587             $('input:radio[name="resolution-type"][value="predefined"]').click();
146588         });
146589         jQuery("#resolution-custom-width").bind("focus", function () {
146590             $('input:radio[name="resolution-type"][value="custom"]').click();
146591         });
146592         jQuery("#resolution-custom-height").bind("focus", function () {
146593             $('input:radio[name="resolution-type"][value="custom"]').click();
146594         });
146595         jQuery("#resolution-custom-width").bind("change", {msg: "width"}, checkResolutionSize);
146596         jQuery("#resolution-custom-height").bind("change", {msg: "height"}, checkResolutionSize);
146597
146598         utils.forEach(platformList, function (platform, platformKey) {
146599             platformNode = utils.createElement("option", {
146600                 "innerText": platformKey === "tizen" ? "mobile": platformKey,
146601                 "value":  platformKey
146602             });
146603
146604             utils.forEach(platform, function (version, versionNumber) {
146605                 versionNode = utils.createElement("option", {
146606                     "innerText": version.text,
146607                     "value":  versionNumber
146608                 });
146609
146610                 if (currentPlatform && version.id === currentPlatform) {
146611                     versionSelect.appendChild(versionNode);
146612                     if (currentVersion && currentVersion === versionNumber) {
146613                         platformNode.selected = true;
146614                         versionNode.selected = true;
146615                     }
146616                 }
146617             });
146618             platformSelect.appendChild(platformNode);
146619         });
146620
146621         _updatePlatformDeviceSelect(currentPlatform, currentDeviceKey);
146622     }
146623 };
146624
146625 });
146626 define('ripple/ui/plugins/platformEvents', function (require, exports, module) {
146627 /*
146628  *  Copyright 2011 Research In Motion Limited.
146629  *
146630  * Licensed under the Apache License, Version 2.0 (the "License");
146631  * you may not use this file except in compliance with the License.
146632  * You may obtain a copy of the License at
146633  *
146634  * http://www.apache.org/licenses/LICENSE-2.0
146635  *
146636  * Unless required by applicable law or agreed to in writing, software
146637  * distributed under the License is distributed on an "AS IS" BASIS,
146638  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146639  * See the License for the specific language governing permissions and
146640  * limitations under the License.
146641  */
146642 var _console = require('ripple/console'),
146643     platform = require('ripple/platform'),
146644     event = require('ripple/event'),
146645     exception = require('ripple/exception'),
146646     utils = require('ripple/utils');
146647
146648 module.exports = {
146649     panel: {
146650         domId: "platform-events-container",
146651         collapsed: true,
146652         pane: "right",
146653         titleName: "Platform Events",
146654         display: true
146655     },
146656     initialize: function () {
146657         var eventSelect = document.getElementById("platform-events-select"),
146658             spec = platform.current();
146659
146660         if (!spec.events) {
146661             return;
146662         }
146663
146664         utils.forEach(spec.events, function (method, name) {
146665             eventSelect.appendChild(utils.createElement("option", {
146666                 "innerText": name,
146667                 "value": name
146668             }));
146669         });
146670
146671         jQuery("#platform-events-fire").click(function () {
146672             var eventName = document.getElementById("platform-events-select").value,
146673                 args = spec.events[eventName].args ? document.getElementById("platform-events-args").value : null,
146674                 callback = spec.events[eventName].callback;
146675
146676             _console.log("fired event => " + eventName);
146677
146678             try {
146679                 callback(args);
146680             } catch (e) {
146681                 exception.throwMaskedException(e);
146682             }
146683         });
146684
146685         jQuery(eventSelect).change(function () {
146686             var argsSelect = jQuery("#platform-events-args"),
146687                 args = spec.events[this.value].args;
146688
146689             argsSelect.empty();
146690
146691             if (args) {
146692                 utils.forEach(spec.events[this.value].args, function (arg, index) {
146693                     argsSelect.append(utils.createElement("option", {
146694                         innerText: arg,
146695                         value: index
146696                     }));
146697                 });
146698
146699                 argsSelect.show();
146700             } else {
146701                 argsSelect.hide();
146702             }
146703         });
146704     }
146705 };
146706
146707 });
146708 define('ripple/ui/plugins/power', function (require, exports, module) {
146709 /*
146710  *  Copyright 2012 Intel Corporation
146711  *
146712  * Licensed under the Apache License, Version 2.0 (the "License");
146713  * you may not use this file except in compliance with the License.
146714  * You may obtain a copy of the License at
146715  *
146716  * http://www.apache.org/licenses/LICENSE-2.0
146717  *
146718  * Unless required by applicable law or agreed to in writing, software
146719  * distributed under the License is distributed on an "AS IS" BASIS,
146720  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146721  * See the License for the specific language governing permissions and
146722  * limitations under the License.
146723  */
146724
146725 var db = require('ripple/db'),
146726     event = require('ripple/event'),
146727     constants = require('ripple/constants'),
146728     _volume  = document.getElementById(constants.BATTERY.VOLUME),
146729     _volumeLabel  = document.getElementById(constants.BATTERY.VOLUME + "-label"),
146730     _charging = document.getElementById(constants.BATTERY.CHARGING),
146731     _battery = {
146732         volume: 600,
146733         level:  1.0,
146734         timerId: null,
146735         charge: function (isStart, isCharge, callback) {
146736             var currentVolume,
146737                 checkValue = function () {
146738                     if (_battery.level < 0 || _battery.level > 1.0 || !isStart) {
146739                         clearInterval(_battery.timerId);
146740                         _battery.timerId = null;
146741                         if (_battery.level < 0)
146742                             _battery.level = 0;
146743                         else if (_battery.level > 1.0)
146744                             _battery.level = 1.0;
146745                     }
146746                 };
146747
146748             if (isStart && !_battery.timerId) {
146749                 _battery.timerId = setInterval(function () {
146750                     currentVolume = isCharge ? _battery.level * _battery.volume + 1 : _battery.level * _battery.volume - 1;
146751                     _battery.level = currentVolume / _battery.volume;
146752                     checkValue();
146753                     return callback && callback();
146754                 }, 1000);
146755             }
146756             checkValue();
146757             return callback && callback();
146758         }
146759     };
146760
146761 function _triggerEvent(chargingStatus, chargingTime, dischargingTime, level, type) {
146762     var status = {
146763         charging: chargingStatus,
146764         chargingTime: chargingTime,
146765         dischargingTime: dischargingTime,
146766         level: level,
146767         type: type
146768     };
146769     event.trigger("BatteryEvent", [status]); // for w3c battery api
146770     // for tizen systeminfo api
146771     if (type === "levelchange") {
146772         event.trigger("BatteryLevelChanged", [level]);
146773     }
146774     if (type === "chargingchange") {
146775         event.trigger("BatteryChargingChanged", [status]);
146776     }
146777 }
146778
146779 function _updateLevelIcons() {
146780     var colors = ["black", "black", "black", "black", "black", "black", "#404040", "#606060", "#808080", "#b0b0b0", "#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff"],
146781         colorIndex = 10 - Math.round(_battery.level * 10),
146782         index;
146783
146784     //map the battery level to the color range
146785     for (index = 0 ; index <= 5 ; index++) {
146786         $("#block" + index).css("backgroundColor", colors[colorIndex]);
146787         colorIndex++;
146788     }
146789 }
146790
146791 function _setVolumeReadOnly(flag) {
146792     if (flag) {
146793         $("#" + constants.BATTERY.VOLUME).hide();
146794         $("#" + constants.BATTERY.VOLUME + "-label").show();
146795     } else {
146796         $("#" + constants.BATTERY.VOLUME).show();
146797         $("#" + constants.BATTERY.VOLUME + "-label").hide();
146798     }
146799 }
146800
146801 function _startDischarging() {
146802     var remainVolume = 0;
146803
146804     if ($("#simulate-low-battery #low-battery-remain-time").val() <= 0) {
146805         $("#simulate-low-battery #low-battery-remain-time").val(0);
146806     }
146807     remainVolume = Number($("#simulate-low-battery #low-battery-remain-time").val());
146808     if ($("#simulate-low-battery #low-battery-start-at").val() > 100) {
146809         $("#simulate-low-battery #low-battery-start-at").val(100);
146810     }
146811     if ($("#simulate-low-battery #low-battery-start-at").val() <= 0) {
146812         $("#simulate-low-battery #low-battery-start-at").val(0);
146813     }
146814     _battery.level = $("#simulate-low-battery #low-battery-start-at").val() / 100.0;
146815     if (_battery.level === 0 || remainVolume === 0) {
146816         $("#simulate-low-battery").dialog("close");
146817         _stopDischarging();
146818         return;
146819     }
146820     _setVolumeReadOnly(true);
146821     if (_charging.checked) {
146822         _charging.checked = false;
146823         _battery.charge(false);
146824     }
146825
146826     _charging.disabled = true;
146827     $("#remaining-time-label").html("Remaining Time to empty (seconds)");
146828     $("#charging-state").html("Plugged in?");
146829
146830     $("#remain-time").show();
146831     _battery.volume = remainVolume / _battery.level;
146832     _volumeLabel.innerText = (_battery.level * 100).toFixed(2);
146833     _battery.charge(true, false, function () {
146834         _volumeLabel.innerText = (_battery.level * 100).toFixed(2);
146835         _volume.value = (_battery.level * 100).toFixed(2);
146836         changeBatteryVolume();
146837         $("#remain-time").html(Math.round(_battery.volume * _battery.level) + " Seconds");
146838         _updateLevelIcons();
146839         if (_battery.level <= 0.0) {
146840             _stopDischarging();
146841         }
146842     });
146843     $("#simulate-low-battery").dialog("close");
146844     $("#simulate-low-battery-btn").hide();
146845     $("#stop-btn").show();
146846     _triggerEvent(false, Infinity, Math.round(_battery.volume * _battery.level), _battery.level, "chargingtimechange");
146847 }
146848
146849 function _stopDischarging() {
146850     _charging.disabled = false;
146851     _battery.level = _volume.value / 100.0;
146852     $("#remain-time").hide();
146853     $("#remain-time").html("");
146854     $("#remaining-time-label").html("Remaining Time (seconds)");
146855     _setVolumeReadOnly(false);
146856     _battery.charge(false);
146857     $("#simulate-low-battery-btn").show();
146858     $("#stop-btn").hide();
146859     _updateLevelIcons();
146860 }
146861
146862 function _setCharging() {
146863     // update the UI parts
146864     if (_charging.checked) {
146865         _battery.volume = 600;
146866         _battery.level = _volume.value / 100;
146867         _setVolumeReadOnly(true);
146868         $("#remain-time").show();
146869         $("#remaining-time-label").html("Remaining Time to fully charged (seconds)");
146870         $("#charging-state").html("Plugged in - charging rate 0.17%/second");
146871         _triggerEvent(true, Math.round(_battery.volume * (1 - _battery.level)), Infinity, _battery.level, "chargingchange");
146872     } else {
146873         _battery.level = _volume.value / 100.0;
146874         _updateLevelIcons();
146875         $("#remain-time").hide();
146876         $("#remain-time").html("");
146877         _setVolumeReadOnly(false);
146878         $("#remaining-time-label").html("Remaining Time (seconds)");
146879         $("#charging-state").html("Plugged in?");
146880         _triggerEvent(false, Infinity, Math.round(_battery.volume * _battery.level), _battery.level, "chargingchange");
146881     }
146882     // if it's unchecked, the timer will stop in this function call, the UI update blow it
146883     _battery.charge(_charging.checked, true, function () {
146884         _volumeLabel.innerText = (_battery.level * 100).toFixed(2);
146885         _volume.value = (_battery.level * 100).toFixed(2);
146886         changeBatteryVolume();
146887         $("#remain-time").html(Math.round(_battery.volume * (1 - _battery.level)) + " Seconds");    //show current remain time
146888         _updateLevelIcons();
146889     });
146890 }
146891
146892 function changeBatteryVolume() {
146893     if (_volume.value < 0)
146894         _volume.value = 0;
146895     else if (_volume.value > 100)
146896         _volume.value = 100;
146897
146898     _battery.level = _volume.value / 100.0;
146899     if (_charging.checked === true) {
146900         _triggerEvent(true, Math.round(_battery.volume * (1 - _battery.level)), Infinity, _battery.level, "levelchange");
146901     } else {
146902         _triggerEvent(false, Infinity, Math.round(_battery.volume * _battery.level), _battery.level, "levelchange");
146903     }
146904     db.save(constants.BATTERY.VOLUME, _volume.value);
146905     _updateLevelIcons();
146906 }
146907
146908 function initBattery() {
146909     $("#" + constants.BATTERY.CHARGING).bind("change", _setCharging);
146910
146911     $("#simulate-low-battery-btn").bind("click", function () {
146912         $("#simulate-low-battery").dialog("open");
146913     });
146914
146915     $("#simulate-low-battery-cancel").bind("click", function () {
146916         $("#low-battery-start-at").val = 20;  //UI initialize
146917         $("#low-battery-remain-time").val = 1200;
146918         $("#simulate-low-battery").dialog("close");
146919     });
146920
146921     $("#simulate-low-battery-start").bind("click", _startDischarging);
146922     $("#stop-btn").bind("click", _stopDischarging);
146923
146924     $("#" + constants.BATTERY.VOLUME).bind("change", function () {
146925         changeBatteryVolume();
146926     });
146927
146928     _charging.checked = false;
146929     _battery.level = db.retrieve(constants.BATTERY.VOLUME) / 100.0;
146930     if (isNaN(_battery.level)) {
146931         _battery.level = 1;
146932     }
146933     _volume.value = (_battery.level * 100).toFixed(2);
146934     _updateLevelIcons();
146935     $("#simulate-low-battery").dialog({
146936         resizable: false,
146937         draggable: true,
146938         modal: true,
146939         autoOpen: false,
146940         position: 'center',
146941         minWidth: '460',
146942         minHeight: '240'
146943     });
146944 }
146945
146946 module.exports = {
146947     panel: {
146948         domId: "power-container",
146949         collapsed: true,
146950         pane: "left",
146951         titleName: "Power Manager",
146952         display: true
146953     },
146954
146955     initialize: function () {
146956         initBattery();
146957     }
146958 };
146959
146960 });
146961 define('ripple/ui/plugins/push', function (require, exports, module) {
146962 /*
146963  *  Copyright 2011 Research In Motion Limited.
146964  *
146965  * Licensed under the Apache License, Version 2.0 (the "License");
146966  * you may not use this file except in compliance with the License.
146967  * You may obtain a copy of the License at
146968  *
146969  * http://www.apache.org/licenses/LICENSE-2.0
146970  *
146971  * Unless required by applicable law or agreed to in writing, software
146972  * distributed under the License is distributed on an "AS IS" BASIS,
146973  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146974  * See the License for the specific language governing permissions and
146975  * limitations under the License.
146976  */
146977 var constants = require('ripple/constants'),
146978     event = require('ripple/event'),
146979     utils = require('ripple/utils'),
146980     db = require('ripple/db'),
146981     PUSH_OPTIONS = constants.PUSH.OPTIONS;
146982
146983 function _updatePushPanel(ports) {
146984     var portsSelect = document.getElementById("port-select"),
146985         currentPort = portsSelect.value;
146986
146987     portsSelect.innerHTML = "";
146988
146989     ports.forEach(function (port) {
146990         portsSelect.appendChild(utils.createElement("option", {
146991             innerText: port,
146992             value: port,
146993             selected: currentPort === port
146994         }));
146995     });
146996 }
146997
146998 module.exports = {
146999     panel: {
147000         domId: "push-container",
147001         collapsed: true,
147002         pane: "left"
147003     },
147004     initialize: function () {
147005         event.on("PushListenersChanged", function (listeners) {
147006             _updatePushPanel(listeners);
147007             jQuery("#port-select").effect("highlight", {color: "#62B4C8"}, 1000);
147008         });
147009
147010         _updatePushPanel([]);
147011
147012         document.getElementById("push-send")
147013             .addEventListener("click", function () {
147014                 var port = document.getElementById("port-select").value,
147015                     text = document.getElementById(PUSH_OPTIONS.PAYLOAD).value,
147016                     pushData = {
147017                         headerField: ["21f39092"],
147018                         requestURI: "/",
147019                         source: "ripple",
147020                         isChannelEncrypted: false,
147021                         payload: text
147022                     };
147023
147024                 event.trigger("Push", [pushData, port], true);
147025             }, false);
147026
147027         utils.bindAutoSaveEvent(jQuery("#" + PUSH_OPTIONS.PAYLOAD), function () {
147028             db.save(PUSH_OPTIONS.PAYLOAD, document.getElementById(PUSH_OPTIONS.PAYLOAD).value);
147029         });
147030
147031         document.getElementById(PUSH_OPTIONS.PAYLOAD).value = db.retrieve(PUSH_OPTIONS.PAYLOAD) || "My payload data";
147032     }
147033 };
147034
147035 });
147036 define('ripple/ui/plugins/sensorSettings', function (require, exports, module) {
147037 /*
147038  *  Copyright 2012 Intel Corporation.
147039  *
147040  * Licensed under the Apache License, Version 2.0 (the "License");
147041  * you may not use this file except in compliance with the License.
147042  * You may obtain a copy of the License at
147043  *
147044  * http://www.apache.org/licenses/LICENSE-2.0
147045  *
147046  * Unless required by applicable law or agreed to in writing, software
147047  * distributed under the License is distributed on an "AS IS" BASIS,
147048  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147049  * See the License for the specific language governing permissions and
147050  * limitations under the License.
147051  */
147052
147053 var constants = require('ripple/constants'),
147054     sensorSettings = require('ripple/sensorSettings'),
147055     utils = require('ripple/utils'),
147056     exception = require('ripple/exception'),
147057     platform = require('ripple/platform'),
147058     _CONST = {
147059         "CONTENT_CONTAINER_ID": "sensorsettings-content-container",
147060         "UKNOWN_CONTROL_MESSAGE": "Unknown sensor control type"
147061     },
147062     _contentContainer,
147063     _CONTAINER_ID = _CONST.CONTENT_CONTAINER_ID;
147064
147065 function _appendSettingNode(labelNode, inputNode, label) {
147066     var frag = document.createDocumentFragment(),
147067         rowNode = frag.appendChild(utils.createElement("tr")),
147068         tempTdNode;
147069
147070     rowNode.appendChild(utils.createElement("td"))
147071            .appendChild(labelNode);
147072
147073     tempTdNode = rowNode.appendChild(utils.createElement("td"));
147074
147075     if (label) {
147076         tempTdNode.appendChild(label);
147077     }
147078
147079     tempTdNode.appendChild(inputNode);
147080
147081     return frag;
147082 }
147083
147084 function _buildDOMNode(setting, settingType, key) {
147085     var settingsNode, tagName, jNode,
147086         fullKey = settingType + "." + key,
147087         savedSetting = sensorSettings.retrieve(fullKey),
147088         // TODO: move this into Utils (isSet method)
147089         currentSetting = (savedSetting || savedSetting === false || savedSetting === "" || savedSetting === 0) ? savedSetting : setting.control.value,
147090         domNode,
147091         domNodeLabel = null;
147092
147093     switch (setting.control.type) {
147094     case "text":
147095     case "number":
147096     case "range":
147097     case "checkbox":
147098         tagName = "input";
147099         break;
147100     case "textarea":
147101         tagName = "textarea";
147102         break;
147103     case "select":
147104         tagName = "select";
147105         break;
147106     default:
147107         exception.raise(exception.types.Application, _CONST.UKNOWN_CONTROL_MESSAGE);
147108     }
147109
147110     settingsNode = utils.createElement(tagName, setting.control.type === "select" ? null : setting.control);
147111
147112     // TODO: this should really be part of utils.createControl? add element of type "range" with label?
147113     if (setting.control.type === "range") {
147114         domNodeLabel = utils.createElement("label", {
147115             "class": constants.UI.LEFT_RANGE_LABEL_CLASS
147116         });
147117     }
147118
147119     domNode = _appendSettingNode(utils.createElement("span", {"innerText": setting.name, "class": constants.UI.TEXT_LABEL_CLASS}), settingsNode, domNodeLabel);
147120
147121     jNode = jQuery(settingsNode);
147122     jNode.addClass(constants.UI.JQUERY_UI_INPUT_CLASSES);
147123
147124     switch (setting.control.type) {
147125     case "checkbox":
147126         jNode.bind("click", function () {
147127             var checked = this.checked ? true : false;
147128             sensorSettings.persist(fullKey, checked);
147129             if (typeof setting.callback === "function") {
147130                 setting.callback(checked);
147131             }
147132         });
147133
147134         if (currentSetting === true) {
147135             jNode.attr("checked", "checked");
147136         }
147137
147138         break;
147139
147140     case "text":
147141     case "textarea":
147142     case "number":
147143         jNode.val(currentSetting);
147144         utils.bindAutoSaveEvent(jNode, function () {
147145             sensorSettings.persist(fullKey, jNode.val());
147146             if (typeof setting.callback === "function") {
147147                 setting.callback(jNode.val());
147148             }
147149         });
147150         break;
147151
147152     case "select":
147153     case "range":
147154         if (setting.control.type === "select") {
147155             utils.forEach(setting.options,  function (value, option) {
147156                 jNode.append(utils.createElement("option", {
147157                     "value": option,
147158                     "innerText": value
147159                 }));
147160             });
147161         }
147162         else {
147163             if (domNodeLabel) {
147164                 domNodeLabel.innerText = currentSetting;
147165             }
147166         }
147167
147168         jNode.val(currentSetting)
147169              .bind("change", function () {
147170                 if (setting.control.type === "range" && domNodeLabel) {
147171                     domNodeLabel.innerText = jQuery(this).val();
147172                 }
147173                 sensorSettings.persist(fullKey, jQuery(this).val());
147174
147175                 if (typeof setting.callback === "function") {
147176                     setting.callback(jQuery(this).val());
147177                 }
147178             }
147179         );
147180     }
147181
147182     // TODO: Brent, do in DeviceSettings on load instead?
147183     if (currentSetting !== setting.control.value) {
147184         sensorSettings.register(fullKey, currentSetting);
147185     }
147186
147187     return domNode;
147188 }
147189
147190 // goes through current platforms sensor settings
147191 // adds nodes to panel and binds respective events
147192 // talks to SensorSettings for persistence
147193 module.exports = {
147194     panel: {
147195         domId: "sensors-panel-container",
147196         collapsed: true,
147197         pane: "right",
147198         titleName: "Sensors",
147199         display: true
147200     },
147201     initialize: function () {
147202         var settings;
147203
147204         _contentContainer = document.getElementById(_CONTAINER_ID);
147205
147206         settings = platform.current().sensor;
147207
147208         utils.forEach(settings, function (settingSection, settingType) {
147209
147210             var currentTableNode, flag = false;
147211             
147212             utils.forEach(settingSection, function (setting, key) {
147213                 if (typeof setting === "object") {
147214                     flag = true;
147215                     return;
147216                 }
147217             });
147218
147219             if (flag) {
147220                 _contentContainer.appendChild(utils.createElement("h3", { "innerText": settingType }));
147221             }
147222
147223             currentTableNode = utils.createElement("table", {
147224                 "class": constants.UI.PANEL_TABLE_CLASS
147225             });
147226
147227             _contentContainer.appendChild(currentTableNode);
147228
147229             utils.forEach(settingSection, function (setting, key) {
147230                 if (typeof setting === "object") {
147231                     currentTableNode.appendChild(_buildDOMNode(setting, settingType, key));
147232                 }
147233
147234             });
147235         });
147236     }
147237 };
147238
147239 });
147240 define('ripple/ui/plugins/sensors', function (require, exports, module) {
147241 /*
147242  * Copyright (c) 2010 Epic Train Hack
147243  * Copyright (c) 2011 Research In Motion Limited
147244  * Contributors: Wolfram Kriesing, Dan Silivestru, Brent Lintner
147245  *
147246  * 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:
147247  *
147248  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
147249  *
147250  * 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.
147251  */
147252 var event = require('ripple/event'),
147253     accelerometer = require('ripple/accelerometer'),
147254     deviceSettings = require('ripple/deviceSettings'),
147255     Acceleration = require('ripple/platform/w3c/1.0/Acceleration'),
147256     Rotation = require('ripple/platform/w3c/1.0/Rotation'),
147257     sensorSettings = require('ripple/sensorSettings'),
147258     _oldX, _oldY, _oldAlphaX,
147259     _camera, _scene, _renderer, _mesh,
147260     _offsets = {
147261         x: 0,
147262         y: 0,
147263         z: -9.81,
147264     },
147265     _flag, // whether the browser supports webGL
147266     _shape =
147267         //
147268         // The front side
147269         //
147270         // x, y, z      x, y, z         x, y, z
147271         // for some strange reason for y -100 is top, 100 is bottom
147272         "-30,30,10,     30,30,10,       30,60,10,       100,100,100,-1,0;" + // top left, top right, bottom right - of the right triangle
147273         "-30,30,10,     30,60,10,       -30,60,10,      100,100,100,-1,0;" + // top left, right bottom, left bottom - of the left triangle
147274         // front side "the phone display"
147275         "-20,-50,11,    20,-50,11,      20,20,11,       100,100,100,-1,0;" +
147276         "-20,-50,11,    20,20,11,       -20,20,11,      100,100,100,-1,0;" +
147277         // below the display
147278         "-30,30,10,     30,20,10,       30,30,10,       0,0,0,-1,0;" +
147279         "-30,30,10,     -30,20,10,      30,20,10,       0,0,0,-1,0;" +
147280         // above the display
147281         "-30,-60,10,    30,-60,10,      30,-50,10,      0,0,0,-1,0;" +
147282         "-30,-60,10,    30,-50,10,      -30,-50,10,     0,0,0,-1,0;" +
147283         // left of the display
147284         "-30,-50,10,    -20,-50,10,     -20,20,10,      0,0,0,-1,0;" +
147285         "-30,-50,10,    -20,20,10,      -30,20,10,      0,0,0,-1,0;" +
147286         // right of the display
147287         "20,-50,10,     30,-50,10,      30,20,10,       0,0,0,-1,0;" +
147288         "20,-50,10,     30,20,10,       20,20,10,       0,0,0,-1,0;" +
147289
147290
147291         // back side, opposite side to the above one
147292         "-30,-60,-10,   30,60,-10,      30,-60,-10,     0,0,0,-1,0;" +
147293         "-30,-60,-10,   -30,60,-10,     30,60,-10,      0,00,-1,0;" +
147294         // right side
147295         "30,-60,-10,    30,60,-10,      30,60,10,       50,50,80,-1,0;" +
147296         "30,-60,-10,    30,60,10,       30,-60,10,      50,50,80,-1,0;" +
147297         // left side
147298         "-30,-60,-10,   -30,60,10,      -30,60,-10,     50,50,80,-1,0;" +
147299         "-30,-60,-10,   -30,-60,10,     -30,60,10,      50,50,80,-1,0;" +
147300
147301         // top
147302         "30,-60,-10,    -30,-60,10, -30,-60,-10,    50,80,50,-1,0;" +
147303         "30,-60,-10,    30,-60,10,      -30,-60,10, 50,80,50,-1,0;" +
147304         // bottom
147305         "30,60,-10, -30,60,-10,     -30,60,10,      80,50,50,-1,0;" +
147306         "30,60,-10, -30,60,10,      30,60,10,       80,50,50,-1,0";
147307
147308 function _createThreeDModel() {
147309     var node,
147310         shader,
147311         hemiLight,
147312         dirLight,
147313         material,
147314         uniforms,
147315         container,
147316         loader,
147317         directionalLight,
147318         isDiffuseTextureLoaded,
147319         isNormalTextureLoaded,
147320         shiftKeyDown,
147321         mouseDown,
147322         ctrlKeyDown = false;
147323
147324     if (_flag) {
147325         // create a 3D phone model with three.js if webGL is supported
147326         node = document.getElementById("accelerometer-div");
147327         container = document.createElement("div");
147328         $("#accelerometer-div").append(container);
147329
147330         _camera = new THREE.PerspectiveCamera(50, 1.5, 0.1, 100);
147331         _camera.position.set(4.32823, 3.74714, 2.62985);
147332         _scene = new THREE.Scene();
147333         _scene.add(new THREE.AmbientLight(0xffffff));
147334         directionalLight = new THREE.DirectionalLight(0xffffff, 1);
147335         directionalLight.position.set(1, 1, 1).normalize();
147336         _scene.add(directionalLight);
147337         hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6);
147338         hemiLight.color.setHSV(0.6, 0.75, 1);
147339         hemiLight.groundColor.setHSV(0.095, 0.5, 1);
147340         hemiLight.position.set(0, 500, 0);
147341         _scene.add(hemiLight);
147342         dirLight = new THREE.DirectionalLight(0xffffff, 1);
147343         dirLight.color.setHSV(0.1, 0.1, 1);
147344         dirLight.position.set(-1, 1.75, 1);
147345         dirLight.position.multiplyScalar(50);
147346         _scene.add(dirLight);
147347         shader = THREE.ShaderSkin["skin"];
147348         uniforms = THREE.UniformsUtils.clone(shader.uniforms);
147349         uniforms["tNormal"].value = THREE.ImageUtils.loadTexture("images/phoneMap_tNormal.png", {}, function () {
147350             isNormalTextureLoaded = true;
147351             if (isDiffuseTextureLoaded) {
147352                 _renderer.clear();
147353                 _renderer.render(_scene, _camera);
147354             }
147355         });
147356         uniforms["uNormalScale"].value = 0.75;
147357         uniforms["tDiffuse"].value = THREE.ImageUtils.loadTexture("images/phoneMap_tDiffuse.png", {}, function () {
147358             isDiffuseTextureLoaded = true;
147359             if (isNormalTextureLoaded) {
147360                 _renderer.clear();
147361                 _renderer.render(_scene, _camera);
147362             }
147363         });
147364         uniforms["uDiffuseColor"].value.setHex(0xbbbbbb);
147365         uniforms["uSpecularColor"].value.setHex(0x070707);
147366         uniforms["uAmbientColor"].value.setHex(0x111111);
147367         uniforms["uRoughness"].value = 0.185;
147368         uniforms["uSpecularBrightness"].value = 0.8;
147369         material = new THREE.ShaderMaterial({ fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true });
147370         loader = new THREE.JSONLoader(true);
147371         document.body.appendChild(loader.statusDomElement);
147372
147373         loader.load("phoneModel.js", function (geometry) {
147374             loader.statusDomElement.style.display = "none";
147375             geometry.computeTangents();
147376             _mesh = new THREE.Mesh(geometry, material);
147377             _mesh.position.set(7, 2, -50);
147378             _mesh.scale.set(18, 12, 18);
147379             _scene.add(_mesh);
147380             _renderer.clear();
147381             _renderer.render(_scene, _camera);
147382         });
147383
147384         _renderer = new THREE.WebGLRenderer({antialias: false});
147385         _renderer.setSize(300, 280);
147386         _renderer.setClearColorHex(0xffffff, 1);
147387         _renderer.autoClear = false;
147388
147389         container.appendChild(_renderer.domElement);
147390     } else { // create the model with 3d.js
147391         node = document.querySelector("#accelerometer-canvas");
147392
147393         jQuery("#accelerometer-div").css("display", "none");
147394         jQuery("#accelerometer-canvas").css("display", "block");
147395         ThreeDee.setCenter(150, 100);
147396         ThreeDee.setLight(-300, -300, 800);
147397         _updateCanvas(0, 0);
147398     }
147399
147400     //change accelerometer and phone by moving the mouse and the key "shift"
147401     node.addEventListener("mousemove", function (event) {
147402         var cosX, sinX, cosY, sinY,
147403             alpha = accelerometer.getInfo().orientation.alpha,
147404             beta = accelerometer.getInfo().orientation.beta,
147405             gamma = accelerometer.getInfo().orientation.gamma,
147406             x = accelerometer.getInfo().acceleration.x,
147407             y = accelerometer.getInfo().acceleration.y,
147408             z = accelerometer.getInfo().acceleration.z;
147409
147410         if (!mouseDown) {
147411             return;
147412         }
147413
147414         // if the shift key is pressed down, only the alpha value will be chagned
147415         if (!shiftKeyDown) {
147416             _offsets.x = (_offsets.x + _oldX - event.offsetX) % 360;
147417             _offsets.y = (_offsets.y + _oldY - event.offsetY) % 360;
147418
147419             alpha = alpha || 0;
147420
147421             // enforce gamma in [-90,90] as per w3c spec
147422             gamma = -_offsets.x;
147423             if (gamma < -90) {
147424                 gamma = -90;
147425             }
147426             if (gamma > 90) {
147427                 gamma = 90;
147428             }
147429
147430             // enforce beta in [-180,180] as per w3c spec
147431             beta = -_offsets.y % 360;
147432             if (beta < -180) {
147433                 beta += 360;
147434             }
147435             else if (beta >= 180) {
147436                 beta -= 360;
147437             }
147438
147439             cosX = Math.cos(gamma * (Math.PI / 180));
147440             sinX = Math.sin(gamma * (Math.PI / 180));
147441             cosY = Math.cos(beta * (Math.PI / 180));
147442             sinY = Math.sin(beta * (Math.PI / 180));
147443             x = 9.81 * cosY * sinX;
147444             y = -9.81 * sinY;
147445             z = -9.81 * cosY * cosX;
147446
147447         } else {
147448             alpha = (alpha - (_oldAlphaX - event.offsetX) * 2.5) % 360;
147449         }
147450         _oldX = event.offsetX;
147451         _oldY = event.offsetY;
147452         _oldAlphaX = event.offsetX;
147453         if (_flag)
147454             _updatePhoneModel(alpha, beta, gamma);
147455         else
147456             _updateCanvas(alpha, -beta, gamma);
147457         accelerometer.setInfo({
147458             x: x,
147459             y: y,
147460             z: z,
147461             alpha: alpha,
147462             beta: beta,
147463             gamma: gamma
147464         });
147465     }, false);
147466
147467     node.addEventListener("mousedown", function (e) {
147468         mouseDown = true;
147469         _oldX = e.offsetX;
147470         _oldY = e.offsetY;
147471         if (shiftKeyDown) {
147472             _oldAlphaX = _oldX;
147473         }
147474     });
147475
147476     node.addEventListener("mouseup", function () {
147477         mouseDown = false;
147478     });
147479
147480     document.addEventListener("mouseup", function () {
147481         //Catch mouseup events that fire when outside canvas bounds
147482         mouseDown = false;
147483     });
147484
147485     document.addEventListener("keydown", function (e) {
147486         switch (e.keyCode) {
147487         case 16:                // Shift Key
147488             shiftKeyDown = true;
147489             break;
147490         case 17:                // Ctrl Key
147491             ctrlKeyDown = true;
147492             break;
147493         case 74:                // J Key
147494             if (shiftKeyDown && ctrlKeyDown) { //if shift+ctrl+j keydown in the meantime, console comes up rather than shift key down
147495                 shiftKeyDown = false;
147496                 ctrlKeyDown = false;
147497             }
147498             break;
147499         }
147500     });
147501
147502     document.addEventListener("keyup", function (e) {
147503         if (e.keyCode === 16) { // Shift Key
147504             shiftKeyDown = false;
147505         }
147506     });
147507 }
147508
147509 // update the 3d model created by 3d.js
147510 function _updateCanvas(a, b, g) {
147511     ThreeDee.loadMesh(_shape);
147512     g = g || 0;
147513     ThreeDee.rotate(0, g, 0);
147514     ThreeDee.rotate(b, 0, a);
147515     ThreeDee.backface();
147516     ThreeDee.shade();
147517     ThreeDee.zSort();
147518     Draw.initialize(document.querySelector("#accelerometer-canvas"));
147519     Draw.clear(0, 0, 480, 300);
147520     Draw.drawScene(ThreeDee.getTranslation(), 3);
147521 }
147522
147523 // update the 3d model created by three.js
147524 function _updatePhoneModel(a, b, g) {
147525     _mesh.rotation.x = b / 90 * 1.5;
147526     _mesh.rotation.y = g / 90 * 1.5;
147527     _mesh.rotation.z = a / 90 * 1.5;
147528     _renderer.clear();
147529     _renderer.render(_scene, _camera);
147530 }
147531
147532 function _resetAccelerometer() {
147533     _oldX = 0;
147534     _oldY = 0;
147535     _oldAlphaX = 0;
147536     _offsets = {
147537         x: 0,
147538         y: 0,
147539         z: -9.81
147540     };
147541     if (_flag) {
147542         _mesh.rotation.x = 0;
147543         _mesh.rotation.y = 0;
147544         _mesh.rotation.z = 0;
147545         _renderer.clear();
147546         _renderer.render(_scene, _camera);
147547     } else {
147548         _updateCanvas(0, 0);
147549     }
147550
147551     accelerometer.setInfo({
147552         acceleration: new Acceleration(0, 0, 0),
147553         accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
147554         rotationRate: new Rotation(0, 0, 0),
147555         orientation: new Rotation(0, 0, 0),
147556         timestamp: new Date().getTime()
147557     });
147558     accelerometer.triggerEvent();
147559 }
147560
147561 function _resetMagneticField() {
147562     jQuery("#magnetic-x").val("100");
147563     jQuery("#magnetic-y").val("100");
147564     jQuery("#magnetic-z").val("100");
147565 }
147566
147567 function _resetLightLevel() {
147568     $("#display-state").children().each(function() {
147569         if ($(this).val() === "OFF") {
147570             $(this).attr("selected", "true");
147571             this.selected = true;
147572         }
147573         else {
147574             $(this).attr("selected", "false");
147575             this.selected = false;
147576         }
147577     });
147578 }
147579
147580
147581 // set a typical mode for accelerometer simulation, when the phone drops,
147582 // x will become to be 0, y will become to be -9.81 and z will become to be 0
147583 function _setDrop() {
147584     //duration = 20 * 50 = 1000ms. 20 is ths number of steps and 50 is the duration of steps.
147585     var alpha = Number(accelerometer.getInfo().orientation.alpha),
147586         beta = Number(accelerometer.getInfo().orientation.beta),
147587         gamma = Number(accelerometer.getInfo().orientation.gamma),
147588         cosX, cosY, sinX, sinY, x, y, z,
147589         alphaStep = Math.abs(alpha) / 20,
147590         betaStep = Math.abs(beta - 90) / 20,
147591         gammaStep = Math.abs(gamma) / 20,
147592         counts = 0, dropTimeout,
147593         drop = function () {
147594             if (counts >= 20) {
147595                 window.clearTimeout(dropTimeout);
147596                 // to avoid showing "-0" or "-0.00"
147597                 if (_flag)
147598                     _updatePhoneModel(0, 90, 0);
147599                 else
147600                     _updateCanvas(0, -90, 0);
147601                 accelerometer.setInfo({
147602                     x: 0,
147603                     y: -9.81,
147604                     z: 0,
147605                     alpha: 0,
147606                     beta: 90,
147607                     gamma: 0
147608                 });
147609             } else {
147610                 dropTimeout = setTimeout(drop, 50);
147611                 step();
147612                 counts++;
147613             }
147614         },
147615         step = function () {
147616             var _beta;
147617
147618             alpha = alpha > 0 ? alpha - alphaStep : alpha + alphaStep;
147619             beta = beta > 90 ? beta - betaStep : beta + betaStep;
147620             gamma = gamma > 0 ? gamma - gammaStep : gamma + gammaStep;
147621             _beta = _flag ? beta + betaStep : -(beta + betaStep);
147622             if (_flag)
147623                 _updatePhoneModel(alpha, _beta, gamma);
147624             else
147625                 _updateCanvas(alpha, _beta, gamma);
147626
147627             cosX = Math.cos(gamma * (Math.PI / 180));
147628             sinX = Math.sin(gamma * (Math.PI / 180));
147629             cosY = Number(Math.cos(beta * (Math.PI / 180)).toFixed(6));
147630             sinY = Math.sin(beta * (Math.PI / 180));
147631             x = 9.81 * cosY * sinX;
147632             y = -9.81 * sinY;
147633             z = -9.81 * cosY * cosX;
147634             accelerometer.setInfo({
147635                 x: x,
147636                 y: y,
147637                 z: z,
147638                 alpha: alpha,
147639                 beta: beta,
147640                 gamma: gamma
147641             });
147642             _offsets.x = -gamma;
147643             _offsets.y = -beta;
147644         };
147645
147646     drop();
147647 }
147648
147649 function _initializeSensorSettings() {
147650     var sensorsInputID = ["accelerometer-alpha", "accelerometer-beta", "accelerometer-gamma", "magnetic-x", "magnetic-y", "magnetic-z"],
147651         magneticEvent = ["MagneticField-xChanged", "MagneticField-yChanged", "MagneticField-zChanged"],
147652          magneticData = ["MagneticField.x", "MagneticField.y", "MagneticField.z"],
147653         oldValue, oldInputX,
147654         inputMouseDown,
147655         triggerFunction,
147656         selectedInputID = null;
147657
147658     triggerFunction = function (val, index) {
147659         var cosX, cosY, sinX, sinY, x, y, z,
147660             alpha = accelerometer.getInfo().orientation.alpha,
147661             beta = accelerometer.getInfo().orientation.beta,
147662             gamma = accelerometer.getInfo().orientation.gamma;
147663
147664         //choose which value to change according to index
147665         switch (index) {
147666         case 0:
147667             alpha = val;
147668             break;
147669         case 1:
147670             beta = val;
147671             break;
147672         case 2:
147673             gamma = val;
147674             break;
147675         default:
147676             sensorSettings.persist(magneticData[index - 3], val);
147677             event.trigger(magneticEvent[index - 3], [val]);
147678         }
147679
147680         //change the phone model and values of other inputs when changing a value of input
147681         if (_flag)
147682             _updatePhoneModel(alpha, beta, gamma);
147683         else
147684             _updateCanvas(alpha, -beta, gamma);
147685         cosX = Math.cos(gamma * (Math.PI / 180));
147686         sinX = Math.sin(gamma * (Math.PI / 180));
147687         cosY = Math.cos(beta * (Math.PI / 180));
147688         sinY = Math.sin(beta * (Math.PI / 180));
147689         x = 9.81 * cosY * sinX;
147690         y = -9.81 * sinY;
147691         z = -9.81 * cosY * cosX;
147692         accelerometer.setInfo({
147693             x: x,
147694             y: y,
147695             z: z,
147696             alpha: alpha,
147697             beta: beta,
147698             gamma: gamma
147699         });
147700         _offsets.x = -gamma;
147701         _offsets.y = -beta;
147702     };
147703
147704     // make the input elements more powful: drag mouse to left to decrease the value and right to increase it;
147705     // also change the value with arrow keys.
147706
147707
147708     sensorsInputID.forEach(function (id, index) {
147709         jQuery("#" + id).mousedown(function (e) {
147710             selectedInputID = id;
147711             oldValue = parseInt(this.value, 10);
147712             oldInputX = e.offsetX;
147713             inputMouseDown = true;
147714         });
147715
147716         jQuery("#" + id).mousemove(function (e) {
147717             if (inputMouseDown && (selectedInputID !== null)) {
147718                 jQuery("#" + selectedInputID).val(parseInt(oldValue + (e.offsetX - oldInputX) / 2, 10));
147719                 if (parseInt(this.value, 10) <= parseInt(jQuery(this).attr("minValue"), 10)) {
147720                     this.value = jQuery(this).attr("minValue");
147721                 }
147722                 if (parseInt(this.value, 10) >= parseInt(jQuery(this).attr("maxValue"), 10)) {
147723                     this.value = jQuery(this).attr("maxValue");
147724                 }
147725                 triggerFunction(this.value, index);
147726             }
147727         });
147728
147729         jQuery("#" + id).mouseup(function () {
147730             selectedInputID = null;
147731             inputMouseDown = false;
147732         });
147733         jQuery(document).mouseup(function () {
147734             selectedInputID = null;
147735             inputMouseDown = false;
147736         });
147737
147738         jQuery("#" + id).click(function () {
147739             this.select();
147740         });
147741
147742         jQuery("#" + id).blur(function () {
147743             if (isNaN(this.value)) {
147744                 this.value = 0;
147745             }
147746             else if (parseInt(this.value, 10) > parseInt(jQuery(this).attr("maxValue"), 10))
147747                 this.value = jQuery(this).attr("maxValue");
147748             else if (parseInt(this.value, 10) < parseInt(jQuery(this).attr("minValue"), 10))
147749                 this.value = jQuery(this).attr("minValue");
147750             else
147751                 this.value = parseInt(this.value, 10);
147752             triggerFunction(this.value, index);
147753         });
147754
147755         jQuery("#" + id).keydown(function (e) {
147756             switch (e.keyCode) {
147757             case 38:
147758                 if (parseInt(this.value, 10) < parseInt(jQuery(this).attr("maxValue"), 10)) {
147759                     this.value = parseInt(this.value, 10) + 1;
147760                     triggerFunction(this.value, index);
147761                 }
147762                 break;
147763             case 40:
147764                 if (parseInt(this.value, 10) > parseInt(jQuery(this).attr("minValue"), 10)) {
147765                     this.value = parseInt(this.value, 10) - 1;
147766                     triggerFunction(this.value, index);
147767                 }
147768                 break;
147769             default:
147770                 return;
147771             }
147772         });
147773     });
147774 }
147775
147776 /*
147777 //initialize light settings
147778 function _initializeLightSettings() {
147779     var displayObj = document.getElementById("display-state"),
147780         DISPLAY_STATE  = require('ripple/constants').POWER_RESOURCE.SCREEN.STATE,
147781         brightness;
147782
147783     displayObj.addEventListener("change", function () {
147784         var state = displayObj.value, value;
147785         value = DISPLAY_STATE[state].VALUE;
147786         deviceSettings.persist("Display.brightness", value);
147787         event.trigger("DisplayBrightnessChanged", [value]);
147788     });
147789
147790     brightness = deviceSettings.retrieve("Display.brightness");
147791     if (brightness ===  DISPLAY_STATE.SCREEN_OFF.MAX) {
147792         displayObj.options[0].selected = true;
147793     } else if (brightness <= DISPLAY_STATE.SCREEN_DIM.MAX) {
147794         displayObj.options[1].selected = true;
147795     } else if (brightness <= DISPLAY_STATE.SCREEN_NORMAL.MAX) {
147796         displayObj.options[2].selected = true;
147797     } else {
147798         displayObj.options[3].selected = true;
147799     }
147800 }
147801 */
147802
147803 module.exports = {
147804     panel: {
147805         domId: "sensors-container",
147806         collapsed: true,
147807         pane: "left",
147808         titleName: "Sensors",
147809         display: true
147810     },
147811     initialize: function () {
147812         var gl,
147813             testCanvas = document.getElementById("accelerometer-canvas");
147814
147815         try { // check whether the browser supports webGL, returns null if not support
147816             gl = testCanvas.getContext("experimental-webgl");
147817             gl.viewport(0, 0, testCanvas.width, testCanvas.height);
147818         } catch (e) {
147819             console.log("unsupport webgl");
147820         }
147821
147822         _flag = gl ? true : false;
147823
147824         accelerometer.init();
147825         _createThreeDModel();
147826         _initializeSensorSettings();
147827         //_initializeLightSettings();
147828
147829         jQuery("#accelerometer-shake").click(function () {
147830             window.setTimeout(require('ripple/ui/plugins/goodVibrations').shakeDevice(8), 1);
147831             accelerometer.shake();
147832         });
147833
147834         jQuery("#sensor-reset-all").click(function () {
147835             _resetAccelerometer();
147836             _resetMagneticField();
147837             _resetLightLevel();
147838         });
147839
147840         jQuery("#accelerometer-drop").click(_setDrop);
147841
147842         event.on("AccelerometerInfoChangedEvent", function (motion) {
147843             jQuery("#accelerometer-x").html(motion.accelerationIncludingGravity.x.toFixed(2));
147844             jQuery("#accelerometer-y").html(motion.accelerationIncludingGravity.y.toFixed(2));
147845             jQuery("#accelerometer-z").html(motion.accelerationIncludingGravity.z.toFixed(2));
147846             jQuery("#accelerometer-alpha").val(Number(motion.orientation.alpha).toFixed(2));
147847             jQuery("#accelerometer-beta").val(Number(motion.orientation.beta).toFixed(2));
147848             jQuery("#accelerometer-gamma").val(Number(motion.orientation.gamma).toFixed(2));
147849         }, this);
147850     }
147851 };
147852
147853 });
147854 define('ripple/ui/plugins/settings-dialog', function (require, exports, module) {
147855 /*
147856  *  Copyright 2011 Research In Motion Limited.
147857  *
147858  * Licensed under the Apache License, Version 2.0 (the "License");
147859  * you may not use this file except in compliance with the License.
147860  * You may obtain a copy of the License at
147861  *
147862  * http://www.apache.org/licenses/LICENSE-2.0
147863  *
147864  * Unless required by applicable law or agreed to in writing, software
147865  * distributed under the License is distributed on an "AS IS" BASIS,
147866  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147867  * See the License for the specific language governing permissions and
147868  * limitations under the License.
147869  */
147870 var db = require('ripple/db'),
147871     utils = require('ripple/utils'),
147872     platform = require('ripple/platform'),
147873     notifications = require('ripple/notifications'),
147874     tooltip = require('ripple/ui/plugins/tooltip'),
147875     bus = require('ripple/bus'),
147876     required = {
147877         build: {
147878             "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName"],
147879             "webworks.bb10": ["sdk", "projectPath", "outputPath", "projectName"],
147880             "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName"]
147881         },
147882         sign: {
147883             "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName", "csk_password", "p12_password", "bundle_number"],
147884             "webworks.bb10": ["sdk", "projectPath", "outputPath", "projectName", "signingPassword", "bundle_number"],
147885             "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName", "signingPassword"]
147886         },
147887         launch: {
147888             "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName", "device"],
147889             "webworks.bb10": ["sdk", "projectPath", "outputPath", "projectName", "device"],
147890             "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName", "simulator"]
147891         }
147892     },
147893     _settings = {
147894         get: function () {
147895             var settings = db.retrieveObject("build-settings", platform.getPersistencePrefix()) || {};
147896             settings.debug = !!settings["remoteInspector"];
147897
147898             return settings;
147899         },
147900         save: function (settings) {
147901             db.saveObject("build-settings", settings, platform.getPersistencePrefix());
147902         }
147903     },
147904     port = "9910",
147905     host = "http://127.0.0.1:" + port + "/ripple",
147906     progressContainer = jQuery("#options-progress"),
147907     progressInterval,
147908     _passwordFields = [
147909         "signingPassword",
147910         "devicePassword",
147911         "csk_password",
147912         "p12_password"
147913     ],
147914     _checkboxFields = [
147915         "remoteInspector"
147916     ],
147917     _passwords = {},
147918     _self;
147919
147920 function missing(settings, action) {
147921     return required[action][platform.current().id].filter(function (field) {
147922         return !settings.hasOwnProperty(field);
147923     });
147924 }
147925
147926 function _isPasswordField(id) {
147927     var match = typeof id === "string" && new RegExp("^" + id + "$", "i");
147928     return match && utils.some(_passwordFields, function (name) {
147929         return match.test(name);
147930     });
147931 }
147932
147933 function _isCheckboxField(id) {
147934     var match = typeof id === "string" && new RegExp("^" + id + "$", "i");
147935     return match && utils.some(_checkboxFields, function (name) {
147936         return match.test(name);
147937     });
147938 }
147939
147940 function table(action) {
147941     var _table = $("<table class='panel-table'>"),
147942         _row = {
147943             row: function (item, desc, opts) {
147944                 var id = "settings-field-" + item.toLowerCase(),
147945                     input = "",
147946                     save = function () {
147947                         var s = _settings.get(),
147948                             v = $("#" + id).val(),
147949                             val = opts.type === "number" ? parseInt(v, 10) : v;
147950
147951                         if (_isCheckboxField(item)) {
147952                             s[item] = $("#" + id).prop("checked");
147953                         }
147954                         else if (val) {
147955                             (_isPasswordField(item) ? _passwords : s)[item] = val;
147956                         }
147957                         else {
147958                             delete s[item];
147959                         }
147960                         _settings.save(s);
147961
147962                         if (opts.onChanged) {
147963                             opts.onChanged(s[item]);
147964                         }
147965                     },
147966                     row;
147967
147968                 opts = opts || { type: "text" };
147969
147970                 switch (opts.type) {
147971                 case "select":
147972                     input = "<select id='" + id + "' class='ui-state-default ui-corner-all' style='width:100%'/>";
147973                     break;
147974                 case "span":
147975                     input = "<span id = '" + id + "'>" + opts.text + "</span>";
147976                     break;
147977                 default:
147978                     input = "<input id='" + id + "' type='" + opts.type + "' class='ui-state-default ui-corner-all' style='width:90%' />";
147979                     break;
147980                 }
147981
147982                 row = $("<tr>" +
147983                     "<td><label for='" + id + "' class='ui-text-label'>" + desc + "</label></td>" +
147984                     "<td>" + input + "</td>" +
147985                 "</tr>");
147986
147987                 row.appendTo(_table);
147988
147989                 //bind save handlers to the row
147990                 utils.bindAutoSaveEvent(row.find("#" + id).change(save), save);
147991
147992                 return _row;
147993             },
147994             appendTo: function (id) {
147995                 var fs = $("<fieldset class='main'><legend class='cap-text'>" + action + "</legend></fieldset>");
147996
147997                 $(_table).appendTo(fs);
147998                 fs.appendTo($(id));
147999             }
148000         };
148001
148002     return _row;
148003 }
148004
148005 function create() {
148006     var build = table('build'),
148007         sign = table('sign'),
148008         launch = table('launch');
148009
148010     build
148011         .row("sdk", "SDK Path")
148012         .row("projectPath", "Project Root")
148013         .row("projectName", "Archive Name")
148014         .row("outputPath", "Output Folder")
148015         .row("remoteInspector", "Enable Remote Web Inspector", {
148016             type: "checkbox",
148017             onChanged: function (enabled) {
148018                 if (enabled) {
148019                     $("#options-menu-build-warning").show();
148020                     tooltip.create("#options-menu-build-warning", "Remote Web Inspector should be disabled when packaging for App World release");
148021                 }
148022                 else {
148023                     $("#options-menu-build-warning").hide();
148024                 }
148025             }
148026         })
148027         .appendTo("#settings-tabs-build");
148028
148029     switch (platform.current().id) {
148030     case "webworks.handset":
148031         sign.row("signingPassword", "Password", {
148032             type: "password"
148033         });
148034
148035         launch.row("simulator", "Simulator", {
148036             type: "select"
148037         });
148038
148039         launch.row("simulatorstatus", "Simulator", {
148040             type: "span",
148041             text: "Searching for simulators ..."
148042         });
148043         
148044         break;
148045
148046     case "webworks.tablet":
148047         sign.row("csk_password", "CSK Password", {
148048             type: "password"
148049         });
148050         sign.row("p12_password", "P12 Password", {
148051             type: "password"
148052         });
148053         sign.row("bundle_number", "Bundle Number", {
148054             type: "number"
148055         });
148056
148057         launch.row("device", "Playbook IP");
148058         launch.row("devicePassword", "Playbook Password", {
148059             type: "password"
148060         });
148061
148062         break;
148063
148064     case "webworks.bb10":
148065         sign.row("signingPassword", "Signing Password", {
148066             type: "password"
148067         });
148068         sign.row("bundle_number", "Bundle Number", {
148069             type: "number"
148070         });
148071
148072         launch.row("device", "Device IP");
148073         launch.row("devicePassword", "Device Password", {
148074             type: "password"
148075         });
148076
148077         break;
148078     }
148079
148080     sign.appendTo("#settings-tabs-build");
148081     launch.appendTo("#settings-tabs-build");
148082
148083     $("#settings-field-simulator").parent().parent().hide();
148084 }
148085
148086 function populate(settings) {
148087     var fill = function (action, prop) {
148088         var element = $("#settings-field-" + prop.toLowerCase());
148089
148090         if (_isPasswordField(prop)) {
148091             element.val(_passwords[prop]);
148092         }
148093         else if (_isCheckboxField(prop)) {
148094             element.prop("checked", settings[prop]);
148095         }
148096         else {
148097             element.val(settings[prop]);
148098         }
148099     };
148100
148101     fill("build", "sdk");
148102     fill("build", "projectPath");
148103     fill("build", "outputPath");
148104     fill("build", "projectName");
148105     fill("build", "remoteInspector");
148106
148107     fill("sign", "signingPassword");
148108     fill("sign", "csk_password");
148109     fill("sign", "p12_password");
148110     fill("sign", "bundle_number");
148111
148112     fill("launch", "simulator");
148113     fill("launch", "device");
148114     fill("launch", "devicePassword");
148115 }
148116
148117 function url(action) {
148118     var target = "";
148119
148120     switch (platform.current().id) {
148121     case "webworks.bb10":
148122         target = "bb10";
148123         break;
148124     case "webworks.tablet":
148125         target = "tablet";
148126         break;
148127     case "webworks.handset":
148128         target = "smartphone";
148129         break;
148130     }
148131
148132     return host + "/" + action + "/" + target;
148133 }
148134
148135 function enable(action) {
148136     $("#options-menu-" + action).removeClass("not-ready");
148137     if (action === "launch") {
148138         $("#settings-field-simulatorstatus").parent().parent().hide();
148139         $("#settings-field-simulator").parent().parent().show();
148140     }
148141 }
148142
148143 function disable(action) {
148144     $("#options-menu-" + action).addClass("not-ready");
148145     if (action === "launch") {
148146         $("#settings-field-simulatorstatus").parent().parent().show();
148147         $("#settings-field-simulator").parent().parent().hide();
148148     }
148149 }
148150
148151 function getSimulators() {
148152     if (!_settings.get().sdk) {
148153         $("#settings-field-simulatorstatus").text("");
148154         disable("launch");
148155         return;
148156     }
148157
148158     bus.ajax(
148159         "POST",
148160         host + "/simulators",
148161         _settings.get(),
148162         function (resp) {
148163             var sims = resp.data.simulators;
148164
148165             $("#settings-field-simulator").empty();
148166             if (sims.length > 0) {
148167                 $(resp.data.simulators.map(function (sim) {
148168                     return "<option value='" + sim + "'>" + sim + "</option>";
148169                 }).join()).appendTo("#settings-field-simulator");
148170
148171                 enable("launch");
148172             }
148173             else {
148174                 disable("launch");
148175                 $("#settings-field-simulatorstatus").text("No simulators found :(");
148176             }
148177         },
148178         function () {
148179             disable("launch");
148180             $("#settings-field-simulatorstatus").text("Error attempting to get simulators :(");
148181         }
148182     );
148183 }
148184
148185 function _startProgress() {
148186     if (progressInterval) {
148187         window.clearInterval(progressInterval);
148188     }
148189     progressInterval = window.setInterval(function () {
148190         if (progressContainer.html().length === 5) {
148191             progressContainer.html(".");
148192         }
148193         else {
148194             progressContainer.html(progressContainer.html() + ".");
148195         }
148196     }, 250);
148197 }
148198
148199 function _endProgress() {
148200     window.clearInterval(progressInterval);
148201     progressInterval = null;
148202     progressContainer.html("");
148203 }
148204
148205
148206 _self = {
148207     initialize: function () {
148208         $("#settings-dialog").dialog({
148209             autoOpen: false,
148210             modal: true,
148211             width: 700,
148212             title: "Settings",
148213             position: 'center'
148214         }).hide();
148215
148216         $("#settings-tabs").tabs();
148217         $("#settings-action").button();
148218
148219         create();
148220
148221         if (platform.current().id === "webworks.handset") {
148222             enable("build");
148223             enable("sign");
148224             enable("settings");
148225
148226             getSimulators();
148227             $("#settings-field-sdk").change(getSimulators);
148228         }
148229         else if (platform.current().id === "webworks.tablet") {
148230             enable("build");
148231             enable("sign");
148232             enable("launch");
148233             enable("settings");
148234         }
148235         else if (platform.current().id === "webworks.bb10") {
148236             enable("build");
148237             enable("sign");
148238             enable("launch");
148239             enable("settings");
148240         }
148241     },
148242
148243     can: function (action) {
148244         var settings = {};
148245
148246         utils.mixin(_settings.get(), settings);
148247         utils.mixin(_passwords, settings);
148248
148249         return action && missing(settings, action).length === 0;
148250     },
148251
148252     value: function (prop) {
148253         var settings = {};
148254
148255         utils.mixin(_settings.get(), settings);
148256         return settings[prop];
148257     },
148258
148259     show: function (action) {
148260         var settings = {};
148261
148262         utils.mixin(_settings.get(), settings);
148263         utils.mixin(_passwords, settings);
148264
148265         populate(settings);
148266
148267         $("#settings-dialog").dialog("open");
148268         $("#settings-action").button("option", "label", action || "Close")[action ? "show" : "hide"]();
148269
148270         if (action) {
148271             missing(settings, action).forEach(function (field) {
148272                 $("#settings-field-" + field.toLowerCase()).effect("highlight", {color: "red"}, 1500);
148273             });
148274
148275             $("#settings-action").unbind("click").click(function () {
148276                 if (_self.can(action)) {
148277                     _self.perform(action);
148278                     $("#settings-dialog").dialog("close");
148279                 }
148280                 else {
148281                     _self.show(action);
148282                 }
148283             });
148284         }
148285     },
148286
148287     perform: function (action) {
148288         var settings = _settings.get(),
148289             data = {},
148290             poll = function (resp) {
148291                 var notifications = require("ripple/notifications");
148292
148293                 if (resp && resp.code !== 0) {
148294                     notifications.openNotification("error", "Build request failed with message: " + resp.msg);
148295                     _endProgress();
148296                 }
148297                 else {
148298                     if (resp && resp.data.status === "building") {
148299                         setTimeout(function () {
148300                             bus.ajax(
148301                                 "GET",
148302                                 host + "/build_status/" + resp.data.id,
148303                                 null,
148304                                 poll,
148305                                 function (error) {
148306                                     notifications.openNotification("error", "Build request failed with message: " + JSON.stringify(error));
148307                                     _endProgress();
148308                                 }
148309                             );
148310                         }, 500);
148311                     }
148312                     else {
148313                         if (action.match(/sign/)) {
148314                             settings["bundle_number"] = $("#settings-field-bundle_number").val(parseInt($("#settings-field-bundle_number").val(), 10) + 1).val();
148315                             _settings.save(settings);
148316                         }
148317                         notifications.openNotification("normal", "Build succeeded!");
148318                         _endProgress();
148319                     }
148320                 }
148321             };
148322
148323         utils.mixin(settings, data);
148324         utils.mixin(_passwords, data);
148325
148326         bus.ajax(
148327             "POST",
148328             url(action),
148329             data,
148330             function (resp) {
148331                 _startProgress();
148332                 poll(resp);
148333             },
148334             function (error) {
148335                 var message = "Build request failded with message: " + error.data;
148336
148337                 if (error.code === 0 || error.code === 404) {
148338                     message += "<br>This could be due to the Build and Deploy services not running or not being installed";
148339                 }
148340
148341                 notifications.openNotification("error", message);
148342             }
148343         );
148344     }
148345 };
148346
148347 module.exports = _self;
148348
148349 });
148350 define('ripple/ui/plugins/settings-menu', function (require, exports, module) {
148351 /*
148352  *  Copyright 2011 Research In Motion Limited.
148353  *
148354  * Licensed under the Apache License, Version 2.0 (the "License");
148355  * you may not use this file except in compliance with the License.
148356  * You may obtain a copy of the License at
148357  *
148358  * http://www.apache.org/licenses/LICENSE-2.0
148359  *
148360  * Unless required by applicable law or agreed to in writing, software
148361  * distributed under the License is distributed on an "AS IS" BASIS,
148362  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148363  * See the License for the specific language governing permissions and
148364  * limitations under the License.
148365  */
148366 var utils = require('ripple/utils'),
148367     constants = require('ripple/constants'),
148368     platform = require('ripple/platform'),
148369     db = require('ripple/db'),
148370     _applicationStateId
148371     ;
148372
148373
148374 function reload() {
148375     window.tinyHipposReload = true;
148376     location.reload();
148377 }
148378
148379 function _showSettingMenu() {
148380     var contentTable = "",
148381     settings = [],
148382     _applicationState = [],
148383     _applicationStateTmp = [],
148384     unselectedNum = 0,
148385     i = 0;
148386
148387     if ($("#settings-menu-popup").is(":visible")) {
148388         $("#settings-menu-popup").hide("slide", {direction: "up"}, "slow");
148389         $("#overlayBackground").hide("fade", "slow");
148390         return;
148391     }
148392
148393     _applicationStateId = constants.COMMON.APPLICATION_STATE + platform.current().id;
148394
148395     _applicationStateTmp = db.retrieveObject(_applicationStateId) || [];
148396
148397     utils.forEach(_applicationStateTmp, function (obj) {
148398         if (obj.display)
148399             _applicationState.push(obj);
148400     });
148401
148402     utils.forEach(_applicationStateTmp, function (obj) {
148403         if (!obj.display)
148404             _applicationState.push(obj);
148405     });
148406
148407     $("#settings-menu-content-panel-table").remove();
148408
148409     contentTable = '<table id="settings-menu-content-panel-table" class="settings-menu-content-table">';
148410     utils.forEach(_applicationState, function (obj) {
148411         var checked = obj.display ? 'checked="yes"':"";
148412         contentTable += '<tr><td><input name="panel-display-setting" type="checkbox" class="settings-menu-checkbox "' +
148413                         checked + '></input>' +
148414                         obj.titleName + '</td></tr>\n';
148415     });
148416     contentTable += "</table>";
148417
148418     $("#settings-menu-container-div").append(contentTable);
148419     $("#settings-menu-popup").css("top", 50);
148420     $("#settings-menu-popup").css("left", $(window).width() - 340);
148421
148422     $("#overlayBackground").css("width", $(window).width());
148423     $("#overlayBackground").css("height", $(window).height());
148424     $("#overlayBackground").show("fade", "slow");
148425     $("#settings-menu-popup").show("slide", {direction: "up"}, "slow");
148426
148427     $("#settings-menu-save-btn").unbind('click');
148428     $("#settings-menu-save-btn").bind("click", function (event) {
148429         $("input[name='panel-display-setting']").each(function (i, a) {
148430             settings.push(a.checked);
148431         });
148432
148433         utils.forEach(_applicationState, function (obj) {
148434             if (!settings[i])
148435                 obj.collapsed = true;
148436             obj.display = settings[i];
148437             i++;
148438         }, this);
148439   
148440         db.saveObject(_applicationStateId, _applicationState);
148441         _applicationStateTmp = db.retrieveObject(_applicationStateId) || [];
148442
148443         $("#settings-menu-popup").hide("slide", {direction: "up"}, "slow");
148444         $("#overlayBackground").hide("fade", "slow");
148445         setTimeout(reload, 500);
148446     });
148447
148448     $(".settings-menu-content-table td").unbind('click');
148449     $(".settings-menu-content-table td").bind("click", function (event) {
148450         var checkbox;
148451         if (($(event.target).children().length === 0)) {
148452             return;
148453         } else {
148454             checkbox = $(event.target).children();
148455         }
148456         
148457         if (checkbox.is(':checked')) {
148458             checkbox.prop('checked', false);
148459         }
148460         else
148461             checkbox.prop('checked', true);
148462     });
148463
148464     $("#settings-menu-close-btn").unbind('click');
148465     $("#settings-menu-close-btn").bind("click", function (event) {
148466         if ($("#settings-menu-popup").is(":visible")) {
148467             $("#settings-menu-popup").hide("slide", {direction: "up"}, "slow");
148468             $("#overlayBackground").hide("fade", "slow");
148469             return;
148470         }
148471     });
148472
148473     $(window).bind('resize', function () {
148474         $("#settings-menu-popup").css("top", 50);
148475         $("#settings-menu-popup").css("left", $(window).width() - 340);
148476         $("#overlayBackground").css("width", $(window).width());
148477         $("#overlayBackground").css("height", $(window).height());
148478     });
148479
148480     $(".settings-menu-checkbox").each(function (i, a) {
148481         if (a.checked === false) {
148482             unselectedNum++;
148483         }
148484     });
148485
148486     if (unselectedNum === 0) {
148487         $("#select_unselect_text").text("Unselect All");
148488         $("#panelSettingSelectAll").prop('checked', true);
148489     }
148490
148491     $("#panelSettingSelectAll").unbind('click');
148492     $("#panelSettingSelectAll").bind("click", function (event) {
148493         if ($("#panelSettingSelectAll").is(':checked')) {
148494             $("#select_unselect_text").text("Unselect All");
148495             $(".settings-menu-checkbox").prop('checked', true);
148496         }
148497         else {
148498             $("#select_unselect_text").text("Select All");
148499             $(".settings-menu-checkbox").prop('checked', false);
148500         }
148501     });
148502 }
148503
148504 module.exports = {
148505     initialize: function () {
148506         $("#options-button-panels").bind("click", function (event) {
148507             _showSettingMenu();
148508         });
148509     }
148510 };
148511
148512 });
148513 define('ripple/ui/plugins/settings', function (require, exports, module) {
148514 /*
148515  *  Copyright 2011 Research In Motion Limited.
148516  *
148517  * Licensed under the Apache License, Version 2.0 (the "License");
148518  * you may not use this file except in compliance with the License.
148519  * You may obtain a copy of the License at
148520  *
148521  * http://www.apache.org/licenses/LICENSE-2.0
148522  *
148523  * Unless required by applicable law or agreed to in writing, software
148524  * distributed under the License is distributed on an "AS IS" BASIS,
148525  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148526  * See the License for the specific language governing permissions and
148527  * limitations under the License.
148528  */
148529 var db = require('ripple/db'),
148530     constants = require('ripple/constants'),
148531     KEY = constants.XHR.PROXY_DISABLED_BUTTON; // TODO: one settings object for all
148532
148533 function _saveAndReload(key, value) {
148534     jWorkflow.order(function (prev, baton) {
148535         baton.take();
148536         db.save(key, value, null, baton.pass);
148537     }).start(function () {
148538         window.tinyHipposReload = true;
148539         location.reload();
148540     });
148541 }
148542
148543 function _initialize(prev, baton) {
148544     var select = document.getElementById("settings-xhr-proxy"),
148545         about = require('ripple/ui/plugins/about-dialog');
148546
148547     select.value = String(db.retrieve(KEY));
148548     select.addEventListener("change", function () {
148549         _saveAndReload(KEY, this.value);
148550     }, false);
148551     
148552     $("#options-menu-about").click(function () {
148553         about.show();
148554     });
148555     // TODO: reload here?
148556 }
148557
148558 module.exports = {
148559     panel: {
148560         domId: "settings-container",
148561         collapsed: true,
148562         pane: "right"
148563     },
148564     initialize: _initialize
148565 };
148566
148567 });
148568 define('ripple/ui/plugins/storage', function (require, exports, module) {
148569 /*
148570  *  Copyright 2011 Research In Motion Limited.
148571  *
148572  * Licensed under the Apache License, Version 2.0 (the "License");
148573  * you may not use this file except in compliance with the License.
148574  * You may obtain a copy of the License at
148575  *
148576  * http://www.apache.org/licenses/LICENSE-2.0
148577  *
148578  * Unless required by applicable law or agreed to in writing, software
148579  * distributed under the License is distributed on an "AS IS" BASIS,
148580  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148581  * See the License for the specific language governing permissions and
148582  * limitations under the License.
148583  */
148584 var constants = require('ripple/constants'),
148585     event = require('ripple/event'),
148586     platform = require('ripple/platform'),
148587     utils = require('ripple/utils'),
148588     app = require('ripple/app'),
148589     db = require('ripple/db');
148590
148591 function _updatePreferencesView() {
148592     var node = document.getElementById(constants.COMMON.STORAGE_TABLE_BODY_CLASS),
148593         countTitle = document.getElementById(constants.COMMON.STORAGE_COUNT_CONTAINER_ID);
148594
148595     // TODO: convert to appendChild
148596     if (node) {
148597         db.retrieveAll(platform.getPersistencePrefix(), function (results) {
148598             var str = "",
148599                 counter = 0;
148600
148601             utils.forEach(results, function (value, key) {
148602                 // TODO: based of current platform
148603                 if (app.isPreferenceReadOnly(key)) {
148604                     str += '<tr class="ui-text-highlight">';
148605                 } else {
148606                     str += '<tr>';
148607                 }
148608                 str += '<td>' + key + '</td><td>' + value + "</td></tr>";
148609                 counter ++;
148610             });
148611
148612             node.innerHTML = str;
148613             countTitle.innerHTML = counter.toString();
148614
148615             if (counter === 0) {
148616                 jQuery("#" + constants.COMMON.STORAGE_CLEAR_BUTTON_ID).addClass(constants.CSS_PREFIX.IRRELEVANT);
148617             }
148618             else {
148619                 jQuery("#" + constants.COMMON.STORAGE_CLEAR_BUTTON_ID).removeClass(constants.CSS_PREFIX.IRRELEVANT);
148620             }
148621         });
148622     }
148623 }
148624
148625 module.exports = {
148626     panel: {
148627         domId: "preferences",
148628         collapsed: true,
148629         pane: "left"
148630     },
148631     initialize: function () {
148632         jQuery("#preferences-clear-button").bind("click", function () {
148633             db.removeAll(platform.getPersistencePrefix());
148634         });
148635
148636         event.on("StorageUpdatedEvent", function () {
148637             _updatePreferencesView();
148638         });
148639
148640         _updatePreferencesView();
148641     }
148642 };
148643
148644 });
148645 define('ripple/ui/plugins/themeSwitcher', function (require, exports, module) {
148646 /*
148647  *  Copyright 2011 Research In Motion Limited.
148648  *
148649  * Licensed under the Apache License, Version 2.0 (the "License");
148650  * you may not use this file except in compliance with the License.
148651  * You may obtain a copy of the License at
148652  *
148653  * http://www.apache.org/licenses/LICENSE-2.0
148654  *
148655  * Unless required by applicable law or agreed to in writing, software
148656  * distributed under the License is distributed on an "AS IS" BASIS,
148657  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148658  * See the License for the specific language governing permissions and
148659  * limitations under the License.
148660  */
148661 var utils = require('ripple/utils'),
148662     db = require('ripple/db'),
148663     THEME_KEY = "ui-theme",
148664     THEME_SELECTOR = "#theme-select",
148665     _currentTheme;
148666
148667 function _saveAndReload(key, value) {
148668     jWorkflow.order(function (prev, baton) {
148669                 baton.take();
148670                 db.save(key, value, null, baton.pass);
148671             }).start(function () {
148672                 window.tinyHipposReload = true;
148673                 location.reload();
148674             });
148675 }
148676
148677 module.exports = {
148678     initialize: function () {
148679         var themeToSet = db.retrieve(THEME_KEY);
148680
148681         // Hide the theme switcher and always set the theme to light
148682         jQuery(".theme-switcher").hide();
148683                 if (themeToSet !== "light") {
148684             _saveAndReload(THEME_KEY, "light");
148685                 }
148686                 return;
148687     }
148688 };
148689
148690 });
148691 define('ripple/ui/plugins/time', function (require, exports, module) {
148692 /*
148693  *  Copyright 2012 Intel Corporation.
148694  *
148695  * Licensed under the Apache License, Version 2.0 (the "License");
148696  * you may not use this file except in compliance with the License.
148697  * You may obtain a copy of the License at
148698  *
148699  * http://www.apache.org/licenses/LICENSE-2.0
148700  *
148701  * Unless required by applicable law or agreed to in writing, software
148702  * distributed under the License is distributed on an "AS IS" BASIS,
148703  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148704  * See the License for the specific language governing permissions and
148705  * limitations under the License.
148706  */
148707
148708 function _init() {
148709     var db = require('ripple/db'),
148710         utils = require('ripple/utils'),
148711         allTZ, dbTZ, node = jQuery("#time-locale-select"),
148712         timezone = require('ripple/platform/tizen/2.0/timezone_info'),
148713         event = require('ripple/event'),
148714         alarms, time;
148715
148716     function triggerAlarm() {
148717         time = new Date();
148718         alarms = db.retrieveObject("tizen1.0-db-alarms");
148719         if (alarms !== null) {
148720             utils.forEach(alarms, function (obj) {
148721                 if (obj.id !== undefined) {
148722                     event.trigger("CheckAlarm", [obj.id]);
148723                 }
148724             });
148725         }
148726     }
148727     window.setInterval(triggerAlarm, 1000);
148728
148729     allTZ = timezone.getAllTimezone();
148730     utils.forEach(allTZ, function (tz) {
148731         node.append(utils.createElement("option", {
148732             "value": tz,
148733             "innerHTML": tz + " - " + timezone.getTimezoneAbbr(tz) + "(" + timezone.getTimezoneDiff(tz) + ")"
148734         }));
148735     });
148736     dbTZ = db.retrieve("tizen-timezone");
148737     if (timezone.isValidTimezone(dbTZ)) {
148738         node.val(dbTZ);
148739     } else {
148740         db.save("tizen-timezone", node.val());
148741     }
148742     node.bind("change", function () {
148743         db.save("tizen-timezone", node.val());
148744     });
148745 /* FIXME: Node "trigger-alarm-id" will be removed from Time panel
148746  *        due to "time" panel will changed to "time zone" panel(PTSDK-875)
148747
148748     event.on("SendTriggerAppId", function (applicationId) {
148749         if (timeId !== undefined)
148750             clearTimeout(timeId);
148751         triggerNode.empty();
148752         triggerNode.append(utils.createElement("p", {
148753             "innerHTML": applicationId + " is triggered"
148754         }));
148755         triggerNode.show();
148756         timeId = setTimeout("jQuery('#trigger-alarm-id').empty();", 10000);// Comments will disappear after 10s
148757     });
148758 */
148759 }
148760
148761 module.exports = {
148762     panel: {
148763         domId: "time-container",
148764         collapsed: true,
148765         pane: "right",
148766         titleName: "Time",
148767         display: true
148768     },
148769     initialize: _init
148770 };
148771
148772 });
148773 define('ripple/ui/plugins/tooltip', function (require, exports, module) {
148774 /*
148775  *  Copyright 2011 Research In Motion Limited.
148776  *
148777  * Licensed under the Apache License, Version 2.0 (the "License");
148778  * you may not use this file except in compliance with the License.
148779  * You may obtain a copy of the License at
148780  *
148781  * http://www.apache.org/licenses/LICENSE-2.0
148782  *
148783  * Unless required by applicable law or agreed to in writing, software
148784  * distributed under the License is distributed on an "AS IS" BASIS,
148785  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148786  * See the License for the specific language governing permissions and
148787  * limitations under the License.
148788  */
148789 var utils = require('ripple/utils'),
148790     _options = {
148791         track: true,
148792         delay: 0,
148793         showURL: false,
148794         fade: 250,
148795         extraClass: "ui-state-highlight ui-corner-all"
148796     };
148797
148798 module.exports = {
148799     create: function (element, message) {
148800         var options = utils.copy(_options);
148801
148802         options.bodyHandler = function () {
148803             return message;
148804         };
148805
148806         return jQuery(element).tooltip(options);
148807     },
148808
148809     toggle: function () {
148810         jQuery.tooltip.block();
148811         return this.isOff();
148812     },
148813
148814     isOff: function () {
148815         return jQuery.tooltip.blocked;
148816     }
148817 };
148818
148819 });
148820 define('ripple/ui/plugins/tooltips', function (require, exports, module) {
148821 /*
148822  *  Copyright 2011 Research In Motion Limited.
148823  *
148824  * Licensed under the Apache License, Version 2.0 (the "License");
148825  * you may not use this file except in compliance with the License.
148826  * You may obtain a copy of the License at
148827  *
148828  * http://www.apache.org/licenses/LICENSE-2.0
148829  *
148830  * Unless required by applicable law or agreed to in writing, software
148831  * distributed under the License is distributed on an "AS IS" BASIS,
148832  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148833  * See the License for the specific language governing permissions and
148834  * limitations under the License.
148835  */
148836 // Class: UI.Tooltips
148837 // Purpose: build tooltips for UI
148838 // See here for Tooltip Options
148839 // http://jquery.bassistance.de/tooltip/demo/
148840 var utils = require('ripple/utils'),
148841     tooltip = require('ripple/ui/plugins/tooltip'),
148842     constants = require('ripple/constants'),
148843     db = require('ripple/db'),
148844     utils = require('ripple/utils');
148845
148846 function _updateButtonText() {
148847     document.querySelector("#settings-toggletooltips > span")
148848             .innerHTML = "Turn " + (tooltip.isOff() ? "On" : "Off");
148849 }
148850
148851 module.exports = {
148852     initialize: function () {
148853         var saved = db.retrieve(constants.SETTINGS.TOOLTIPS_KEY);
148854
148855         // blarg, tooltips are always enabled so if its saved to false disable it
148856         if (!tooltip.isOff() && (saved === "false" || saved === false)) {
148857             tooltip.toggle();
148858         }
148859
148860         _updateButtonText();
148861
148862         jQuery(constants.SETTINGS.TOOLTIPS_TOGGLE_DIV).click(function () {
148863             db.save(constants.SETTINGS.TOOLTIPS_KEY, !tooltip.toggle());
148864             _updateButtonText();
148865         });
148866     }
148867 };
148868
148869 });
148870 define('ripple/ui/plugins/touchEvent', function (require, exports, module) {
148871 /*
148872  *  Copyright 2012 Intel Corporation
148873  *
148874  * Licensed under the Apache License, Version 2.0 (the "License");
148875  * you may not use this file except in compliance with the License.
148876  * You may obtain a copy of the License at
148877  *
148878  * http://www.apache.org/licenses/LICENSE-2.0
148879  *
148880  * Unless required by applicable law or agreed to in writing, software
148881  * distributed under the License is distributed on an "AS IS" BASIS,
148882  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148883  * See the License for the specific language governing permissions and
148884  * limitations under the License.
148885  */
148886
148887 var event = require('ripple/event'),
148888     db = require('ripple/db'),
148889     constants = require('ripple/constants'),
148890     colors  = ["red", "green", "magenta", "blue", "yellow"],
148891     Point,
148892     intervalId,
148893     moveEvents  = {},
148894     currentIndex = 0,
148895     enlargeRatio = 4;
148896
148897 function _exec(operation) {
148898     var canvas = document.getElementById(constants.TOUCHEVENT.CANVAS),
148899         cxt = canvas.getContext("2d"),
148900         altKey = document.getElementById(constants.TOUCHEVENT.ALTKEY),
148901         metaKey = document.getElementById(constants.TOUCHEVENT.METAKEY),
148902         ctrlKey = document.getElementById(constants.TOUCHEVENT.CTRLKEY),
148903         shiftKey = document.getElementById(constants.TOUCHEVENT.SHIFTKEY),
148904         key, eventType;
148905
148906     if (operation === "start") {
148907         altKey.disabled = 'disabled';
148908         metaKey.disabled = 'disabled';
148909         ctrlKey.disabled = 'disabled';
148910         shiftKey.disabled = 'disabled';
148911         clearInterval(intervalId);
148912         currentIndex = 0;
148913         eventType = "touchEvent";
148914     } else if (operation === "cancel") {
148915         altKey.disabled = '';
148916         metaKey.disabled = '';
148917         ctrlKey.disabled = '';
148918         shiftKey.disabled = '';
148919         altKey.checked = false;
148920         metaKey.checked = false;
148921         ctrlKey.checked = false;
148922         shiftKey.checked = false;
148923         cxt.clearRect(0, 0, canvas.width, canvas.height);
148924         moveEvents = {};
148925         eventType = "touchCancel";
148926     }
148927
148928     event.trigger(eventType, [{
148929         data : moveEvents,
148930         keys : [altKey.checked, metaKey.checked, ctrlKey.checked, shiftKey.checked]
148931     }]);
148932 }
148933
148934 Point = function (x, y, color, isDragging) {
148935     var _self = {};
148936
148937     _self.x = x;
148938     _self.y = y;
148939     _self.color = color;
148940     _self.isDragging = isDragging;
148941
148942     return _self;
148943 };
148944
148945 module.exports = {
148946     panel: {
148947         domId: "touchEvent-container",
148948         collapsed: true,
148949         pane: "left",
148950         titleName: "Touch Event",
148951         display: true
148952     },
148953
148954     initialize: function () {
148955         var deviceInfo = require('ripple/devices').getCurrentDevice(),
148956             canvas = document.getElementById(constants.TOUCHEVENT.CANVAS),
148957             button = document.getElementById(constants.TOUCHEVENT.OPTION),
148958             cxt = canvas.getContext("2d"),
148959             points = [],
148960             paint = false,
148961             currentPoint = {};
148962
148963         function drawPoints() {
148964             var key, index, points = [], point;
148965
148966             for (key in moveEvents) {
148967                 points = moveEvents[key];
148968                 cxt.fillStyle = colors[key];
148969
148970                 for (index = 0; index < points.length; index++) {
148971                     point = points[index];
148972                     cxt.beginPath();
148973                     cxt.arc(point.offsetX, point.offsetY, 5, 0, 2 * Math.PI, 1);
148974                     cxt.fill();
148975                 }
148976             }
148977         }
148978
148979         function endDraw(event) {
148980             if (paint) {
148981                 paint = false;
148982                 clearInterval(intervalId);
148983                 moveEvents[currentIndex].push(event);
148984                 drawPoints();
148985
148986                 currentIndex++;
148987                 if (currentIndex === 5)
148988                     currentIndex = 0;
148989             }
148990         }
148991
148992         canvas.addEventListener("mousedown", function (event) {
148993             if (button.value === "Touch Cancel") {
148994                 button.value = "Touch Start";
148995                 _exec("cancel");
148996             }
148997             moveEvents[currentIndex] = [];
148998             currentPoint = event;
148999             moveEvents[currentIndex].push(event);
149000             paint = true;
149001             drawPoints();
149002             intervalId = setInterval(function () {
149003                 moveEvents[currentIndex].push(currentPoint);
149004             }, 100);
149005         });
149006
149007         canvas.addEventListener("mousemove", function (event) {
149008             if (paint) {
149009                 currentPoint = event;
149010                 drawPoints();
149011             }
149012         });
149013
149014         canvas.addEventListener("mouseup", endDraw);
149015         canvas.addEventListener("mouseout", endDraw);
149016         canvas.addEventListener("mouseleave", endDraw);
149017
149018         document.getElementById(constants.TOUCHEVENT.OPTION).addEventListener("click", function () {
149019             if (!moveEvents[0])
149020                 return;
149021
149022             if (this.value === "Touch Start") {
149023                 this.value = "Touch Cancel";
149024                 _exec("start");
149025             } else if (this.value === "Touch Cancel") {
149026                 this.value = "Touch Start";
149027                 _exec("cancel");
149028             }
149029         }, false);
149030
149031         canvas.width = deviceInfo.screen.width / enlargeRatio;
149032         canvas.height = deviceInfo.screen.height / enlargeRatio;
149033     }
149034 };
149035
149036 });
149037 define('ripple/ui/plugins/vehicle', function (require, exports, module) {
149038 /*
149039  *  Copyright 2013 Research In Motion Limited.
149040  *
149041  * Licensed under the Apache License, Version 2.0 (the "License");
149042  * you may not use this file except in compliance with the License.
149043  * You may obtain a copy of the License at
149044  *
149045  * http://www.apache.org/licenses/LICENSE-2.0
149046  *
149047  * Unless required by applicable law or agreed to in writing, software
149048  * distributed under the License is distributed on an "AS IS" BASIS,
149049  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149050  * See the License for the specific language governing permissions and
149051  * limitations under the License.
149052  */
149053 var event = require('ripple/event'),
149054     exception = require('ripple/exception'),
149055     vehiclePanelEngine = require('ripple/platform/ivi/3.0/VehiclePanelEngine').VehiclePanelEngine,
149056     _vehicleGlobalVars = {
149057         currentAutoStatus: false,
149058         currentDataIndex: 0,
149059         timeFlag: null,
149060         timeInterval: 1000, //ms
149061         timeCurrent: 0,
149062         timeHistoryArray: [],
149063         timeHistoryLimit: 60 * 60,
149064         registerListeners: {},
149065         vehicleCache: {},
149066         history: {},
149067         notShowProperties: [
149068             "zone", "time", "source"
149069         ]
149070     };
149071
149072 function _interceptString (str, length) {
149073     return str.length > length ? str.substring(0, length) + "...": str;
149074 }
149075
149076 function _setVehicleConfigurationSel (configuration) {
149077     var selContainer = jQuery("#vehicle-container #vehicle-configuration-types"),
149078         html = "", i = 0;
149079
149080     for (var value in configuration) {
149081         html += '<option value="' + value + '">' +
149082             'Car ' + i +
149083             '</option>';
149084
149085         i++;
149086     }
149087
149088     selContainer.html(html);
149089 }
149090
149091 function _setVehicleConfiguration (configuration, currentType) {
149092     var container = jQuery("#vehicle-container #vehicle-configuration-show"),
149093         selContainer = jQuery("#vehicle-container #vehicle-configuration-types"),
149094         current, property, propertyList, item, unit, html = "", i,
149095         enums, showValue;
149096
149097     if (currentType !== selContainer.val()) {
149098         for (i = 0; i < selContainer[0].options.length; i++) {
149099             if (selContainer[0].options[i].value === currentType) {
149100                 selContainer[0].selectedIndex = i;
149101                 break;
149102             }
149103         }
149104         if (i >= selContainer[0].options.length ) {
149105             throw "undefined configuration: " + currentType + ".";
149106         }
149107     }
149108
149109     current = configuration[currentType];
149110     if (!current) {
149111         throw "undefined configuration: " + currentType + ".";
149112     }
149113
149114     for (property in current) {
149115         html += '<tr><td colspan="2" class="vehicle-property-header">' + property + '</td></tr>';
149116
149117         propertyList = current[property];
149118         for (item in propertyList) {
149119             showValue = propertyList[item];
149120             unit = vehiclePanelEngine.getPropertyUnit(property, item);
149121             enums = vehiclePanelEngine.getPropertyConstant(property, item);
149122             if (enums) {
149123                 showValue = enums["val" + showValue];
149124             }
149125
149126             html += '<tr class="vehicle-property-content">' +
149127                 '<td class="vehicle-property-label"> ' + item + unit + '</td>' +
149128                 '<td class="vehicle-property-value" id="' + property + '-' + item + '-show">' + showValue + '</td>' +
149129                 '<td style="display: none;">' +
149130                 '<input id="' + property + '-' + item + '-set" type="hidden" ' + 'value="' + propertyList[item] + '" />' +
149131                 '</td></tr>';
149132         }
149133     }
149134
149135     container.html(html);
149136     return;
149137 }
149138
149139 function _setVehicleSupported (properties, supported) {
149140     var hideContainer = jQuery("#vehicle-container #vehicle-supported-hide"),
149141         showContainer = jQuery("#vehicle-container #vehicle-supported-show"),
149142         hideHtml = "", showHtml = "", tempHtml, column = 0, columnNum = 3, className,
149143         i, property, propertyAbbr;
149144
149145     for (i = 0; i < properties.length; i++) {
149146         property = properties[i];
149147         propertyAbbr = _interceptString(property, 12);
149148
149149         if (supported.indexOf(property) > -1) {
149150             className = "vehicle-property-supported";
149151             hideHtml += '<input type="checkbox" id="' + property + '-supported" value="' + property + '" checked="checked" />';
149152         }
149153         else {
149154             className = "vehicle-property-unsupported";
149155             hideHtml += '<input type="checkbox" id="' + property + '-supported" value="' + property + '" />';
149156         }
149157
149158         tempHtml = '<td id="' + property + '-supported-show" ' + 'class="' + className + '" title="' + property + '">' + propertyAbbr + '</td>';
149159
149160         if (column % columnNum === 0) {
149161             showHtml += '<tr>' + tempHtml;
149162         }
149163         else if (column % columnNum === (columnNum - 1)){
149164             showHtml += tempHtml + '</tr>';
149165         }
149166         else {
149167             showHtml += tempHtml;
149168         }
149169         column++;
149170     }
149171
149172     hideContainer.html(hideHtml);
149173     showContainer.html(showHtml);
149174 }
149175
149176 function _setVehicleSetting (settings) {
149177     var settingContainer = jQuery("#vehicle-container #vehicle-setting-show"),
149178         property, propertyItems, item, html = "", unit, range,
149179         optionHtml = "", i, optionName, option, options;
149180
149181     for (property in settings) {
149182         html += '<tr><td colspan="2" class="vehicle-property-header">' + property + '</td></tr>';
149183
149184         propertyItems = settings[property];
149185         for (item in propertyItems) {
149186             unit = vehiclePanelEngine.getPropertyUnit(property, item);
149187
149188             if (propertyItems[item].type === "radio" || propertyItems[item].type === "select") {
149189                 optionHtml = "";
149190                 options = propertyItems[item].options;
149191                 for (i = 0; i < options.length; i++) {
149192                     option = options[i];
149193                     for (optionName in option) {
149194                         if (option[optionName].toString() === propertyItems[item].value.toString()) {
149195                             optionHtml += '<option value="' + option[optionName] + '" selected>' +
149196                                 optionName + '</option>';
149197                         }
149198                         else {
149199                             optionHtml += '<option value="' + option[optionName] + '">' +
149200                                 optionName + '</option>';
149201                         }
149202                         break;
149203                     }
149204                 }
149205                 html += '<tr class="vehicle-property-content">' +
149206                     '<td class="vehicle-property-label" title="' + item + unit  + '">' + _interceptString(item + unit, 18)  + '</td>' +
149207                     '<td class="vehicle-property-value">' +
149208                     '<select id="' + property + '-' + item + '-set">' + optionHtml + '</select>' +
149209                     '</td></tr>';
149210             }
149211             else if (propertyItems[item].type === "range") {
149212                 range = vehiclePanelEngine.getPropertyRange(property, item);
149213
149214                 html += '<tr class="vehicle-property-content">' +
149215                     '<td class="vehicle-property-label" title="' + item + unit  + '">' + _interceptString(item + unit, 18)  + '</td>' +
149216                     '<td class="vehicle-property-value">' +
149217                     '<label id="' + property + '-' + item + '-num">' + propertyItems[item].value + '</label>' +
149218                     '<input id="' + property + '-' + item + '-set" type="range" value="' + propertyItems[item].value + '"' +
149219                         ' min="' + range[0] + '" max="' + range[1] + '" step="' + range[2] + '" class="vehicle-property-range" />' +
149220                     '</td></tr>';
149221             }
149222             else if (propertyItems[item].type === "text") {
149223                 html += '<tr class="vehicle-property-content">' +
149224                     '<td class="vehicle-property-label" title="' + item + unit  + '">' + _interceptString(item + unit, 18)  + '</td>' +
149225                     '<td class="vehicle-property-value">' +
149226                     '<input id="' + property + '-' + item + '-set" type="text" value="' + propertyItems[item].value + '" />' +
149227                     '</td></tr>';
149228             }
149229         }
149230     }
149231
149232     settingContainer.html(html);
149233 }
149234
149235 function _addArrayValueEnter (property, item, value) {
149236     var itemValue, html = "", i,
149237         id = property + '-' + item + "-set";
149238
149239     itemValue = value.split(",");
149240
149241     if (jQuery("#" + id + "Array") && jQuery("#" + id + "Array").length === 1) {
149242         html += '<td colspan="3">';
149243     }
149244     else {
149245         html += '<tr id="'+ id + 'Array" class="vehicle-property-array">' +
149246             '<td colspan="3">';
149247     }
149248
149249     if (itemValue.length === 0) {
149250         html += '<div class="vehicle-property-arrayItem">' +
149251             '<button>add</button>' +
149252             '<input type="text" value="0" />' +
149253             '<button>del</button>' +
149254             '</div>';
149255     }
149256     else {
149257         for (i = 0; i < itemValue.length; i++) {
149258             if (i === itemValue.length - 1) {
149259                 html += '<div class="vehicle-property-arrayItem">' +
149260                     '<button style="margin-left: -60px;">add</button>' +
149261                     '<input type="text" value="' + itemValue[i] + '" />' +
149262                     '<button >del</button>' +
149263                     '</div>';
149264             }
149265             else {
149266                 html += '<div class="vehicle-property-arrayItem">' +
149267                     '<button style="display: none;">add</button>' +
149268                     '<input type="text" value="' + itemValue[i] + '" />' +
149269                     '<button >del</button>' +
149270                     '</div>';
149271             }
149272         }
149273     }
149274
149275     if (jQuery("#" + id + "Array") && jQuery("#" + id + "Array").length === 1) {
149276         html += '</td>';
149277
149278         jQuery("#" + id + "Array").html(html);
149279     }
149280     else {
149281         html += '</td></tr>';
149282
149283         html += '<tr id="'+ id + 'OK" class="vehicle-property-array">' +
149284             '<td colspan="3">';
149285         html += '<button class="vehicle-property-arrayOk">OK</button>';
149286         html += '</td></tr>';
149287     }
149288
149289     return html;
149290 }
149291
149292 function _setVehicleAutoRunning (autoRunning, isFill) {
149293     var autoContainer = jQuery("#vehicle-container #vehicle-running-show"),
149294         timeStamp, html = "", unit,  range, property, propertyItem, value, data,
149295         showContainer, setContainer, valueField, options, option, optionName, i,
149296         enums, showValue;
149297
149298     timeStamp = (new Date()).getTime();
149299     data = autoRunning["auto" + _vehicleGlobalVars.currentDataIndex];
149300     if (!data) {
149301         _vehicleGlobalVars.currentDataIndex = 0;
149302         data = autoRunning["auto0"];
149303     }
149304     _vehicleGlobalVars.timeCurrent = timeStamp;
149305
149306     if (!isFill) {
149307         html += '<tr class="vehicle-property-content">' +
149308             '<td class="vehicle-property-label">Time</td>' +
149309             '<td class="vehicle-property-value" id="vehicle-time-show">' + timeStamp + '</td></tr>';
149310
149311         for (property in data) {
149312             html += '<tr><td colspan="2" class="vehicle-property-header">' + property + '</td></tr>';
149313
149314             for (propertyItem in data[property]) {
149315                 value = data[property][propertyItem].value;
149316                 unit = vehiclePanelEngine.getPropertyUnit(property, propertyItem);
149317
149318                 if (Object.prototype.toString.call(value) === '[object Array]') {
149319                     value = value.join(",");
149320                 }
149321
149322                 if (data[property][propertyItem].type === "radio" || data[property][propertyItem].type === "select") {
149323                     valueField = "";
149324                     options = data[property][propertyItem].options;
149325                     for (i = 0; i < options.length; i++) {
149326                         option = options[i];
149327                         for (optionName in option) {
149328                             if (option[optionName].toString() === data[property][propertyItem].value) {
149329                                 valueField += '<option value="' + option[optionName] + '" selected>' +
149330                                     optionName + '</option>';
149331                             }
149332                             else {
149333                                 valueField += '<option value="' + option[optionName] + '">' +
149334                                     optionName + '</option>';
149335                             }
149336                             break;
149337                         }
149338                     }
149339
149340                     valueField = '<select id="' + property + '-' + propertyItem + '-set">' + valueField + '</select>';
149341                 }
149342                 else if (data[property][propertyItem].type === "range") {
149343                     range = vehiclePanelEngine.getPropertyRange(property, propertyItem);
149344
149345                     valueField = '<label id="' + property + '-' + propertyItem + '-num">' + value + '</label>' +
149346                         '<input id="' + property + '-' + propertyItem + '-set" type="range" value="' + value + '"' +
149347                         ' min="' + range[0] + '" max="' + range[1] + '" step="' + range[2] + '" class="vehicle-property-range" />';
149348                 }
149349                 else if (data[property][propertyItem].type === "text") {
149350                     valueField = '<input type="text" value="' + value +'" id="' + property + '-' + propertyItem + '-set" disabled />';
149351                 }
149352
149353                 enums = vehiclePanelEngine.getPropertyConstant(property, propertyItem);
149354                 if (enums) {
149355                     showValue = enums["val" + value];
149356                 }
149357
149358                 html += '<tr class="vehicle-property-content">' +
149359                     '<td class="vehicle-property-label" title="' + propertyItem + unit  + '">' + _interceptString(propertyItem + unit, 18) + '</td>' +
149360                     '<td class="vehicle-property-value vehicle-property-value-auto" id="' + property + '-' + propertyItem + '-show">' + showValue + '</td>' +
149361                     '<td class="vehicle-property-value vehicle-property-value-manual">' +
149362                     valueField +
149363                     '</td></tr>';
149364
149365                 if (data[property][propertyItem].type === "text") {
149366                     html += _addArrayValueEnter(property, propertyItem, value);
149367                 }
149368
149369                 if (_vehicleGlobalVars.registerListeners[property]) {
149370                     event.trigger("vehicle-subscribe-request", [property, false, 0]);
149371                 }
149372             }
149373         }
149374
149375         autoContainer.html(html);
149376         _switchAutoManual(false);
149377     }
149378     else {
149379         if (_vehicleGlobalVars.currentAutoStatus) {
149380             for (property in data) {
149381
149382                 for (propertyItem in data[property]) {
149383                     value = data[property][propertyItem].value;
149384
149385                     showContainer = jQuery("#vehicle-container #vehicle-running-show #" + property + '-' + propertyItem + "-show");
149386                     setContainer = jQuery("#vehicle-container #vehicle-running-show #" + property + '-' + propertyItem + "-set");
149387
149388                     if (Object.prototype.toString.call(value) === '[object Array]') {
149389                         value = value.join(",");
149390                     }
149391
149392                     if (data[property][propertyItem].type === "text") {
149393                         _addArrayValueEnter(property, propertyItem, value);
149394                     }
149395
149396                     if (showContainer && setContainer) {
149397                         showContainer.html(value);
149398                         setContainer.val(value);
149399                     }
149400                 }
149401             }
149402         }
149403         else {
149404         }
149405         jQuery("#vehicle-container #vehicle-running-show #vehicle-time-show").html(timeStamp);
149406     }
149407
149408     for (property in _vehicleGlobalVars.registerListeners) {
149409         event.trigger("vehicle-subscribe-request", [property, false, 0]);
149410     }
149411
149412     _saveVehicleData();
149413     _vehicleGlobalVars.currentDataIndex++;
149414 }
149415
149416 function _formatHistory (historyData, time, zone, source) {
149417     var format = {}, property, name, item, value;
149418
149419     for (property in historyData) {
149420         name = property.split("-")[0];
149421         item = property.split("-")[1];
149422
149423         if (!format[name]) {
149424             format[name] = {};
149425             format[name].time = time;
149426             format[name].zone = zone;
149427             format[name].source = source;
149428         }
149429
149430         value = historyData[property];
149431         if (value.indexOf(",") > -1) {
149432             value = value.split(",");
149433         }
149434         if (value === "true") value = true;
149435         if (value === "false") value = false;
149436
149437         format[name][item] = value;
149438     }
149439
149440     return format;
149441 }
149442
149443 function _saveVehicleData () {
149444     var configurationContainer = jQuery("#vehicle-container #vehicle-configuration-show *[id$='-set']"),
149445         currentConfigContainer = jQuery("#vehicle-container #vehicle-configuration-types"),
149446         settingContainer = jQuery("#vehicle-container #vehicle-setting-show  *[id$='-set']"),
149447         autoContainer = jQuery("#vehicle-container #vehicle-running-show  *[id$='-set']"),
149448         supportedContainer = jQuery("#vehicle-container #vehicle-supported-hide  *[id$='-supported']:checked"),
149449         supported = [], currentConfig, configuration = [], setting = [], autoRunning = [],
149450         history = {}, itemKey, format, delTime, time, zone, source;
149451
149452     supportedContainer.each(function (index, item) {
149453         supported.push(item.value);
149454     });
149455
149456     currentConfig = currentConfigContainer.val().replace("configuration", "");
149457
149458     configurationContainer.each(function (index, item) {
149459         itemKey = item.id.replace("-set", "");
149460         history[itemKey] = item.value;
149461
149462         configuration.push(item.value);
149463     });
149464
149465     settingContainer.each(function (index, item) {
149466         itemKey = item.id.replace("-set", "");
149467         history[itemKey] = item.value;
149468
149469         setting.push(item.value);
149470     });
149471
149472     autoContainer.each(function (index, item) {
149473         var value;
149474
149475         value = item.value;
149476         if (item.id.indexOf("TripMeter") > -1) {
149477             value = item.value.split(",");
149478         }
149479
149480         itemKey = item.id.replace("-set", "");
149481         history[itemKey] = value;
149482
149483         autoRunning.push(value);
149484     });
149485
149486     _vehicleGlobalVars.timeHistoryArray.push(_vehicleGlobalVars.timeCurrent);
149487     if (_vehicleGlobalVars.timeHistoryArray.length > _vehicleGlobalVars.timeHistoryLimit) {
149488         delTime = _vehicleGlobalVars.timeHistoryArray.shift();
149489         delete _vehicleGlobalVars.history[delTime];
149490     }
149491
149492     time = _vehicleGlobalVars.timeCurrent;
149493     source = "";
149494     zone = 0;
149495
149496     format = _formatHistory(history, time, zone, source);
149497     _vehicleGlobalVars.history[_vehicleGlobalVars.timeCurrent] = format;
149498     event.trigger("vehicle-cache-refresh", [supported, format]);
149499
149500     vehiclePanelEngine.saveData(supported, currentConfig, configuration, setting, autoRunning);
149501 }
149502
149503 function _switchAutoManual (isAuto) {
149504     var autoContainer = jQuery("#vehicle-container #vehicle-running-show .vehicle-property-value-auto"),
149505         manualContainer = jQuery("#vehicle-container #vehicle-running-show .vehicle-property-value-manual"),
149506         arrayContainer = jQuery("#vehicle-container #vehicle-running-show .vehicle-property-array"),
149507         autoBtnContainer = jQuery("#vehicle-container #vehicle-running-auto");
149508
149509     if (isAuto) {
149510         autoBtnContainer.addClass("vehicle-property-supported");
149511         autoBtnContainer.removeClass("vehicle-property-unsupported");
149512         autoContainer.show();
149513         manualContainer.hide();
149514         arrayContainer.hide();
149515     }
149516     else {
149517         autoBtnContainer.addClass("vehicle-property-unsupported");
149518         autoBtnContainer.removeClass("vehicle-property-supported");
149519         autoContainer.hide();
149520         manualContainer.show();
149521         arrayContainer.show();
149522     }
149523 }
149524
149525 function _addVehicleDomEventListener () {
149526     var configSelection = jQuery("#vehicle-container #vehicle-configuration-types"),
149527         supportedSelection = jQuery("#vehicle-container #vehicle-supported-show td"),
149528         autoSelection = jQuery("#vehicle-container #vehicle-running-auto"),
149529         arraySelection = jQuery("#vehicle-container .vehicle-property-array"),
149530         arrayOKSelection = jQuery("#vehicle-container .vehicle-property-arrayOk"),
149531         rangeSelection = jQuery("#vehicle-container input[type='range']");
149532
149533     arraySelection.delegate("button", "click", function () {
149534         var els = jQuery(this), appHtml;
149535
149536         appHtml = '<div class="vehicle-property-arrayItem">' +
149537             '<button style="margin-left: -60px;">add</button>' +
149538             '<input type="text" value="0" />' +
149539             '<button >del</button>' +
149540             '</div>';
149541
149542         if (els.html() === "add") {
149543             jQuery(appHtml).insertAfter(els.parent());
149544             els.hide();
149545         }
149546         else if (els.html() === "del") {
149547             if (els.parent().prev().length === 0 && els.parent().next().length === 0)
149548                 return;
149549             els.parent().prev().find("button")[0].style.marginLeft = "-60px";
149550             els.parent().prev().find("button")[0].style.display = "";
149551             els.parent().remove();
149552         }
149553     });
149554
149555     arrayOKSelection.click("click", function () {
149556         var els = jQuery(this), inputEls, i, trEls,
149557             setElsId, value = [];
149558
149559         trEls = els.parent().parent();
149560         setElsId = trEls.attr("id").replace("OK", "");
149561
149562         inputEls = trEls.prev().find("input");
149563         for (i = 0; i < inputEls.length; i++)  {
149564             value.push(inputEls[i].value);
149565         }
149566
149567         jQuery("#vehicle-container #" + setElsId).val(value.join(","));
149568     });
149569
149570     rangeSelection.bind("change", function () {
149571         var domJQuery = jQuery(this);
149572
149573         domJQuery.prev().html(domJQuery.val());
149574     });
149575
149576     configSelection.bind("change", function () {
149577         var configuration, current,
149578             domJQuery = jQuery(this);
149579
149580         configuration = _vehicleGlobalVars.vehicleCache.configurationData;
149581         current = domJQuery.val();
149582         _setVehicleConfiguration(configuration, current);
149583     });
149584
149585     //add vehicle supported click event
149586     supportedSelection.bind("click", function () {
149587         var domJQuery = jQuery(this), vehicleChecked,
149588             propertiesSelector = "#vehicle-container #vehicle-supported-hide",
149589             content, supportedId, inputJQuery;
149590
149591         content = domJQuery.html();
149592         supportedId = content + "-supported";
149593         inputJQuery = jQuery(propertiesSelector + " #" + supportedId);
149594         if (domJQuery.hasClass("vehicle-property-unsupported")) {
149595             inputJQuery.attr("checked", "checked");
149596             domJQuery.removeClass("vehicle-property-unsupported");
149597             domJQuery.addClass("vehicle-property-supported");
149598         }
149599         else {
149600             inputJQuery.removeAttr("checked");
149601             domJQuery.removeClass("vehicle-property-supported");
149602             domJQuery.addClass("vehicle-property-unsupported");
149603         }
149604
149605         vehicleChecked = jQuery("#vehicle-container #vehicle-supported-hide input:checked");
149606         _vehicleGlobalVars.vehicleCache.supported.length = 0;
149607         vehicleChecked.each(function (index, els) {
149608             _vehicleGlobalVars.vehicleCache.supported.push(els.value);
149609         });
149610     });
149611
149612     //add vehicle auto click event
149613     autoSelection.bind("click", function () {
149614         if (_vehicleGlobalVars.currentAutoStatus) {
149615             _vehicleGlobalVars.currentAutoStatus = false;
149616             jQuery("#vehicle-container #vehicle-configuration-noOperation").hide();
149617             jQuery("#vehicle-container #vehicle-supported-noOperation").hide();
149618         }
149619         else {
149620             _vehicleGlobalVars.currentAutoStatus = true;
149621             jQuery("#vehicle-container #vehicle-configuration-noOperation").show();
149622             jQuery("#vehicle-container #vehicle-supported-noOperation").show();
149623         }
149624         _switchAutoManual(_vehicleGlobalVars.currentAutoStatus);
149625
149626         _vehicleGlobalVars.timeFlag = setInterval(function () {
149627             _setVehicleAutoRunning(_vehicleGlobalVars.vehicleCache.autoRunningData, true);
149628         }, _vehicleGlobalVars.timeInterval);
149629     });
149630 }
149631
149632 function _addVehicleEventListener () {
149633     event.once("vehicle-cache-request", function (data) {
149634         data.supported = _vehicleGlobalVars.vehicleCache.supported;
149635         data.data = _vehicleGlobalVars.history[_vehicleGlobalVars.timeCurrent];
149636     });
149637
149638     event.on("vehicle-subscribe-request", function (property, isRegister, zone) {
149639         if (isRegister) {
149640             _vehicleGlobalVars.registerListeners[property] = true;
149641             return;
149642         }
149643
149644         var value, status, time, history,
149645             propertyObj = {};
149646
149647         if (_vehicleGlobalVars.vehicleCache.supported.indexOf(property) === -1) {
149648             propertyObj.val = null;
149649             propertyObj.supported = false;
149650             propertyObj.type = property;
149651         }
149652         else {
149653             history = _vehicleGlobalVars.history;
149654             time = _vehicleGlobalVars.timeCurrent;
149655
149656             value = history[time][property];
149657             value.time = time;
149658             status = true;
149659
149660             propertyObj.val = value;
149661             propertyObj.supported = status;
149662             propertyObj.type = property;
149663         }
149664
149665         event.trigger("vehicle-subscribe-response", [propertyObj]);
149666     });
149667
149668     event.on("vehicle-set-request", function (property, value) {
149669         var status = true, enums, showValue;
149670
149671         for (var item in value) {
149672             var enterID = property + "-" + item + "-set";
149673             var showID = property + "-" + item + "-show";
149674             var enterContainer = jQuery("#vehicle-container #" + enterID);
149675             var showContainer = jQuery("#vehicle-container #" + showID);
149676
149677             if (Object.prototype.toString.call(value[item]) === '[object Array]') {
149678                 enterContainer.val(value[item].join(","));
149679             }
149680             else {
149681                 enterContainer.val(value[item].toString());
149682             }
149683             if (showContainer) {
149684                 enums = vehiclePanelEngine.getPropertyConstant(property, item);
149685                 showValue = value[item];
149686                 if (enums) {
149687                     showValue = enums["val" + value[item]];
149688                 }
149689                 showContainer.html(showValue);
149690             }
149691         }
149692
149693         event.trigger("vehicle-set-response", [status]);
149694     });
149695
149696     event.on("vehicle-history-request", function (property, zone, startTime, endTime) {
149697         var history, historyResponse = [], obj, status, time;
149698
149699         history = _vehicleGlobalVars.history;
149700
149701         for (time in history) {
149702             if (time >= startTime && time <= endTime &&
149703                 history[time].hasOwnProperty(property)) {
149704                 obj = history[time][property];
149705                 obj.time = time;
149706                 historyResponse.push(obj);
149707             }
149708         }
149709         status = true;
149710
149711         event.trigger("vehicle-history-response", [historyResponse, status]);
149712     });
149713 }
149714
149715 function _initializeVehiclePanel () {
149716     try {
149717         var stop = false,
149718             configuration, current, properties, supported, settings,
149719             autoRunning;
149720
149721         _vehicleGlobalVars.timeHistoryArray = [];
149722
149723         configuration = vehiclePanelEngine.getConfiguration();
149724         current = vehiclePanelEngine.getCurrentConfiguration();
149725         _setVehicleConfigurationSel(configuration);
149726         _vehicleGlobalVars.vehicleCache.configurationData = configuration;
149727         _vehicleGlobalVars.vehicleCache.currentConfiguration = current;
149728         _setVehicleConfiguration(configuration, current);
149729
149730         properties = vehiclePanelEngine.getProperties();
149731         supported = vehiclePanelEngine.getSupported();
149732         _vehicleGlobalVars.vehicleCache.properties = properties;
149733         _vehicleGlobalVars.vehicleCache.supported = supported;
149734         _setVehicleSupported(properties, supported);
149735
149736         settings = vehiclePanelEngine.getSettings();
149737         _vehicleGlobalVars.vehicleCache.settingData = settings;
149738         _setVehicleSetting(settings);
149739
149740         autoRunning = vehiclePanelEngine.getAutoRunning();
149741         _vehicleGlobalVars.vehicleCache.autoRunningData = autoRunning;
149742         _setVehicleAutoRunning(autoRunning, false);
149743         _vehicleGlobalVars.currentDataIndex = 0;
149744
149745         _vehicleGlobalVars.timeFlag = setInterval(function () {
149746             _setVehicleAutoRunning(_vehicleGlobalVars.vehicleCache.autoRunningData, true);
149747         }, _vehicleGlobalVars.timeInterval);
149748
149749         _addVehicleDomEventListener();
149750
149751         _addVehicleEventListener();
149752
149753         jQuery("#vehicle-properties h3").click(function (event) {
149754             if (stop) {
149755                 event.stopImmediatePropagation();
149756                 event.preventDefault();
149757                 stop = false;
149758             }
149759         });
149760         jQuery("#vehicle-properties").accordion("destroy").accordion({
149761             header: "> div > h3",
149762             autoHeight: false
149763         });
149764     } catch (e) {
149765         exception.handle(e, true);
149766     }
149767 }
149768
149769 module.exports = {
149770     panel: {
149771         domId: "vehicle-container",
149772         collapsed: true,
149773         pane: "right",
149774         titleName: "Vehicle Information",
149775         display: true
149776     },
149777     initialize: function () {
149778         _initializeVehiclePanel();
149779     }
149780 };
149781
149782 });
149783 define('ripple/ui/plugins/videoPlayer', function (require, exports, module) {
149784 /*
149785  *  Copyright 2011 Research In Motion Limited.
149786  *
149787  * Licensed under the Apache License, Version 2.0 (the "License");
149788  * you may not use this file except in compliance with the License.
149789  * You may obtain a copy of the License at
149790  *
149791  * http://www.apache.org/licenses/LICENSE-2.0
149792  *
149793  * Unless required by applicable law or agreed to in writing, software
149794  * distributed under the License is distributed on an "AS IS" BASIS,
149795  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149796  * See the License for the specific language governing permissions and
149797  * limitations under the License.
149798  */
149799 var constants = require('ripple/constants'),
149800     event = require('ripple/event');
149801
149802 module.exports = {
149803     initialize: function () {
149804         var videoObj,
149805             videoProgress = document.getElementById(constants.COMMON.MULTIMEDIA_VIDEO_PROGRESS_ID);
149806
149807         event.on("MultimediaAppVideoPlayerCreated", function (videoDOMObj) {
149808             videoObj = videoDOMObj;
149809
149810             videoObj.addEventListener("timeupdate", function () {
149811                 var s = parseInt(videoObj.currentTime % 60, 10),
149812                     m = parseInt((videoObj.currentTime / 60) % 60, 10);
149813
149814                 videoProgress.innerText = ((m > 9) ? m  : "0" + m) + ':' + ((s > 9) ? s  : "0" + s);
149815             }, false);
149816         });
149817
149818         event.on("MultimediaVolumeChanged", function (volume) {
149819             if (videoObj) {
149820                 videoObj.volume = parseFloat(volume / 10);
149821             }
149822         });
149823
149824         event.on("MultimediaVideoStateChanged", function (state) {
149825             document.getElementById(constants.COMMON.MULTIMEDIA_VIDEO_STATE_FIELD_ID).innerText = state;
149826             document.getElementById(constants.COMMON.MULTIMEDIA_VIDEO_FILE_FIELD_ID).innerText = videoObj.getAttribute("src");
149827         });
149828     }
149829 };
149830
149831 });
149832 define('ripple/ui/plugins/widgetConfig', function (require, exports, module) {
149833 /*
149834  *  Copyright 2011 Research In Motion Limited.
149835  *
149836  * Licensed under the Apache License, Version 2.0 (the "License");
149837  * you may not use this file except in compliance with the License.
149838  * You may obtain a copy of the License at
149839  *
149840  * http://www.apache.org/licenses/LICENSE-2.0
149841  *
149842  * Unless required by applicable law or agreed to in writing, software
149843  * distributed under the License is distributed on an "AS IS" BASIS,
149844  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149845  * See the License for the specific language governing permissions and
149846  * limitations under the License.
149847  */
149848 var constants = require('ripple/constants'),
149849     event = require('ripple/event'),
149850     utils = require('ripple/utils'),
149851     exception = require('ripple/exception'),
149852     tooltip = require('ripple/ui/plugins/tooltip'),
149853     platform = require('ripple/platform'),
149854     widgetConfig = require('ripple/widgetConfig');
149855
149856 function _buildConfigAccordionNode(node, accordionContainer, counter) {
149857     var nodeDiv, nodeTitleH3, nodeContentDiv, tableString, attribute, child, result,
149858         tableClass, nameClass, attributeNameClass, messageClass, nameId, messageId, attributeName, attributeValue, attributeMessage,
149859         helpText = {},
149860         nodeCounter = 0,
149861         attributeCounter = 0,
149862         moreNodes = node.validationResult,
149863         createTooltip = function (value, index) {
149864             tooltip.create("#" +  index, value);
149865         };
149866
149867     while (moreNodes) {
149868         result = node.validationResult[nodeCounter];
149869
149870         if (!result) {
149871             // this should never happen
149872             return;
149873         }
149874
149875         // the container of the entire accordion block
149876         nodeDiv = utils.createElement("div", {
149877             "id": "config-accordion-node-content-" + counter + "-" + nodeCounter,
149878             "class": "ui-corner-all"
149879         });
149880
149881         // the header bar of the accordion block
149882         nodeTitleH3 = utils.createElement("h3", {
149883             "id": "config-accordion-node-title-" + counter + "-" + nodeCounter,
149884             "class": "config-accordion-node-title"
149885         });
149886
149887         nodeTitleH3.appendChild(utils.createElement("a", {
149888             href: "#",
149889             innerText: node.nodeName,
149890             "class": constants.CONFIG.SUCCESS_CSS[(result.valid === undefined) ? "missing" : result.valid.toString()]
149891         }));
149892         nodeDiv.appendChild(nodeTitleH3);
149893
149894         if (node.helpText) {
149895             helpText[nodeTitleH3.id] = node.helpText;
149896         }
149897
149898         nodeContentDiv = utils.createElement("div");
149899
149900         // display node value (add tool tip if exists)
149901         if (node.type || (!node.type && result && result.value)) {
149902             nodeContentDiv.appendChild(utils.createElement("div", {
149903                 "id": "config-accordion-node-content-value-" + counter + "-" + nodeCounter,
149904                 "class": "config-accordion-node-content-value",
149905                 "innerHTML": "<span>Value:</span>" + (result.value || "")
149906             }));
149907
149908             if (node.helpValueText) {
149909                 helpText["config-accordion-node-content-value-" + counter + "-" + nodeCounter] = node.helpValueText;
149910             }
149911         }
149912
149913         // display node message if failed validation
149914         if (result && result.message) {
149915             nodeContentDiv.appendChild(utils.createElement("div", {
149916                 "id": "config-accordion-node-content-value-message-" + counter + "-" + nodeCounter,
149917                 "class": "config-accordion-node-content-value-message ui-text-fail",
149918                 "innerHTML": "<span>Message:</span>" + result.message
149919             }));
149920         }
149921
149922         // display node attributes with name, value, message if failed validation
149923         if (result.attributes) {
149924             nodeContentDiv.appendChild(utils.createElement("div", {
149925                 "id": "config-accordion-node-content-attributes-title-" + counter + "-" + nodeCounter,
149926                 "class": "config-accordion-node-content-attributes-title",
149927                 "innerHTML": "Attributes..."
149928             }));
149929
149930             tableClass = "preferences-table";
149931             nameClass = "config-attributes-name-value";
149932             attributeNameClass = "ui-text-label";
149933             messageClass = "config-attributes-message";
149934
149935             tableString = '<table class="' + tableClass + ' ui-widget-content">';
149936             for (attribute in result.attributes) {
149937                 if (result.attributes.hasOwnProperty(attribute)) {
149938                     nameId = "config-accordion-node-content-attributes-table-name-" + counter + "-" + nodeCounter + "-" + attributeCounter;
149939                     messageId = "config-accordion-node-content-attributes-table-message-" + counter + "-" + nodeCounter + "-" + attributeCounter;
149940                     attributeName = result.attributes[attribute].attributeName;
149941                     attributeValue = result.attributes[attribute].value || "&nbsp;";
149942                     attributeMessage = result.attributes[attribute].message || null;
149943
149944                     tableString += '<tr class="' + nameClass + '" id="' + nameId + '">' +
149945                             '<td class="' + attributeNameClass + '">' + attributeName + '</td>' +
149946                             '<td>' + attributeValue + '</td></tr>';
149947
149948                     if (node.attributes[attributeName].helpText) {
149949                         helpText[nameId] = node.attributes[attributeName].helpText;
149950                     }
149951
149952                     if (attributeMessage !== null) {
149953                         tableString += "<tr class=" + messageClass + " id=" + messageId + "><td colspan=\"2\">" +
149954                                 attributeMessage + "</td></tr>";
149955                     }
149956                     attributeCounter++;
149957                 }
149958             }
149959             tableString += "</table>";
149960
149961             nodeContentDiv.innerHTML += tableString;
149962         }
149963
149964
149965         nodeDiv.appendChild(nodeContentDiv);
149966         accordionContainer.appendChild(nodeDiv);
149967
149968         utils.forEach(helpText, createTooltip);
149969
149970         nodeCounter ++;
149971
149972         if (!node.validationResult[nodeCounter]) {
149973             nodeCounter = 0;
149974             moreNodes = false;
149975         }
149976     }
149977
149978     if (node.children) {
149979         for (child in node.children) {
149980             if (node.children.hasOwnProperty(child)) {
149981                 counter ++;
149982                 _buildConfigAccordionNode(node.children[child], accordionContainer, counter);
149983             }
149984         }
149985     }
149986 }
149987
149988 function _initializeConfigResultsView(results) {
149989     try {
149990         var rootNode,
149991             accordionContainer = document.getElementById("widget-config");
149992
149993         accordionContainer.innerHTML = "";
149994         if (!results) {
149995             accordionContainer.appendChild(utils.createElement("div", {
149996                 "class": "config-accordion-node-title " + constants.CONFIG.SUCCESS_CSS["false"],
149997                 "innerHTML": "Expected to find a configuration file for your application, but none is present. Please create" +
149998                         " a configuration file with the following name in the root directory of your application: " +
149999                         platform.current().fileName
150000             }));
150001             return;
150002         }
150003
150004         rootNode = results[results.rootElement];
150005
150006         _buildConfigAccordionNode(rootNode, accordionContainer, 0);
150007
150008         jQuery(function () {
150009             var stop = false;
150010             jQuery("#widget-config h3").click(function (event) {
150011                 if (stop) {
150012                     event.stopImmediatePropagation();
150013                     event.preventDefault();
150014                     stop = false;
150015                 }
150016             });
150017             jQuery("#widget-config").accordion("destroy").accordion({
150018                 header: "> div > h3",
150019                 autoHeight: false
150020             });
150021         });
150022     } catch (e) {
150023         exception.handle(e, true);
150024     }
150025 }
150026
150027 event.on("FrameHistoryChange", function () {
150028     module.exports.initialize();
150029 });
150030
150031 module.exports = {
150032     panel: {
150033         domId: "config-container",
150034         collapsed: true,
150035         pane: "right",
150036         titleName: "Application Configuration",
150037         display: true
150038     },
150039     initialize: function () {
150040         var results = widgetConfig.getValidationResults();
150041         _initializeConfigResultsView(results);
150042     }
150043 };
150044
150045 });
150046 define('ripple/ui/themes', function (require, exports, module) {
150047 /*
150048  *  Copyright 2011 Research In Motion Limited.
150049  *
150050  * Licensed under the Apache License, Version 2.0 (the "License");
150051  * you may not use this file except in compliance with the License.
150052  * You may obtain a copy of the License at
150053  *
150054  * http://www.apache.org/licenses/LICENSE-2.0
150055  *
150056  * Unless required by applicable law or agreed to in writing, software
150057  * distributed under the License is distributed on an "AS IS" BASIS,
150058  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150059  * See the License for the specific language governing permissions and
150060  * limitations under the License.
150061  */
150062 //module.exports = ["dark", "light"];
150063 module.exports = ["light"];
150064
150065 });
150066 define('ripple/ui', function (require, exports, module) {
150067 /*
150068  *  Copyright 2011 Research In Motion Limited.
150069  *
150070  * Licensed under the Apache License, Version 2.0 (the "License");
150071  * you may not use this file except in compliance with the License.
150072  * You may obtain a copy of the License at
150073  *
150074  * http://www.apache.org/licenses/LICENSE-2.0
150075  *
150076  * Unless required by applicable law or agreed to in writing, software
150077  * distributed under the License is distributed on an "AS IS" BASIS,
150078  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150079  * See the License for the specific language governing permissions and
150080  * limitations under the License.
150081  */
150082 var _self,
150083     db = require('ripple/db'),
150084     platform = require('ripple/platform'),
150085     constants = require('ripple/constants'),
150086     utils = require('ripple/utils'),
150087     exception = require('ripple/exception'),
150088     event = require('ripple/event'),
150089     themes = require('ripple/ui/themes'),
150090     _applicationStateId,
150091     _applicationState,
150092     _availablePanels,
150093     _applicationStateTmp,
150094     _systemPlugins = [
150095         "options",
150096         "about-dialog",
150097         "settings-dialog",
150098         "exec-dialog",
150099         "firstRunCheck",
150100         "eulaCheck",
150101         "devices",
150102         "goodVibrations",
150103         "panelCollapse",
150104         "platform",
150105         "information",
150106         "layout",
150107         "themeSwitcher",
150108         "settings-menu",
150109         "configWindow",
150110         "HWKeys"
150111         //"launchingHistory"
150112     ],
150113     _overlay = {
150114         getOrCreate: function (id) {
150115             var _container = document.getElementById(constants.COMMON.HTML_CONTAINER),
150116                 _overlays = document.getElementById("overlay-views"),
150117                 _overlay = _overlays.children[id],
150118                 _hide = function (node) {
150119                     node.setAttribute("style", "display: none");
150120                 },
150121                 _show = function (node) {
150122                     node.setAttribute("style", "display: block");
150123                 },
150124                 _trigger = function (callback) {
150125                     if (callback) {
150126                         callback.apply(null, [_overlay]);
150127                     }
150128                 };
150129
150130
150131             if (!_overlay) {
150132                 _overlay = utils.createElement("section", {id: id, "class": "overlay"});
150133                 _overlays.appendChild(_overlay);
150134             }
150135
150136             return {
150137                 hide: function (callback) {
150138                     _hide(_overlay);
150139                     _show(_container);
150140                     _trigger(callback);
150141                 },
150142                 show: function (callback, showContainer) {
150143                     _show(_overlay);
150144                     if (!showContainer) {
150145                         _hide(_container);
150146                     }
150147                     _trigger(callback);
150148                 }
150149             };
150150         }
150151     };
150152
150153 function _addUIPaneItemsToApplicationState(arrayObj, pane) {
150154     utils.forEach(arrayObj, function (domId) {
150155         var collapsed = jQuery("#" + domId + " .info")[0];
150156         collapsed = (collapsed.style && collapsed.style.display === "none") ? true : false;
150157         utils.forEach(_applicationStateTmp, function (obj) {
150158             if (obj.domId === domId) {
150159                 _applicationState.push({
150160                     "domId": domId,
150161                     "collapsed": collapsed,
150162                     "pane": pane,
150163                     "titleName" : obj.titleName,
150164                     "display" : obj.display
150165                 });
150166                 _applicationStateTmp.splice(_applicationStateTmp.indexOf(obj), 1);
150167                 return;
150168             }
150169         }, this);
150170     }, this);
150171
150172     utils.forEach(_applicationStateTmp, function (obj) {
150173         _applicationState.push({
150174             "domId": obj.domId,
150175             "collapsed": obj.collapsed,
150176             "pane": obj.pane,
150177             "titleName" : obj.titleName,
150178             "display" : obj.display
150179         });
150180     });
150181 }
150182
150183 function _currentlyEnabledTheme() {
150184     var qsSet = utils.queryString().theme,
150185         current = db.retrieve("ui-theme") || themes[0];
150186
150187     function matches(something) {
150188         return function (item) {
150189             return something === item;
150190         };
150191     }
150192
150193     if (qsSet && themes.some(matches(qsSet))) {
150194         current = qsSet;
150195         db.save("ui-theme", qsSet);
150196     }
150197
150198     return current;
150199 }
150200
150201 function _insertStyleSheets() {
150202     var uiTheme = db.retrieve("ui-theme") || require('ripple/ui/themes')[0],
150203         extensionURL = jQuery("#extension-url").text(),
150204         uiThemeURL = extensionURL + "themes/" + uiTheme + "/theme.css",
150205         head = document.getElementsByTagName('head')[0];
150206
150207     function stylesheet(src) {
150208         var scriptElement = document.createElement("link");
150209         scriptElement.setAttribute("href", src);
150210         scriptElement.setAttribute("type", "text/css");
150211         scriptElement.setAttribute("rel", "stylesheet");
150212         return scriptElement;
150213     }
150214
150215     head.appendChild(stylesheet(uiThemeURL));
150216 }
150217
150218 function _collapsePannels(side) {
150219     var collapseNode = [],
150220         event = document.createEvent("UIEvent");
150221
150222     collapseNode = side === "left" ? document.getElementsByClassName("left-panel-collapse") : 
150223                                      document.getElementsByClassName("right-panel-collapse");
150224     
150225     if (collapseNode.length > 0) {
150226         event.initEvent("click", true, true);
150227         collapseNode[0].dispatchEvent(event);    
150228     }
150229 }
150230
150231 function _initializeUI() {
150232     _applicationStateId = constants.COMMON.APPLICATION_STATE + platform.current().id;
150233     _applicationState = db.retrieveObject(_applicationStateId) || [];
150234     _insertStyleSheets();
150235
150236     var leftPanelSection = jQuery(".left"),
150237         uiBoxToggleEngaged = false;
150238
150239     //clean up
150240     db.remove("ui-application-state");
150241     utils.forEach(_availablePanels, function (obj) {
150242         var matchingDomId = function (panel) {
150243             return panel.domId === obj.domId;
150244         };
150245         if (!utils.some(_applicationState, matchingDomId)) {
150246             _applicationState.push({
150247                 "domId": obj.domId,
150248                 "collapsed": obj.collapsed,
150249                 "pane": obj.pane,
150250                 "titleName" : obj.titleName,
150251                 "display" : obj.display
150252             });
150253         }
150254     });
150255
150256     utils.forEach(_applicationState, function (obj) {
150257         var node = jQuery("#" + obj.domId),
150258             imgNode = node.find(".ui-box-TitleImage"),
150259             matchingDomId = function (panel) {
150260                 return panel.domId === obj.domId;
150261             };
150262
150263         if (node.length > 0) {
150264             if (!utils.some(_availablePanels, matchingDomId)) {
150265                 node.parent()[0].removeChild(node[0]);
150266             }
150267             else {
150268                 if (obj.display !== false) {
150269                     leftPanelSection.append(node.parent()[0].removeChild(node[0]));
150270                     if (!obj.collapsed) {
150271                         node.find(".info")
150272                             .css({
150273                             "display": "block"
150274                         })
150275                         .end()
150276                         .addClass("ui-box-open");
150277                         imgNode.addClass("ui-box-TitleImageOpen");
150278                     }
150279                 }
150280             }
150281         }
150282     });
150283
150284     db.saveObject(_applicationStateId, _applicationState);
150285
150286     event.on("ApplicationState", function () {
150287         try {
150288             var leftArray = jQuery(".left").sortable('toArray');
150289             _applicationStateTmp = [];
150290             _applicationStateTmp = utils.copy(_applicationState);
150291             _applicationState = [];
150292             _addUIPaneItemsToApplicationState(leftArray, "left");
150293
150294             if (leftArray.length === 0) {
150295                 _collapsePannels("left");
150296             }
150297
150298             db.saveObject(_applicationStateId, _applicationState);
150299         }
150300         catch (e) {
150301             exception.handle(e);
150302         }
150303     });
150304
150305     jQuery(".left").sortable({
150306         handle: ".drag-handle",
150307         revert: true,
150308         placeholder: 'ui-sortable-highlight ui-corner-all',
150309         connectWith: [".left"],
150310         scroll: true,
150311         update: function (uiEvent, ui) {
150312             event.trigger("ApplicationState");
150313         }
150314     });
150315
150316     jQuery(".left").sortable({ axis: 'y' });
150317
150318     jQuery(".collapse-handle").bind("click", function () {
150319         if (!uiBoxToggleEngaged) {
150320
150321             uiBoxToggleEngaged = true;
150322
150323             var jNode = jQuery(this).parentsUntil(".ui-box"),
150324                     pNode = jNode.parent(),
150325                     isOpen = pNode.hasClass("ui-box-open"),
150326                     imgNode = jQuery(this).find(".ui-box-TitleImage");
150327
150328             if (!isOpen) {
150329                 pNode.addClass("ui-box-open");
150330                 imgNode.removeClass("ui-box-TitleImageClosed");
150331                 imgNode.addClass("ui-box-TitleImageOpen");
150332             }
150333
150334             jQuery(this).parent().next().toggle("blind", {}, 300, function () {
150335                 if (isOpen) {
150336                     pNode.removeClass("ui-box-open");
150337                     imgNode.removeClass("ui-box-TitleImageOpen");
150338                     imgNode.addClass("ui-box-TitleImageClosed");
150339                 }
150340                 event.trigger("ApplicationState", [pNode]);
150341                 uiBoxToggleEngaged = false;
150342             });
150343         }
150344     });
150345 }
150346
150347 function _db_upgrade_for_release() {
150348     var version = db.retrieve(constants.RELEASE_VERSION);
150349
150350     // version: 20121115 is the first release version
150351     if (version === null || version === undefined || Number(version) < 20130722) {
150352         db.remove(constants.COMMON.APPLICATION_STATE + "tizen");
150353         db.remove(constants.COMMON.APPLICATION_STATE + "cordova");
150354         db.remove("tizen1-db-application");
150355         db.remove("tizen-db-package");
150356         version = 20130722;
150357         db.save(constants.RELEASE_VERSION, version);
150358     }
150359 }
150360
150361 _self = module.exports = {
150362     initialize: function () {
150363         var plugins = _systemPlugins.concat(platform.current().ui.plugins || []).map(function (name) {
150364                 return require('ripple/ui/plugins/' + name);
150365             }),
150366             boot = jWorkflow.order(_initializeUI);
150367
150368         _db_upgrade_for_release();
150369         _availablePanels = [];
150370
150371         plugins.forEach(function (plugin) {
150372             if (plugin.initialize) {
150373                 boot.andThen(plugin.initialize);
150374             }
150375
150376             if (plugin.panel) {
150377                 _availablePanels.push(plugin.panel);
150378             }
150379         });
150380
150381         boot.start();
150382     },
150383
150384     getSystemPlugins: function () {
150385         return utils.copy(_systemPlugins);
150386     },
150387
150388     register: function (plugin) {
150389         _systemPlugins.push(plugin);
150390     },
150391
150392     registered: function (plugin) {
150393         return _systemPlugins.indexOf(plugin) >= 0;
150394     },
150395
150396     getExtensionURL: function () {
150397         return jQuery("#" + constants.COMMON.EXTENSION_URL_CONTAINER).text();
150398     },
150399
150400     showOverlay: function (id, callback, showContainer) {
150401         _overlay.getOrCreate(id).show(callback, showContainer);
150402     },
150403
150404     hideOverlay: function (id, callback) {
150405         _overlay.getOrCreate(id).hide(callback);
150406     }
150407 };
150408
150409 });
150410 define('ripple/utils', function (require, exports, module) {
150411 /*
150412  *  Copyright 2011 Research In Motion Limited.
150413  *
150414  * Licensed under the Apache License, Version 2.0 (the "License");
150415  * you may not use this file except in compliance with the License.
150416  * You may obtain a copy of the License at
150417  *
150418  * http://www.apache.org/licenses/LICENSE-2.0
150419  *
150420  * Unless required by applicable law or agreed to in writing, software
150421  * distributed under the License is distributed on an "AS IS" BASIS,
150422  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150423  * See the License for the specific language governing permissions and
150424  * limitations under the License.
150425  */
150426 var self,
150427     exception = require('ripple/exception'),
150428     constants = require('ripple/constants'),
150429     _HtmlElements = ['header', 'footer', 'section', 'aside', 'nav', 'article'];
150430
150431 self = module.exports = {
150432     validateNumberOfArguments: function (lowerBound, upperBound, numberOfArguments, customExceptionType, customExceptionMessage, customExceptionObject) {
150433
150434         customExceptionMessage = customExceptionMessage || "";
150435
150436         if (arguments.length < 3 || arguments.length > 6) {
150437             exception.raise(exception.types.Argument, "Wrong number of arguments when calling: validateNumberOfArguments()");
150438         }
150439
150440         if (isNaN(lowerBound) && isNaN(upperBound) && isNaN(numberOfArguments)) {
150441             exception.raise(exception.types.ArgumentType, "(validateNumberOfArguments) Arguments are not numbers");
150442         }
150443
150444         lowerBound = parseInt(lowerBound, 10);
150445         upperBound = parseInt(upperBound, 10);
150446         numberOfArguments = parseInt(numberOfArguments, 10);
150447
150448         if (numberOfArguments < lowerBound || numberOfArguments > upperBound) {
150449             exception.raise((customExceptionType || exception.types.ArgumentLength), (customExceptionMessage + "\n\nWrong number of arguments"), customExceptionObject);
150450         }
150451
150452     },
150453
150454     validateArgumentType: function (arg, argType, customExceptionType, customExceptionMessage, customExceptionObject) {
150455         var invalidArg = false,
150456             msg;
150457
150458         switch (argType) {
150459         case "array":
150460             if (!arg instanceof Array) {
150461                 invalidArg = true;
150462             }
150463             break;
150464         case "date":
150465             if (!arg instanceof Date) {
150466                 invalidArg = true;
150467             }
150468             break;
150469         case "integer":
150470             if (typeof arg === "number") {
150471                 if (arg !== Math.floor(arg)) {
150472                     invalidArg = true;
150473                 }
150474             }
150475             else {
150476                 invalidArg = true;
150477             }
150478             break;
150479         default:
150480             if (typeof arg !== argType) {
150481                 invalidArg = true;
150482             }
150483             break;
150484         }
150485
150486         if (invalidArg) {
150487             msg = customExceptionMessage +  ("\n\nInvalid Argument type. argument: " + arg + " ==> was expected to be of type: " + argType);
150488             exception.raise((customExceptionType || exception.types.ArgumentType), msg, customExceptionObject);
150489         }
150490     },
150491
150492     validateMultipleArgumentTypes: function (argArray, argTypeArray, customExceptionType, customExceptionMessage, customExceptionObject) {
150493         for (var i = 0; i < argArray.length; i++) {
150494             this.validateArgumentType(argArray[i], argTypeArray[i], customExceptionType, customExceptionMessage, customExceptionObject);
150495         }
150496     },
150497
150498     createElement: function (elementType, attributes) {
150499         var d = document.createElement(elementType);
150500
150501         if (attributes) {
150502             this.forEach(attributes, function (attributeValue, attributeName) {
150503
150504                 switch (attributeName.toLowerCase()) {
150505
150506                 case "innerhtml":
150507                     d.innerHTML = attributeValue;
150508                     break;
150509
150510                 case "innertext":
150511                     d.innerText = attributeValue;
150512                     break;
150513
150514                 default:
150515                     d.setAttribute(attributeName, attributeValue);
150516                 }
150517
150518             });
150519         }
150520
150521         return d;
150522     },
150523
150524
150525     loadHTMLElements: function () {
150526         for (var i = 0; i < _HtmlElements.length; i += 1) {
150527             document.createElement(_HtmlElements[i]);
150528         }
150529     },
150530
150531     getAllStylesheetRules: function getAllStylesheetRules(title) {
150532         this.validateNumberOfArguments(1, 1, arguments.length);
150533
150534         var i, x, sheet, rules, styles_array = [];
150535
150536         // get style sheet according to title
150537         for (i = 0; i < document.styleSheets.length; i += 1) {
150538
150539             sheet = document.styleSheets[i];
150540             rules = sheet.cssRules;
150541
150542             if (rules) {
150543                 for (x = 0; x < rules.length; x += 1) {
150544                     if (rules[x].selectorText && rules[x].selectorText === (title.toString())) {
150545                         styles_array.push(rules[x]);
150546                     }
150547                 }
150548             }
150549         }
150550
150551         return (styles_array);
150552     },
150553
150554     location: function () {
150555         return window.location;
150556     },
150557
150558     queryString: function () {
150559         // trim the leading ? and split each name=value
150560         var args = this.location().search.replace(/^\?/, '').split('&');
150561
150562         return args.reduce(function (obj, value) {
150563             if (value) {
150564                 value = value.toLowerCase().split("=");
150565                 obj[value[0]] = value[1];
150566             }
150567             return obj;
150568         }, {});
150569     },
150570
150571     extensionUrl: function () {
150572         return document.getElementById("extension-url").innerText;
150573     },
150574
150575     appLocation: function () {
150576         if (require('ripple/ui').registered("omnibar")) {
150577             /* rootURL can only get url saved from 'FrameHistoryChange' event
150578                it causes trouble when navigating directory through online 
150579                version as index.html is automatically loaded.
150580                Need a way to get more updated URL */
150581
150582             var path = require('ripple/ui/plugins/omnibar').rootURL(),
150583                 parts;
150584
150585             if ((parts = path.match(/^((http[s]?|ftp|file):\/\/)(.+\/)?([^\/].+)$/i)) !== null && parts.length === 5) {
150586                 // this is a path already.
150587                 if (path.search(/\/$/, "") !== -1) {
150588                     return path;
150589                 }
150590                 if (parts[4] === "about:blank") {
150591                     path = "";
150592                 }
150593                 else if (parts[3]) {
150594                     path = parts[1] + parts[3];
150595                     if (parts[4].indexOf(".") === -1) {
150596                         path += parts[4] + "/";
150597                     }
150598                 }
150599                 else {
150600                     path = parts[1] + parts[4] + "/";
150601                 }
150602             }
150603             else {
150604                 path = "";
150605             }
150606             return path;
150607         }
150608         return self.rippleLocation();
150609     },
150610
150611     rippleLocation: function () {
150612         var loc = self.location(),
150613             parts = loc.pathname.replace(/\/$/, "").split("/"),
150614             base = "",
150615             port = loc.port ? ":" + loc.port : "";
150616
150617         if (parts[parts.length - 1].indexOf(".") !== -1) {
150618             parts = parts.splice(0, parts.length - 1);
150619         }
150620         base = parts.join("/");
150621
150622         return loc.protocol + "//" + loc.hostname + port + base + "/";
150623     },
150624
150625     arrayContains: function (array, obj) {
150626         var i = array.length;
150627         while (i--) {
150628             if (array[i] === obj) {
150629                 return true;
150630             }
150631         }
150632         return false;
150633     },
150634
150635     some: function (obj, predicate, scope) {
150636         if (obj instanceof Array) {
150637             return obj.some(predicate, scope);
150638         }
150639         else {
150640             var values = self.map(obj, predicate, scope);
150641
150642             return self.reduce(values, function (some, value) {
150643                 return value ? value : some;
150644             }, false);
150645         }
150646     },
150647
150648     count: function (obj) {
150649         return self.sum(obj, function (total) {
150650             return 1;
150651         });
150652     },
150653
150654     sum: function (obj, selector, scope) {
150655         var values = self.map(obj, selector, scope);
150656         return self.reduce(values, function (total, value) {
150657             return total + value;
150658         });
150659     },
150660
150661     max: function (obj, selector, scope) {
150662         var values = self.map(obj, selector, scope);
150663         return self.reduce(values, function (max, value) {
150664             return max < value ? value : max;
150665         }, Number.MIN_VALUE);
150666     },
150667
150668     min: function (obj, selector, scope) {
150669         var values = self.map(obj, selector, scope);
150670         return self.reduce(values, function (min, value) {
150671             return min > value ? value : min;
150672         }, Number.MAX_VALUE);
150673     },
150674
150675     forEach: function (obj, action, scope) {
150676         if (obj instanceof Array) {
150677             return obj.forEach(action, scope);
150678         }
150679         else {
150680             self.map(obj, action, scope);
150681         }
150682     },
150683
150684     filter: function (obj, predicate, scope) {
150685         if (obj instanceof Array) {
150686             return obj.filter(predicate, scope);
150687         }
150688         else {
150689             var result = [];
150690             self.forEach(obj, function (value, index) {
150691                 if (predicate.apply(scope, [value, index])) {
150692                     result.push(value);
150693                 }
150694
150695             }, scope);
150696
150697             return result;
150698         }
150699     },
150700
150701     reduce: function (obj, func, init, scope) {
150702         var i,
150703             initial = init === undefined ? 0 : init,
150704             result = initial;
150705
150706
150707         if (obj instanceof Array) {
150708             return obj.reduce(func, initial);
150709         }
150710         else if (obj instanceof NamedNodeMap) {
150711             for (i = 0; i < obj.length; i++) {
150712                 result = func.apply(scope, [result, obj[i], i]);
150713             }
150714         }
150715         else {
150716             for (i in obj) {
150717                 if (obj.hasOwnProperty(i)) {
150718                     result = func.apply(scope, [result, obj[i], i]);
150719                 }
150720             }
150721         }
150722
150723         return result;
150724
150725     },
150726
150727     map: function (obj, func, scope) {
150728         var i,
150729             returnVal = null,
150730             result = [];
150731
150732         if (obj instanceof Array) {
150733             return obj.map(func, scope);
150734         }
150735         else if (obj instanceof NamedNodeMap) {
150736             for (i = 0; i < obj.length; i++) {
150737                 returnVal = func.apply(scope, [obj[i], i]);
150738                 result.push(returnVal);
150739             }
150740         }
150741         else {
150742             for (i in obj) {
150743                 if (obj.hasOwnProperty(i)) {
150744                     returnVal = func.apply(scope, [obj[i], i]);
150745                     result.push(returnVal);
150746                 }
150747             }
150748         }
150749
150750         return result;
150751     },
150752
150753     regexSanitize: function (regexString) {
150754         return regexString.replace("^", "\\^")
150755                     .replace("$", "\\$")
150756                     .replace("(", "\\(")
150757                     .replace(")", "\\)")
150758                     .replace("<", "\\<")
150759                     .replace("[", "\\[")
150760                     .replace("{", "\\{")
150761                     .replace(/\\/, "\\\\")
150762                     .replace("|", "\\|")
150763                     .replace(">", "\\>")
150764                     .replace(".", "\\.")
150765                     .replace("*", "\\*")
150766                     .replace("+", "\\+")
150767                     .replace("?", "\\?");
150768     },
150769
150770     bindAutoSaveEvent: function (node, saveCallback) {
150771         var oldSetTimeoutId,
150772             jNode = jQuery(node);
150773
150774         jNode.bind("keyup", function (event) {
150775             if (event.keyCode !== 9) {
150776                 clearTimeout(oldSetTimeoutId);
150777                 oldSetTimeoutId = window.setTimeout(function () {
150778                     saveCallback();
150779                 }, 500);
150780             }
150781         });
150782     },
150783
150784     find: function (comparison, collection, startInx, endInx, callback) {
150785         var results = [],
150786             compare = function (s, pattern) {
150787
150788                 if (typeof(s) !== "string" || pattern === null) {
150789                     return s === pattern;
150790                 }
150791
150792                 var regex = pattern.replace(/\./g, "\\.")
150793                                    .replace(/\^/g, "\\^")
150794                                    .replace(/\*/g, ".*")
150795                                    .replace(/\\\.\*/g, "\\*");
150796
150797                 regex = "^".concat(regex, "$");
150798
150799                 return !!s.match(new RegExp(regex, "i"));
150800             };
150801
150802         self.forEach(collection, function (c) {
150803             var match,
150804                 fail = false;
150805
150806             self.forEach(comparison, function (value, key) {
150807                 if (!fail && value !== undefined) {
150808
150809                     if (compare(c[key], value)) {
150810                         match = c;
150811                     }
150812                     else {
150813                         fail = true;
150814                         match = null;
150815                     }
150816                 }
150817             });
150818
150819             if (match) {
150820                 results.push(match);
150821             }
150822         });
150823
150824         if (callback) {
150825             if (startInx === undefined) {
150826                 startInx = 0;
150827             }
150828             if (endInx === undefined) {
150829                 endInx = results.length;
150830             }
150831             if (startInx === endInx) {
150832                 endInx = startInx + 1;
150833             }
150834
150835             callback.apply(null, [results.slice(startInx, endInx)]);
150836         }
150837     },
150838
150839     mixin: function (mixin, to) {
150840         for (var prop in mixin) {
150841             if (Object.hasOwnProperty.call(mixin, prop)) {
150842                 to[prop] = mixin[prop];
150843             }
150844         }
150845         return to;
150846     },
150847
150848     copy: function (obj) {
150849         var i,
150850             newObj = jQuery.isArray(obj) ? [] : {};
150851
150852         if (typeof obj === 'number' ||
150853             typeof obj === 'string' ||
150854             typeof obj === 'boolean' ||
150855             obj === null ||
150856             obj === undefined) {
150857             return obj;
150858         }
150859
150860         if (obj instanceof Date) {
150861             return new Date(obj);
150862         }
150863
150864         if (obj instanceof RegExp) {
150865             return new RegExp(obj);
150866         }
150867
150868         for (i in obj) {
150869             if (obj.hasOwnProperty(i)) {
150870                 if (obj[i] && typeof obj[i] === "object") {
150871                     if (obj[i] instanceof Date) {
150872                         newObj[i] = obj[i];
150873                     }
150874                     else {
150875                         newObj[i] = self.copy(obj[i]);
150876                     }
150877                 }
150878                 else {
150879                     newObj[i] = obj[i];
150880                 }
150881             }
150882         }
150883
150884         return newObj;
150885     },
150886
150887     navHelper: function () {
150888         return {\r
150889             getHeading: function (lat1, lon1, lat2, lon2) {\r
150890                 var dLon = this.rad(lon2 - lon1),
150891                     llat1 = this.rad(lat1),
150892                     llat2 = this.rad(lat2),
150893                     y = Math.sin(dLon) * Math.cos(llat2),
150894                     x = Math.cos(llat1) * Math.sin(llat2) - Math.sin(llat1) * Math.cos(llat2) * Math.cos(dLon);
150895                 return (this.deg(Math.atan2(y, x)) + 360) % 360;\r
150896             },
150897
150898             getDistance: function (lat1, lon1, lat2, lon2) {\r
150899                 var dLat = this.rad(lat2 - lat1),
150900                     dLon = this.rad(lon2 - lon1),
150901                     a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.rad(lat1)) * Math.cos(this.rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2),
150902                     c = 2 * Math.asin(Math.sqrt(a)),
150903                     d = 6378100 * c;
150904                 return d;\r
150905             },
150906
150907             simulateTravel: function (lat, lon, hdg, dist) {\r
150908                 var lat1 = this.rad(lat),
150909                     lon1 = this.rad(lon),
150910                     brng = this.rad(hdg),
150911                     angularDistance = dist / 6378100,
150912                     lat2 = Math.asin(Math.sin(lat1) * Math.cos(angularDistance) + Math.cos(lat1) * Math.sin(angularDistance) * Math.cos(brng)),
150913                     lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(angularDistance) * Math.cos(lat1), Math.cos(angularDistance) - Math.sin(lat1) * Math.sin(lat2));
150914                 lon2 = (lon2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI; // Normalise to -180..+180
150915
150916                 return {\r
150917                     latitude: this.deg(lat2),\r
150918                     longitude: this.deg(lon2)\r
150919                 };\r
150920             },
150921
150922             deg: function (num) {\r
150923                 return num * 180 / Math.PI;\r
150924             },
150925
150926             rad: function (num) {\r
150927                 return num * Math.PI / 180;\r
150928             }\r
150929         };
150930     }
150931 };
150932
150933 });
150934 define('ripple/widgetConfig', function (require, exports, module) {
150935 /*
150936  *  Copyright 2011 Research In Motion Limited.
150937  *
150938  * Licensed under the Apache License, Version 2.0 (the "License");
150939  * you may not use this file except in compliance with the License.
150940  * You may obtain a copy of the License at
150941  *
150942  * http://www.apache.org/licenses/LICENSE-2.0
150943  *
150944  * Unless required by applicable law or agreed to in writing, software
150945  * distributed under the License is distributed on an "AS IS" BASIS,
150946  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150947  * See the License for the specific language governing permissions and
150948  * limitations under the License.
150949  */
150950 var exception = require('ripple/exception'),
150951     event = require('ripple/event'),
150952     app = require('ripple/app'),
150953     _console = require('ripple/console'),
150954     utils = require('ripple/utils'),
150955     platform = require('ripple/platform'),
150956     _validationResult = {
150957         valid: false,
150958         message: "",
150959         value: null
150960     },
150961     _configValidationResults = null;
150962
150963 function _failNodeValidation(schemaNode, message, value, node) {
150964     var validationResult = utils.copy(_validationResult);
150965
150966     if (!schemaNode.validationResult) {
150967         schemaNode.validationResult = [];
150968     }
150969     validationResult.valid = false;
150970     if (value) {
150971         validationResult.value = value;
150972     }
150973     else {
150974         delete(validationResult.value);
150975     }
150976     validationResult.message = schemaNode.nodeName + message;
150977     validationResult.node = node;
150978
150979     schemaNode.validationResult.push(validationResult);
150980 }
150981
150982 function _createEmptyNodeValidation(node) {
150983
150984     var validationResult = utils.copy(_validationResult),
150985         attributeValidationResult, attribute;
150986
150987     if (!node.validationResult) {
150988         node.validationResult = [];
150989     }
150990
150991     validationResult.value = "";
150992     delete(validationResult.valid);
150993     delete(validationResult.message);
150994
150995     if (node.attributes) {
150996         for (attribute in node.attributes) {
150997             if (node.attributes.hasOwnProperty(attribute)) {
150998                 if (!validationResult.attributes) {
150999                     validationResult.attributes = {};
151000                 }
151001
151002                 attributeValidationResult = utils.copy(_validationResult);
151003
151004                 attributeValidationResult.attributeName = node.attributes[attribute].attributeName;
151005                 delete(attributeValidationResult.value);
151006                 delete(attributeValidationResult.valid);
151007                 delete(attributeValidationResult.message);
151008
151009                 validationResult.attributes[attributeValidationResult.attributeName] = attributeValidationResult;
151010             }
151011         }
151012     }
151013
151014     node.validationResult.push(validationResult);
151015 }
151016
151017 function _validateValue(valueToTest, schemaNode) {
151018     var failMessage = "",
151019         nodeValue,
151020         numbers,
151021         numberRangeIndex,
151022         numberRange,
151023         range1,
151024         range2;
151025
151026     switch (schemaNode.type) {
151027     case "string":
151028         if (typeof valueToTest !== "string") {
151029             failMessage = " value was expected to be of type string but was typeof: " + typeof(valueToTest);
151030         }
151031         break;
151032     case "number":
151033         nodeValue = parseFloat(valueToTest);
151034         if (isNaN(nodeValue)) {
151035             failMessage = " value was expected to be of type number but was typeof: " + typeof(valueToTest);
151036         }
151037         break;
151038     case "integer":
151039         nodeValue = parseInt(valueToTest, 10);
151040         if (isNaN(nodeValue)) {
151041             failMessage = " value was expected to be of type number but was typeof: " + typeof(valueToTest);
151042         }
151043         break;
151044     case "boolean":
151045         if (valueToTest !== "false" && valueToTest !== "true") {
151046             failMessage = " value was expected to be of type boolean (i.e. 'true' or 'false' but was: " + valueToTest;
151047         }
151048         break;
151049     case "list":
151050         if (!utils.arrayContains(schemaNode.listValues, valueToTest)) {
151051             failMessage = " value is not recognized as being valid, it was:<br/><br/><span class=\"ui-text-fail\">" + valueToTest +
151052                     "</span><br/><br/>Valid values are:<p class=\"ui-text-pass\">" + schemaNode.listValues.join(" <br/> ") + "</p>";
151053         }
151054         break;
151055     case "listBoolean":
151056     case "listDefault":
151057         if (!utils.arrayContains(schemaNode.listValues, valueToTest)) {
151058             failMessage = " value is not recognized as being valid, it was:<br/><br/><span class=\"ui-text-fail\">" + valueToTest +
151059                     "</span><br/><br/>The framework will assume the value to be:<p class=\"ui-text-pass\">" + schemaNode.defaultValue + "</p>";
151060         }
151061         break;
151062     case "listNumbers":
151063         numbers = valueToTest.split(",");
151064
151065         for (numberRangeIndex = 0; numberRangeIndex < numbers.length; numberRangeIndex++) {
151066             numberRange = valueToTest.split("-");
151067             if (numberRange.length > 1) {
151068                 range1 = parseInt(numberRange[0], 10);
151069                 range2 = parseInt(numberRange[1], 10);
151070                 if (isNaN(range1) || isNaN(range2)) {
151071                     failMessage = " range values where not recognized as being valid, they was: " + range1 +
151072                             " and " + range2 + " :: valid values should be of type 'integer'";
151073                     break;
151074                 }
151075             }
151076             else if (numberRange.length === 1) {
151077                 range1 = parseInt(numberRange[0], 10);
151078                 if (isNaN(range1)) {
151079                     failMessage = " value was not recognized as being valid, it was: " + range1 +
151080                             " :: valid values should be of type 'integer'";
151081                     break;
151082                 }
151083             }
151084         }
151085         break;
151086     case "regex":
151087         if (!valueToTest.match(schemaNode.regex)) {
151088             failMessage = " value does not match expected format. Value should pass this regular expression validation: " + schemaNode.regex;
151089         }
151090         break;
151091     case "iso-language":
151092         break;
151093     default:
151094         exception.raise(exception.types.Application, "Schema node with value type of: " + schemaNode.type + " is not known");
151095     }
151096
151097     return failMessage;
151098 }
151099
151100 function _passNodeValidation(schemaNode, value, node) {
151101     var validationResult = utils.copy(_validationResult);
151102
151103     if (!schemaNode.validationResult) {
151104         schemaNode.validationResult = [];
151105     }
151106     validationResult.valid = true;
151107     validationResult.node = node;
151108     if (value) {
151109         validationResult.value = value;
151110     }
151111     else {
151112         delete(validationResult.value);
151113     }
151114     delete(validationResult.message);
151115
151116     schemaNode.validationResult.push(validationResult);
151117 }
151118
151119 function _validateNodeValue(schemaNode, node) {
151120     var failMessage,
151121         valueToTest = node && node.nodeValue ? node.nodeValue.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : null;
151122
151123     if (schemaNode.type && valueToTest) {
151124
151125         failMessage = _validateValue(valueToTest, schemaNode);
151126
151127         if (failMessage !== "") {
151128             _failNodeValidation(schemaNode, failMessage, valueToTest, node);
151129             return;
151130         }
151131     }
151132     _passNodeValidation(schemaNode, valueToTest, node);
151133 }
151134
151135 function _failNodeAttributeValidation(node, attribute, message, value) {
151136     var nodeValidationResult = node.validationResult ? node.validationResult.pop() : utils.copy(_validationResult),
151137         attributeValidationResult = utils.copy(_validationResult);
151138
151139     if (!nodeValidationResult.attributes) {
151140         nodeValidationResult.attributes = {};
151141     }
151142
151143     nodeValidationResult.valid = false;
151144     nodeValidationResult.message = "One or more attributes failed validation";
151145
151146     attributeValidationResult.attributeName = attribute.attributeName;
151147     attributeValidationResult.valid = false;
151148     if (value) {
151149         attributeValidationResult.value = value;
151150     }
151151     else {
151152         delete(attributeValidationResult.value);
151153     }
151154     attributeValidationResult.message = node.nodeName + "." + attribute.attributeName + message;
151155
151156     nodeValidationResult.attributes[attribute.attributeName] = attributeValidationResult;
151157     node.validationResult.push(nodeValidationResult);
151158 }
151159
151160 function _passNodeAttributeValidation(node, attribute, value) {
151161     var nodeValidationResult = node.validationResult ? node.validationResult.pop() : utils.copy(_validationResult),
151162         attributeValidationResult = utils.copy(_validationResult);
151163
151164     if (!nodeValidationResult.attributes) {
151165         nodeValidationResult.attributes = {};
151166     }
151167
151168     attributeValidationResult.attributeName = attribute.attributeName;
151169     attributeValidationResult.valid = true;
151170     if (value) {
151171         attributeValidationResult.value = value;
151172     }
151173     else {
151174         delete(attributeValidationResult.value);
151175     }
151176     delete(attributeValidationResult.message);
151177
151178     nodeValidationResult.attributes[attribute.attributeName] = attributeValidationResult;
151179     node.validationResult.push(nodeValidationResult);
151180 }
151181
151182 function _validateNodeAttributeValue(schemaNode, schemaNodeAttribute, attribute) {
151183     var failMessage,
151184         valueToTest = attribute ? attribute.value.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : null;
151185
151186     if (schemaNodeAttribute.type && valueToTest) {
151187
151188         failMessage = _validateValue(valueToTest, schemaNodeAttribute);
151189
151190         if (failMessage !== "") {
151191             _failNodeAttributeValidation(schemaNode, schemaNodeAttribute, failMessage, valueToTest);
151192             return;
151193         }
151194     }
151195     _passNodeAttributeValidation(schemaNode, schemaNodeAttribute, valueToTest);
151196 }
151197
151198 function _validateNodeAttributes(schemaNode, node, children) {
151199
151200     var siblings = utils.filter(children, function (child) {
151201             return child !== node;
151202         }),
151203         attributeConverter = function (attribute) {
151204             var _self = {
151205                 toValue: function (n) {
151206                     var obj = _self.toNode(n);
151207                     return obj ? obj.value : null;
151208                 },
151209                 toNode: function (n) {
151210                     return n.attributes.getNamedItem(attribute.attributeName);
151211                 }
151212             };
151213
151214             return _self;
151215         };
151216
151217     utils.forEach(schemaNode.attributes, function (attribute) {
151218
151219         var convert = attributeConverter(attribute),
151220             dupe = false;
151221
151222         if (attribute.unique) {
151223             // this means we need to check and see if there are other node with the same name
151224             // and ensure that they have a different value for this attributes, if not... fail
151225
151226             dupe = siblings.some(function (sibling) {
151227                 return convert.toValue(sibling) === convert.toValue(node);
151228             });
151229
151230             if (dupe) {
151231                 _failNodeAttributeValidation(schemaNode,
151232                         attribute,
151233                         " node is allowed to appear multiple times, however it must be unique based on this attribute and in this case another node with an identical attribute vale was found",
151234                         convert.toValue(node));
151235                 return;
151236             }
151237         }
151238
151239         if (attribute.required && !convert.toValue(node)) {
151240             _failNodeAttributeValidation(schemaNode, attribute, " attribute was expected but not found", null);
151241         }
151242         else {
151243             _validateNodeAttributeValue(schemaNode, attribute, convert.toNode(node));
151244         }
151245     });
151246 }
151247
151248
151249 function _validateNode(schemaNode, parentNode) {
151250     var children = utils.filter(parentNode.childNodes, function (child) {
151251         return child && child.nodeName === schemaNode.nodeName;
151252     });
151253
151254     if (children.length === 0) {
151255         if (schemaNode.required) {
151256             _failNodeValidation(schemaNode, " node expected, but not found", null, null);
151257         }
151258     }
151259
151260     utils.forEach(children, function (child) {
151261         if (schemaNode.occurrence !== 0 && schemaNode.occurrence < children.length) {
151262             _failNodeValidation(schemaNode, " node: more then " + schemaNode.occurrence + " node(s) found", null, child);
151263         }
151264         else {
151265             _validateNodeValue(schemaNode, child.childNodes[0] || child);
151266
151267             _validateNodeAttributes(schemaNode, child, children);
151268         }
151269
151270         utils.forEach(schemaNode.children, function (schema) {
151271             _validateNode(schema, child);
151272         });
151273     });
151274 }
151275
151276 function _validateAgainstSchemaNode(configSchema, configXML) {
151277     var results = utils.copy(configSchema);
151278     try {
151279         _validateNode(results[configSchema.rootElement], configXML);
151280     }
151281     catch (e) {
151282         exception.handle(e, true);
151283     }
151284
151285     return results;
151286 }
151287
151288 function _validate(configXML) {
151289     // traverse the config schema JSON object
151290     // TODO: update to get platform.getPlatformConfigSpec().schema
151291     return _validateAgainstSchemaNode(platform.current().config.schema, configXML);
151292 }
151293
151294 function _process(results) {
151295     // Check to make sure that widget is the correct version (i.e. config.xml needs to match selected platform)
151296     var validVersion = app.validateVersion(results);
151297
151298     if (!validVersion) {
151299         _console.warn("Your application does not appear to match" +
151300                 " the platform you have selected. The version number in your configuration might not " +
151301                 "match the selected platform version or your configuration file has errors in it.");
151302     }
151303
151304     // save widget info
151305     app.saveInfo(results);
151306     event.trigger("WidgetInformationUpdated");
151307
151308     // Check for readonly preferences (WAC only?)
151309
151310     if (app.getInfo().preferences !== {}) {
151311         event.trigger("StorageUpdatedEvent");
151312     }
151313 }
151314
151315 function _xmlToJson(xml) {
151316     var obj = {};
151317
151318     if (xml.nodeType === 1) { // element
151319         if (xml.attributes.length > 0) {
151320             obj["@attributes"] = {};
151321             utils.forEach(xml.attributes, function (attribute) {
151322                 obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
151323             });
151324         }
151325     } 
151326     else if (xml.nodeType === 3) { // text node
151327         obj = xml.nodeValue;
151328     }
151329
151330     if (xml.hasChildNodes && xml.hasChildNodes()) {
151331         utils.forEach(xml.childNodes, function (child) {
151332             if (!child.nodeName) {
151333                 return;
151334             }
151335             if (!obj[child.nodeName]) {
151336                 obj[child.nodeName] = [];
151337             }
151338             obj[child.nodeName].push(_xmlToJson(child));
151339         });
151340     }
151341
151342     return obj;
151343 }
151344
151345 module.exports = {
151346
151347     validate: function (configXML) {
151348         utils.validateNumberOfArguments(1, 1, arguments.length);
151349         return _validate(configXML);
151350     },
151351
151352     initialize: function (previous, baton) {
151353         var xmlHttp = new XMLHttpRequest(),
151354             config = platform.current().config,
151355             fileName = config ? config.fileName : null,
151356             results;
151357
151358         if (!fileName) {
151359             return;
151360         }
151361
151362         try {
151363             xmlHttp.open("GET", utils.appLocation() + fileName, false);
151364             xmlHttp.send();
151365             if (xmlHttp.responseXML) {
151366                 results = _validate(xmlHttp.responseXML);
151367                 results.rawJSON = _xmlToJson(xmlHttp.responseXML);
151368                 _process(results);
151369                 _configValidationResults = results;
151370             }
151371             else {
151372                 _process();
151373                 _configValidationResults = null;
151374                 require('ripple/ui/plugins/widgetConfig').initialize();
151375             }
151376         }
151377         catch (e) {
151378             exception.handle(e);
151379         }
151380     },
151381
151382     getValidationResults: function () {
151383         return _configValidationResults;
151384     }
151385 };
151386
151387 });
151388 define('ripple/xhr/base', function (require, exports, module) {
151389 /*
151390  *  Copyright 2011 Research In Motion Limited.
151391  *
151392  * Licensed under the Apache License, Version 2.0 (the "License");
151393  * you may not use this file except in compliance with the License.
151394  * You may obtain a copy of the License at
151395  *
151396  * http://www.apache.org/licenses/LICENSE-2.0
151397  *
151398  * Unless required by applicable law or agreed to in writing, software
151399  * distributed under the License is distributed on an "AS IS" BASIS,
151400  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151401  * See the License for the specific language governing permissions and
151402  * limitations under the License.
151403  */
151404 var XHR = window.XMLHttpRequest;
151405
151406 function _handle(object, key) {
151407     return function () {
151408         return object[key].apply(object, Array.prototype.slice.call(arguments));
151409     };
151410 }
151411
151412 function _getter(object, key) {
151413     return function () {
151414         return object[key];
151415     };
151416 }
151417
151418 function _setter(object, key) {
151419     return function (val) {
151420         object[key] = val;
151421     };
151422 }
151423
151424 function _writeable(obj) {
151425     var newObj = {},
151426         key;
151427
151428     // need prototypes
151429     for (key in obj) {
151430         //HACK: don't even know what to say bout this, resonseBlob can go fly a kite: related to this issue:
151431         //https://github.com/blackberry/Ripple-UI/issues/394
151432         if (key !== "responseBlob" && typeof obj[key] === "function") {
151433             newObj[key] = _handle(obj, key);
151434         } else {
151435             newObj.__defineGetter__(key, _getter(obj, key));
151436             newObj.__defineSetter__(key, _setter(obj, key));
151437         }
151438     }
151439
151440     return newObj;
151441 }
151442
151443 function _XMLHttpRequest() {
151444     var Xhr = require('ripple/emulatorBridge').xhr() || XHR;
151445     return _writeable(new Xhr());
151446 }
151447
151448 module.exports = _XMLHttpRequest;
151449
151450 });
151451 define('ripple/xhr/cors', function (require, exports, module) {
151452 /*
151453  *  Copyright 2011 Research In Motion Limited.
151454  *
151455  * Licensed under the Apache License, Version 2.0 (the "License");
151456  * you may not use this file except in compliance with the License.
151457  * You may obtain a copy of the License at
151458  *
151459  * http://www.apache.org/licenses/LICENSE-2.0
151460  *
151461  * Unless required by applicable law or agreed to in writing, software
151462  * distributed under the License is distributed on an "AS IS" BASIS,
151463  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151464  * See the License for the specific language governing permissions and
151465  * limitations under the License.
151466  */
151467 var helpers = require('ripple/xhr/helpers'),
151468     constants = require('ripple/constants'),
151469     XHR = require('ripple/xhr/base');
151470
151471 function _XMLHttpRequest() {
151472     var xhr = new XHR(),
151473         origMethods = {
151474             setRequestHeader: xhr.setRequestHeader,
151475             open: xhr.open
151476         };
151477
151478     xhr.setRequestHeader = function (header, value) {
151479         // This is done to get around jQuery 1.3.2 setting a header that it shouldn't
151480         if (header && header.toUpperCase() !== "X-REQUESTED-WITH") {
151481             origMethods.setRequestHeader.apply(xhr, Array.prototype.slice.call(arguments));
151482         }
151483     };
151484
151485     xhr.open = function (method, url, async, user, password) {
151486         if (!helpers.isLocalRequest(url)) {
151487             url = constants.API_URL + "/xhr_proxy?tinyhippos_apikey=ABC&tinyhippos_rurl=" + escape(url);
151488         }
151489
151490         origMethods.open.apply(xhr, Array.prototype.slice.call(arguments));
151491     };
151492
151493     return xhr;
151494 }
151495
151496 module.exports = _XMLHttpRequest;
151497
151498 });
151499 define('ripple/xhr/helpers', function (require, exports, module) {
151500 /*
151501  *  Copyright 2011 Research In Motion Limited.
151502  *
151503  * Licensed under the Apache License, Version 2.0 (the "License");
151504  * you may not use this file except in compliance with the License.
151505  * You may obtain a copy of the License at
151506  *
151507  * http://www.apache.org/licenses/LICENSE-2.0
151508  *
151509  * Unless required by applicable law or agreed to in writing, software
151510  * distributed under the License is distributed on an "AS IS" BASIS,
151511  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151512  * See the License for the specific language governing permissions and
151513  * limitations under the License.
151514  */
151515 var constants = require('ripple/constants'),
151516     db = require('ripple/db');
151517
151518 module.exports = {
151519     isLocalRequest: function (url) {
151520         return (!!(url.match(constants.REGEX.LOCAL_URI)) || !url.match(constants.REGEX.EXTERNAL_URI)) || 
151521                 !!(location.host && url.match(location.host));
151522     },
151523
151524     proxyEnabled: function () {
151525         var isDisabled = db.retrieve(constants.XHR.PROXY_DISABLED_BUTTON);
151526         return !isDisabled || isDisabled === "false" ? true : false;
151527     }
151528 };
151529
151530 });
151531 define('ripple/xhr/jsonp', function (require, exports, module) {
151532 /*
151533  *  Copyright 2011 Research In Motion Limited.
151534  *
151535  * Licensed under the Apache License, Version 2.0 (the "License");
151536  * you may not use this file except in compliance with the License.
151537  * You may obtain a copy of the License at
151538  *
151539  * http://www.apache.org/licenses/LICENSE-2.0
151540  *
151541  * Unless required by applicable law or agreed to in writing, software
151542  * distributed under the License is distributed on an "AS IS" BASIS,
151543  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151544  * See the License for the specific language governing permissions and
151545  * limitations under the License.
151546  */
151547 var constants = require('ripple/constants'),
151548     exception = require('ripple/exception'),
151549     utils = require('ripple/utils'),
151550     helpers = require('ripple/xhr/helpers'),
151551     _console = require('ripple/console'),
151552     XHR = require('ripple/xhr/base');
151553
151554 function _XMLHttpRequest() {
151555     var xhr = new XHR(),
151556         origMethods = {
151557             setRequestHeader: xhr.setRequestHeader,
151558             getResponseHeader: xhr.getResponseHeader,
151559             getAllResponseHeaders: xhr.getAllResponseHeaders,
151560             open: xhr.open,
151561             send: xhr.send,
151562             abort: xhr.abort
151563         },
151564         _jxhr = new window.jXHR(),
151565         _sendFlag = false,
151566         _headers = [],
151567         _errorFlag = false,
151568         _url,
151569         _async;
151570
151571     function _localURI() {
151572         return _url && helpers.isLocalRequest(_url);
151573     }
151574
151575     function _set(prop, value) {
151576         xhr.__defineGetter__(prop, function () {
151577             return value;
151578         });
151579     }
151580
151581     function _reset() {
151582         _set("response", "");
151583         _set("responseText", "");
151584         _set("responseXML", null);
151585     }
151586
151587     xhr.setRequestHeader = function (header, value) {
151588         if (_localURI()) {
151589             origMethods.setRequestHeader.apply(xhr, Array.prototype.slice.call(arguments));
151590         } else {
151591             _console.error("XMLHttpRequest :: setRequestHeader does not work with JSONP.");
151592         }
151593     };
151594
151595     xhr.getResponseHeader = function (header) {
151596         return _localURI() ?
151597                 origMethods.getAllResponseHeaders.apply(xhr, [header]) :
151598                 _headers[header] || null;
151599     };
151600
151601     xhr.getAllResponseHeaders = function () {
151602         return _localURI() ?
151603                 origMethods.getAllResponseHeaders.apply(xhr) :
151604                 utils.reduce(_headers, function (str, value, key) {
151605                     return str + key + ": " + value + '\n';
151606                 }, "").replace(/\n$/, '');
151607     };
151608
151609     xhr.open = function (method, url, async) {
151610         _url = url;
151611         _async = async !== false ? true : false;
151612
151613         if (_localURI()) {
151614             origMethods.open.apply(xhr, Array.prototype.slice.call(arguments));
151615         } else {
151616             _reset();
151617             method = method.toUpperCase();
151618
151619             if (method === "POST") {
151620                 //HACK: Switch the method to get for now to simulate post
151621                 method = "GET";
151622             }
151623
151624             if (method !== "GET") {
151625                 exception.raise(exception.types.MethodNotImplemented, "Method: " + method + " not supported!");
151626             }
151627
151628             _jxhr.onreadystatechange = function (data) {
151629                 var response;
151630
151631                 try {
151632                     _set("readyState", _jxhr.readyState);
151633
151634                     if (xhr.readyState === xhr.DONE) {
151635                         _sendFlag = false;
151636                         _set("status", data.status);
151637                         _set("statusText", data.statusText);
151638                         _headers = data.headers;
151639
151640                         if (data.responseXML) {
151641                             response = new DOMParser().parseFromString(unescape(data.responseXML), "text/xml");
151642                             _set("responseXML", response);
151643                         } else {
151644                             response = unescape(data.responseText);
151645                             _set("responseText", response);
151646                         }
151647
151648                         _set("response", response);
151649                     }
151650
151651                     if (typeof xhr.onreadystatechange === "function") {
151652                         xhr.onreadystatechange.apply(xhr);
151653                     }
151654                 } catch (e) {
151655                     exception.handle(e);
151656                 }
151657             };
151658
151659             _jxhr.onerror = xhr.onerror;
151660             _jxhr.open(method, constants.API_URL + "/jsonp_xhr_proxy?callback=?&tinyhippos_apikey=ABC&tinyhippos_rurl=" + escape(url));
151661         }
151662     };
151663
151664     xhr.send = function (data) {
151665         if (_localURI()) {
151666             origMethods.send(data);
151667             return;
151668         }
151669
151670         if (!_async) {
151671             exception.raise(exception.types.MethodNotImplemented, "Synchronous not supported.");
151672         }
151673
151674         if (xhr.readyState !== xhr.OPENED || _sendFlag === true) {
151675             exception.raise(exception.types.InvalidState, "Ready state should be OPENED (1)");
151676         }
151677
151678         _errorFlag = false;
151679         _sendFlag = true;
151680         data = null;
151681
151682         _jxhr.send();
151683     };
151684
151685     xhr.abort = function () {
151686         if (_localURI()) {
151687             origMethods.abort();
151688             return;
151689         }
151690
151691         _reset();
151692
151693         _errorFlag = true;
151694
151695         if (xhr.readyState === xhr.UNSENT ||
151696                 (xhr.readyState === xhr.OPENED && _sendFlag === false) ||
151697                 xhr.readyState === xhr.DONE) {
151698             _set("readyState", xhr.UNSENT);
151699         } else {
151700             _set("readyState", xhr.DONE);
151701             _sendFlag = false;
151702
151703             if (typeof xhr.onreadystatechange === "function") {
151704                 xhr.onreadystatechange.apply(xhr);
151705             }
151706         }
151707
151708         _jxhr.onreadystatechange = null;
151709
151710         if (xhr.onabort) {
151711             xhr.onabort.apply(xhr, arguments);
151712         }
151713     };
151714
151715     return xhr;
151716 }
151717
151718 module.exports = _XMLHttpRequest;
151719
151720 });
151721 define('ripple/xhr', function (require, exports, module) {
151722 /*
151723  *  Copyright 2011 Research In Motion Limited.
151724  *
151725  * Licensed under the Apache License, Version 2.0 (the "License");
151726  * you may not use this file except in compliance with the License.
151727  * You may obtain a copy of the License at
151728  *
151729  * http://www.apache.org/licenses/LICENSE-2.0
151730  *
151731  * Unless required by applicable law or agreed to in writing, software
151732  * distributed under the License is distributed on an "AS IS" BASIS,
151733  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151734  * See the License for the specific language governing permissions and
151735  * limitations under the License.
151736  */
151737 var constants = require('ripple/constants'),
151738     utils = require('ripple/utils'),
151739     ui = require('ripple/ui'),
151740     helpers = require('ripple/xhr/helpers'),
151741     XHR = window.XMLHttpRequest;
151742
151743 module.exports = {
151744     initialize: function (previous, baton) {
151745         window.XMLHttpRequest = require('ripple/xhr/base');
151746
151747         if (helpers.proxyEnabled() && !ui.registered("omnibar")) {
151748             var isFileScheme = utils.location().protocol.match(/^file:/);
151749             window.XMLHttpRequest = require(isFileScheme ? 'ripple/xhr/jsonp' : 'ripple/xhr/cors');
151750         }
151751     }
151752 };
151753
151754 });
151755 define('ripple', function (require, exports, module) {
151756 /*
151757  *  Copyright 2011 Research In Motion Limited.
151758  *
151759  * Licensed under the Apache License, Version 2.0 (the "License");
151760  * you may not use this file except in compliance with the License.
151761  * You may obtain a copy of the License at
151762  *
151763  * http://www.apache.org/licenses/LICENSE-2.0
151764  *
151765  * Unless required by applicable law or agreed to in writing, software
151766  * distributed under the License is distributed on an "AS IS" BASIS,
151767  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151768  * See the License for the specific language governing permissions and
151769  * limitations under the License.
151770  */
151771 var omgwtf = require('ripple/omgwtf'),
151772     db = require('ripple/db'),
151773     xhr = require('ripple/xhr'),
151774     geo = require('ripple/geo'),
151775     fileSystem = require('ripple/fileSystem'),
151776     fs = require('ripple/dbfs'),
151777     platform = require('ripple/platform'),
151778     emulatorBridge = require('ripple/emulatorBridge'),
151779     devices = require('ripple/devices'),
151780     widgetConfig = require('ripple/widgetConfig'),
151781     deviceSettings = require('ripple/deviceSettings'),
151782     sensorSettings = require('ripple/sensorSettings'),
151783     ui = require('ripple/ui'),
151784     appcache = require('ripple/appcache'),
151785     _self = {
151786         boot: function (booted) {
151787             // techdebt (event registration timing)
151788             // require('ripple/platform/webworks.core/2.0.0/fsCache');
151789
151790             window.addEventListener("keydown", function (event) {
151791                 var hasMetaOrAltPressed = (event.metaKey || event.ctrlKey),
151792                     key = parseInt(event.keyCode, 10);
151793
151794                 if (key === 37 && hasMetaOrAltPressed) { // cmd/ctrl + left arrow
151795                     event.preventDefault();
151796                     emulatorBridge.window().history.back();
151797                 }
151798
151799                 if (key === 39 && hasMetaOrAltPressed) { // cmd/ctrl + right arrow
151800                     event.preventDefault();
151801                     emulatorBridge.window().history.forward();
151802                 }
151803
151804                 if (key === 82 && hasMetaOrAltPressed) { // cmd/ctrl + r
151805                     event.preventDefault();
151806                     window.tinyHipposReload = true;
151807                     emulatorBridge.window().location.reload();
151808                 }
151809
151810                 if (key === 116) { // F5
151811                     event.preventDefault();
151812                     window.tinyHipposReload = true;
151813                     emulatorBridge.window().location.reload();
151814                 }
151815             });
151816
151817             window.onbeforeunload = function () { 
151818                 if (!window.tinyHipposReload) {
151819                     return "Web Simulator";
151820                 }
151821             };
151822
151823             jWorkflow.order(omgwtf.initialize, omgwtf)
151824                  .andThen(appcache.initialize, appcache)
151825                  .andThen(db.initialize, db)
151826                  .andThen(xhr.initialize, xhr)
151827                  .andThen(geo.initialize, geo)
151828                  .andThen(fileSystem.initialize, fileSystem)
151829                  .andThen(fs.initialize, fs)
151830                  .andThen(platform.initialize, platform)
151831                  .andThen(devices.initialize, devices)
151832                  .andThen(widgetConfig.initialize, widgetConfig)
151833                  .andThen(deviceSettings.initialize, deviceSettings)
151834                  .andThen(ui.initialize, ui)
151835                  .start(booted);
151836         }
151837     };
151838
151839 module.exports = _self;
151840
151841 });
151842 require('ripple/ui').register('omnibar');require('ripple/bootstrap').bootstrap();